本帖最后由 y990441 于 2016-6-29 23:03 编辑
第二篇 滴答定时器
前一篇中的delay函数延时是不准确的。在这一篇中,我们首先使用滴答定时器来延时。注意到原子哥的代码在不涉及操作系统时,并没有采用滴答定时器的中断来延时,可能是为了更方便的在中断处理函数中调用延时吧(如果你在外部中断中调用了延时函数,而该函数的延时依赖于滴答定时器的中断,而滴答定时器的中断优先级又比外部中断低。。。那这个延时函数就挂掉了)。
对于延时,可以直接“复用”原子哥代码中的一个微秒级延时和两个毫秒级延时~~~(为什么直接“复用”呢?其实是因为库函数所提供的The SysTick_Config()和SysTick_CLKSourceConfig()不足以完成时钟摘取的操作,所以这些代码中涉及到一些寄存器的操作。但是指望像我这样的菜鸟去写寄存器的代码~~~那是很不切实际的,但是当你掌握了代码复用的技术以后,就会发现无数的巨人肩膀可以让你踩,这样你就不需要深入学习寄存器操作了)。
代码直接把上一篇中的延时代码改成新版本的延时,就OK了
关于滴答定时器的中断,在裸机中如何使用呢?比如我们可以定制出让滴答定时器每1ms中断一次。这样,我们就可以通过软件的方式实现软件定时器(定时时间是1ms的整数倍)。以下代码实现了LED0一秒翻转一次,而LED1两秒翻转一次。 所以,对于软件定时器,其基本的接口应该是: 这些函数操纵的数据成员为:
接下来就比较简单了,让滴答定时器一毫秒中断一次,每次中断时一次检查my_tmr数组里的各个软件定时器是否到时间,没到时间,count-=1,到时设置flag,并根据是一次性的还是自动重装的来决定count的新值。
最后,为了让软件定时器和延时函数并存,注意到原子版本的延时函数开头都开启滴答定时器,最后都关闭了滴答定时器。。。把这两句代码注释掉,两部分功能就可以融合在一起了。
|