<抄>STM32 定时器有时一开启就进中断的问题

    在STM32F103中发现了这个问题,没细究,在STM32F030中也出现了一开中断就进一次中断的情况,仿真调试发现,在初始化定时器函数中TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);最后一句:

         /* Generate an update event to reload the Prescaler and the Repetition counter values immediately */
        TIMx->EGR = TIM_PSCReloadMode_Immediate; //此语句导致TIM3->SR = 0x0001

>>>>文档中对EGR寄存器的bit0的说明:

Bit 0 UG: Update generation
        This bit can be set by software, it is automatically cleared by hardware.
        0: No action
        1: Re-initialize the counter and generates an update of the registers. Note that the prescaler
        counter is cleared too (anyway the prescaler ratio is not affected). The counter is cleared if
        the center-aligned mode is selected or if DIR=0 (upcounting), else it takes the auto-reload
        value (TIMx_ARR) if DIR=1 (downcounting).

>>>>文档中对SR寄存器bit0的说明:

Bit 0UIF: Update interrupt flag
        This bit is set by hardware on an update event. It is cleared by software.

        0: No update occurred.
        1: Update interrupt pending.
        This bit is set by hardware when the registers are updated:
        At overflow or underflow and if UDIS=0 in the TIMx_CR1 register.
        When CNT is reinitialized by software using the UG bit in TIMx_EGR register, if URS=0 and
        UDIS=0 in the TIMx_CR1 register.
        When CNT is reinitialized by a trigger event (refer to the synchro control register description), if
        URS=0 and UDIS=0 in the TIMx_CR1 register.



http://www.51hei.com/bbs/dpj-40940-1.html

整理:MilerShao 

    在用到STM32定时器的更新中断时,发现有些情形下只要开启定时器就立即进入一次中断。准确说,只要使能更新中断允许位就立即响应一次更新中断【当然前提是相关NVIC也已经配置好】。换言之,只要使能了相关定时器更新中断,不管你定时间隔多长甚至不在乎你是否启动了相关定时器,它都会立即进入一次定时器更新中断服务程序。

STM32F051芯片为例,做了几种不同顺序的组合测试。根据测试发现,的确有些情况下一运行TIM_ITConfig(TIM1, TIM_IT_Update, ENABLE); 【即使能更新中断】就立即进入更新中断服务程序。当然后面的中断都是正常的。

老实说,这个问题比较容易忽视,有些情况下也无关紧要,但有些情况可能会给应用带来困扰。从ST MCU相关技术手册似乎并不能明显地找到关于这个问题的很合适或者逻辑性很强的前因后果。

经过验证测试,如果注意一下相关指令代码顺序是可以回避这个问题的。
    

做更新中断标志的清除操作,即清除TIMx->SR寄存器里的UIF标志,然后做定时器更新中断的使能操作。至于开启相关定时器的指令摆放位置并不严格。下面是相关动作的操作顺序及结果,可以参考、验证之。这里共罗列了6种写法,其中有3种情形是会立即进入中断的,另外3种不会。
 
   TIM_ClearITPendingBit(TIM1, TIM_IT_Update); //清除更新中断请求位

    TIM_ITConfig(TIM1, TIM_IT_Update, ENABLE); //使能定时器1更新中断

TIM_Cmd(TIM1, ENABLE);                   //启动定时器

         1。。。。。。不会立即进入更新中断程序。

 

    TIM_ClearITPendingBit(TIM1, TIM_IT_Update);//清除更新中断请求位

TIM_Cmd(TIM1, ENABLE); 

    TIM_ITConfig(TIM1, TIM_IT_Update, ENABLE);//使能定时器1更新中断

     (2。。。。。。不会立即进入更新中断程序。
 

TIM_Cmd(TIM1, ENABLE);

   TIM_ClearITPendingBit(TIM1, TIM_IT_Update);//清除更新中断请求位

  TIM_ITConfig(TIM1, TIM_IT_Update, ENABLE);//使能定时器1更新中断

   3。。。。。。不会立即进入更新中断程序。


    TIM_Cmd(TIM1, ENABLE);

    TIM_ITConfig(TIM1, TIM_IT_Update, ENABLE);//使能定时器1更新中断

    TIM_ClearITPendingBit(TIM1, TIM_IT_Update);//清除更新中断请求位

       4。。。。。。立即进入更新中断程序。

 
 
    TIM_ITConfig(TIM1, TIM_IT_Update, ENABLE);//使能定时器1更新中断

   TIM_ClearITPendingBit(TIM1, TIM_IT_Update);//清除更新中断请求位

TIM_Cmd(TIM1, ENABLE);  

  5。。。。。。立即进入更新中断程序。
 

     TIM_ITConfig(TIM1, TIM_IT_Update, ENABLE);//使能定时器1更新中断

     TIM_Cmd(TIM1, ENABLE); 

     TIM_ClearITPendingBit(TIM1, TIM_IT_Update);//清除更新中断请求位

  6。。。。。。立即进入更新中断程序。
 

 顺便提下关于定时器里UG位和URS位的使用,分别在TIMx->EGRTIMx->CR1寄存器里。对UG位置1可以产生更新事件并对相关计数器和寄存器重新初始化,如果URS位为0的话,同时会产生更新中断。如果不希望对UG位置1的同时产生更新中断,得置URS位为1,否则会立即进入更新中断。 


 

  • 4
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值