打印
[STM32F1]

STM32 Timer2定时500ms中断,测得定时有误差不准确

[复制链接]
2268|17
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
rhgz123|  楼主 | 2014-11-14 11:41 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
请问,stm32v103  Timer2定时500ms中断,软件仿真时,测得定时为420ms,存在80ms的稳定时差,但是硬件仿真时 时间基本为随机的,500ms的定时测出来 1s多,两秒多的都有~
请问大侠们这是怎么回事??
沙发
LOVE_ELEC| | 2014-11-14 12:42 | 只看该作者
这种情况,建议楼主看一下Tim2的时钟分频是否正确!

使用特权

评论回复
板凳
mmuuss586| | 2014-11-14 12:51 | 只看该作者

用的内部晶振吧;
F1的话,内部晶振,倍频后,最大只能到64M;
这样你的误差就有40mS了;

使用特权

评论回复
地板
rhgz123|  楼主 | 2014-11-14 14:00 | 只看该作者
mmuuss586 发表于 2014-11-14 12:51
用的内部晶振吧;
F1的话,内部晶振,倍频后,最大只能到64M;
这样你的误差就有40mS了;

貌似是和晶振有关系,那请问 如何查看使用的外部晶振还是内部晶振呢,如何设置呢

使用特权

评论回复
5
rhgz123|  楼主 | 2014-11-14 14:03 | 只看该作者
LOVE_ELEC 发表于 2014-11-14 12:42
这种情况,建议楼主看一下Tim2的时钟分频是否正确!

您有stm32 Timer定时的例程吗 让我参考一下,最好是基于寄存器的,没有使用库的~

使用特权

评论回复
6
LOVE_ELEC| | 2014-11-14 14:50 | 只看该作者
rhgz123 发表于 2014-11-14 14:03
您有stm32 Timer定时的例程吗 让我参考一下,最好是基于寄存器的,没有使用库的~ ...

手里面暂时没有源码,可以下载个正点原子的寄存器版的程序!

使用特权

评论回复
7
cool_coder| | 2014-11-15 12:02 | 只看该作者
这种对执行效率要求不高的场合,还是用固件库更好吧?可读性好,易写易维护。我只在中断或其它有性能要求的地方才用直接寄存器操作。
其实,把固件库调用转换成直接的寄存器操作并不难。

使用特权

评论回复
8
mmuuss586| | 2014-11-15 12:18 | 只看该作者
rhgz123 发表于 2014-11-14 14:00
貌似是和晶振有关系,那请问 如何查看使用的外部晶振还是内部晶振呢,如何设置呢
...

:L
看你的程序啊;
实在不行,网上找下,参考程序很多;

使用特权

评论回复
9
zhaoyu2005| | 2014-11-15 19:58 | 只看该作者
mmuuss586 发表于 2014-11-14 12:51
用的内部晶振吧;
F1的话,内部晶振,倍频后,最大只能到64M;
这样你的误差就有40mS了;

自己对着rcc的寄存器看下数据就知道配置成用哪个时钟了。

使用特权

评论回复
10
mmuuss586| | 2014-11-15 21:17 | 只看该作者
zhaoyu2005 发表于 2014-11-15 19:58
自己对着rcc的寄存器看下数据就知道配置成用哪个时钟了。

呵呵,应该回答楼主,不是回答我,呵呵;

使用特权

评论回复
11
zhaoyu2005| | 2014-11-17 09:06 | 只看该作者
mmuuss586 发表于 2014-11-15 21:17
呵呵,应该回答楼主,不是回答我,呵呵;

不好意思,不知咋点错了,本意是回复楼主的

使用特权

评论回复
12
rhgz123|  楼主 | 2014-11-17 15:13 | 只看该作者
zhaoyu2005 发表于 2014-11-17 09:06
不好意思,不知咋点错了,本意是回复楼主的

哈哈我也看到了,谢谢你啊~但是硬件仿真时 时间基本为随机的,500ms的定时测出来 1s多,两秒多的都有~这又是怎么回事呢?实际的定时时间到底为多少呢????

使用特权

评论回复
13
rhgz123|  楼主 | 2014-11-17 15:29 | 只看该作者
mmuuss586 发表于 2014-11-15 12:18
看你的程序啊;
实在不行,网上找下,参考程序很多;

是使用的内部晶振,但是 我现在有点糊涂了,硬件仿真时 时间基本为随机的,500ms的定时测出来 1s多,两秒多的都有~这是怎么回事???实际的定时时间到底是多少?我怎么看?我现在需要一个精确地500ms定时该怎么做??

使用特权

评论回复
14
mmuuss586| | 2014-11-17 17:37 | 只看该作者
rhgz123 发表于 2014-11-17 15:29
是使用的内部晶振,但是 我现在有点糊涂了,硬件仿真时 时间基本为随机的,500ms的定时测出来 1s多,两秒 ...

肯定误差没这么大了;
有空我写个程序测试下,发你参考吧;

使用特权

评论回复
15
mmuuss586| | 2014-11-17 18:15 | 只看该作者
TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
TIM_OCInitTypeDef  TIM_OCInitStructure;
__IO uint16_t CCR1_Val = 50000;
uint16_t PrescalerValue = 0;
void Time2_Configuration(void)
{
          /* ---------------------------------------------------------------
    TIM2 Configuration: Output Compare Timing Mode:
    TIM2 counter clock at 1 MHz
    CC1 update rate = TIM2 counter clock / CCR1_Val = 1000 Hz
  --------------------------------------------------------------- */

  /* Time base configuration */
  TIM_TimeBaseStructure.TIM_Period = 65535;
  TIM_TimeBaseStructure.TIM_Prescaler = 63;
  TIM_TimeBaseStructure.TIM_ClockDivision = 0;
  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;

  TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);

  /* Prescaler configuration */
  //TIM_PrescalerConfig(TIM2, PrescalerValue, TIM_PSCReloadMode_Immediate);

  /* Output Compare Timing Mode configuration: Channel1 */
  TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Timing;
  TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
  TIM_OCInitStructure.TIM_Pulse = CCR1_Val;
  TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;

  TIM_OC1Init(TIM2, &TIM_OCInitStructure);

  TIM_OC1PreloadConfig(TIM2, TIM_OCPreload_Disable);


  /* TIM IT enable */
  TIM_ITConfig(TIM2, TIM_IT_CC1, ENABLE);

  /* TIM2 enable counter */
  TIM_Cmd(TIM2, ENABLE);

}

void NVIC_Configuration(void)
{
  NVIC_InitTypeDef NVIC_InitStructure;

        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);

  /* Enable the TIM2 global Interrupt */
  NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

  NVIC_Init(&NVIC_InitStructure);
}

使用特权

评论回复
16
mmuuss586| | 2014-11-17 18:15 | 只看该作者
uint16_t capture = 0;
extern __IO uint16_t CCR1_Val;
void TIM2_IRQHandler(void)
{
  if (TIM_GetITStatus(TIM2, TIM_IT_CC1) != RESET)
  {
    TIM_ClearITPendingBit(TIM2, TIM_IT_CC1);

    GPIO_WriteBit(GPIOC, GPIO_Pin_10, (BitAction)(1 - GPIO_ReadOutputDataBit(GPIOC, GPIO_Pin_10)));
    capture = TIM_GetCapture1(TIM2);
    TIM_SetCompare1(TIM2, capture + CCR1_Val);
  }
  else;
}

使用特权

评论回复
17
mmuuss586| | 2014-11-17 18:18 | 只看该作者
上面是定时50mS;
你定时500mS甚至更长,最好用32位定时器或者滴答定时器,另外最好加个变量,比如定时1ms,用变量计时500次,实现500mS输出,定时精度要求高的话尽量改成寄存器读写;

如果定时精度还不够,就用CPLD或FPGA吧;

使用特权

评论回复
18
fengyun2351| | 2014-11-17 23:41 | 只看该作者
换种写法吧  误差有点大了

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

4

主题

13

帖子

0

粉丝