STM32 定时器开关导致延时不准确
我的代码设置如下:定时器配置为向上计数模式,计数间隔为1us,10us中断一次,来实现一个10us的延时。
开关定时器方法:
定时器中断函数()
{
关闭定时器,清除CEN位;----------------此时CNT寄存器有时是0,有时是1
执行处理代码;
打开定时器,设置CEN位;----------------CNT计数起点受制于前面,如果是1,那么下次9us后进入中断,而不是10
}
疑问:
进入中断后,立即关闭定时器时,CNT寄存器值可能每次不一样,导致开启定时器时计数起点不同。难道芯片每次进入中断后运行到关闭定时器的那行代码的时间会变化吗?大神能否解释一下?
想到的解决办法:
1、添加对CNT寄存器设置操作
定时器中断函数()
{
关闭定时器,清除CEN位;----------------此时CNT寄存器有时是0,有时是1
执行处理代码;
CNT = 0;
打开定时器,设置CEN位;----------------CNT计数起点受制于前面
}
2、将定时器设置为单脉冲模式----onePulse,查看参考手册发现设置为单脉冲模式,定时器溢出后自动停止计数器。
以上两种方法是否可行?哪种方法好呢,会不会引入其它问题。请大神指点!谢谢!
1、中断需要压栈、退栈等操作,并非楼主所想那个10us操作。楼主在这个非常紧张的中断里中断中又要关闭定时器,又要启动定时器,还能剩下多少指令执行时间?。
2、其实要做到个10uS的中断,无需关心CNT的值,只要细心配置好定时器中断参数,每次中断就是10uS,在中断里,执行小于10uS(这个10Us能做的事很有限,还要扣除堆栈操作))的操作就是。 本帖最后由 oceane 于 2018-7-4 13:06 编辑
为什么要关闭定时器呢?关闭后再打开就不是精确的10us中断了,关闭打开也需要时间肯定会有延时不准。 本帖最后由 stm1024 于 2018-7-4 13:05 编辑
话说这个是不是放错板块了……
不太明白你为什么要采用这种方式,通常清除中断标志就可以了。以最简单的TIM6/7为例:void TIM6_IRQHandler(void)
{
if(TIM_GetITStatus(TIM6 ,TIM_IT_Update)!= RESET)
{
GPIO_WriteBit(GPIOB,GPIO_Pin_13,ba);
ba=1-ba;
}
TIM_ClearITPendingBit(TIM6,TIM_FLAG_Update);
}其实你可以多看看别人是怎么实施的。
wenyangzeng 发表于 2018-7-4 13:26
1、中断需要压栈、退栈等操作,并非楼主所想那个10us操作。楼主在这个非常紧张的中断里中断中又要关闭定时 ...
感谢回复,中断中执行代码大于10us,所以进入中断就把它关闭了。 stm1024 发表于 2018-7-4 13:02
话说这个是不是放错板块了……
不太明白你为什么要采用这种方式,通常清除中断标志就可以了。以最简单的TI ...
感谢回复是发错地方了我在中断中必须关闭定时器,因为代码执行时间要远大于10
oceane 发表于 2018-7-4 13:00
为什么要关闭定时器呢?关闭后再打开就不是精确的10us中断了,关闭打开也需要时间肯定会有延时不准。 ...
感谢回复,中断中执行代码大于10us,所以进入中断就把它关闭了。 既然代码执行时间大于10us为什么还要在10us的中断里面执行这段代码呢。
如果不是必须在中断中执行的东西可以放到中断外面去执行,另外就是优化一下代码,也许能在10us内执行完 子曰好人 发表于 2018-7-4 14:06
既然代码执行时间大于10us为什么还要在10us的中断里面执行这段代码呢。
如果不是必须在中断中执行的东西可 ...
感谢回复,这里的定时器的作用只是控制程序进行的作用 miraclexue 发表于 2018-7-4 13:41
感谢回复,中断中执行代码大于10us,所以进入中断就把它关闭了。
既然中断中执行代码大于10us,楼主设置这个10us中断有何意义?
页:
[1]
2