打印

使用STM32中遇到的一个定时器的问题

[复制链接]
2738|2
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
freny|  楼主 | 2009-4-27 17:05 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
我的意愿是将TC4作为一个定时器,该定时器定时值可改变,但预分频不变,一开始就先初始化,什么都设置好了,等要使用定时的时候,我会先将要定时的值设置好,然后启动定时器,然后在溢出中断中设置了一个标志符,中断一到该标志符将置为定时完成标志,在主程序中一直在查询该标志,应该算是查询方式吧。
volatile int8 Timer4_over;
void TIM4_IRQHandler(void) 
{    
  if (TIM4->SR & (1<<0)) 
  {                        
    TIM4->SR &= ~(1<<0);                          // clear UIF flag
    Timer4_over=is_over;
  }
} // end TIM4_IRQHandler
__inline static  void TIM4_Init(uint16 Prescale)

  RCC->APB1ENR |= RCC_APB1ENR_TIM4EN;//特别注意
  TIM4->PSC = Prescale*2;                               // set prescaler
  TIM4->CR1 &= ~0x0001;                              // disable timer
  TIM4->SR &= ~(1<<0);                          // clear UIF flag
  Timer4_over=not_over;
  TIM4->CR1 = (1<<7)|(1<<4)|(1<<3)|(1<<2);
  TIM4->CR2 = 0;
  TIM4->DIER = __TIM4_DIER;                             // enable interrupt
  NVIC->ISER[0] |= (1 << (TIM4_IRQChannel & 0x1F));     // enable interrupt

  TIM4->ARR = 40000;
  TIM4->CNT=40000;  
}
void TIM4_Start(uint16 delay)
{            
    RCC->APB1ENR |= RCC_APB1ENR_TIM4EN;
    TIM4->CR1 &= ~0x0001;                              // disable timer
    TIM4->SR &= ~(1<<0);                          // clear UIF flag    
    TIM4->ARR = delay;
  TIM4->CNT=delay;
  Timer4_over=not_over;
  TIM4->CR1 |= TIMX_CR1_CEN;      
}
uint16 TIM4_Stop(void)
{
    if(Timer4_over==is_over)
    { 
        TIM4->CR1 &= ~0x0001;                              // disable timer
        TIM4->SR &= ~(1<<0);                          // clear UIF flag    
        return is_over;    
    }
    else return not_over;        
}
void TIM4_Close(void)

    TIM4->CR1 &= ~0x0001;                              // disable timer
    TIM4->SR &= ~(1<<0);                          // clear UIF flag    
}

使用方法为:
TIM4_Init(374);
TIM4_Start(9600);
while(TIM4_Stop()!=is_over);
TIM4_Close();
...
TIM4_Start(9600);
while(TIM4_Stop()!=is_over);
TIM4_Close();
现在发现一个问题,就是第一次定时的时候,总是时长不正确,偏小,从第二次以后就正常了。
最后我发现ST的官方程序是将RCC->APB1ENR |= RCC_APB1ENR_TIM4EN;提到最前面的,但在看了http://hi.baidu.com/comyboy/blog/item/e5f08e01021a38011d9583e7.html后,他却没有这样做,难道不是开了时钟后才能操作定时器的寄存器吗?
最后我该了下,将“//特别注意”那一行移到结尾,再运行,发现,一下子就正确了。

问题解决了,但是到底是什么原因造成这个了?还有,难道不是开了时钟后才能操作定时器的寄存器吗?因为我记得我有另外个模块,就是因为在操作寄存器前没有开启该时钟而导致过失败。

以上问题请各位能解惑,谢谢1
沙发
香水城| | 2009-4-27 18:15 | 只看该作者

问题出在预分频器的初值没有设置好

预分频器有影子寄存器,你需要在函数TIM4_Init()的最后通过TIMx_EGR的UG位加载预分频器的初值,否则它的内容是复位后的默认值。

第一次定时结束后,会产生一个更新事件,这个更新事件把预分频器影子寄存器的值传送到预分频器中,所以从第2次开始定时时间正确。

使用特权

评论回复
板凳
freny|  楼主 | 2009-4-28 09:23 | 只看该作者

谢谢了,PDF没看仔细的苦果呀

PDF没看仔细的苦果呀

使用特权

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

本版积分规则

12

主题

37

帖子

0

粉丝