管理员
- 积分
- 165352
- 金钱
- 165352
- 注册时间
- 2010-12-1
- 在线时间
- 2108 小时
|
有细心的客户发现,我们的STM32定时器中断实验,只要开启定时器中断,就会立即进入一次定时器中断服务程序,此后便正常了。
这个初次初始化,按理说,不应该这么快进入中断的(定时时间还未到),但是配置什么的,都是正常,可STM32就不按规则来,只要你开启,立即进入中断。
以我们探索者STM32F407开发板的定时器中断实验(实验8)为例,我们直接仿真例程,可以发现,只要执行完TIM3_Int_Init函数最后一行代码,便立即跳转到
TIM3_IRQHandler中断服务函数,点亮了LED1。如下图所示:
进入中断服务函数后,点亮LED1,所以大家可以看到,每次按复位,都是先亮LED1,然后再亮LED0的。
按设计来说,LED1应该在程序启动500ms以后,才开始亮的,而LED0则是初始化完成,就点亮闪烁。
所以和设计不符。
解决办法,其实很简单,在此贴:http://www.openedv.com/thread-68826-1-1.html ,1楼就给出了解决办法。
我们只需要在MY_NVIC_Init这行代码之前,添加2行代码,就可以了,修改后代码如下:
[mw_shl_code=c,true]//通用定时器3中断初始化
//这里时钟选择为APB1的2倍,而APB1为42M
//arr:自动重装值。
//psc:时钟预分频数
//定时器溢出时间计算方法:Tout=((arr+1)*(psc+1))/Ft us.
//Ft=定时器工作频率,单位:Mhz
//这里使用的是定时器3!
void TIM3_Int_Init(u16 arr,u16 psc)
{
RCC->APB1ENR|=1<<1; //TIM3时钟使能
TIM3->ARR=arr; //设定计数器自动重装值
TIM3->PSC=psc; //预分频器
TIM3->DIER|=1<<0; //允许更新中断
TIM3->CR1|=0x01; //使能定时器3
TIM3->EGR|=1<<0; //产生更新事件
TIM3->SR=0; //清所有标志
MY_NVIC_Init(1,3,TIM3_IRQn,2); //抢占1,子优先级3,组2
}[/mw_shl_code]
实际上就是在设置定时器中断优先级之前,人为的产生一次更新事件,并对产生的标记进行清零。
这样,就解决了STM32定时器启动后立即进入中断的bug。
最后,感谢xkwy提供的解决思路,并附上修改后的测试代码(基于探索者F407开发板,不会立即进入定时器中断)。
实验8 定时器中断实验(修改后,不立即中断).rar
(127.53 KB, 下载次数: 941)
|
|