第十八课--定时器中断的使用/zh
目的
上一课我们学习了Microduino CoreSTM32外部中断的使用,本课将学习定时器中断的使用。仅有硬币大小的Microduino CoreSTM32内部有4个16位定时器,每个定时器可以计数到最大65535,每个定时器有4个比较器,每个比较器可以独立地与定时器比较触发操作,触发操作可以是PWM或产生中断。同一个定时器上的不同比较器可以以相同的频率触发,但触发的相位不同,这可以用于PWM与步进电机驱动等应用。
设备
Microduino-CoreSTM 是以ARM Cortex-M3为核心的32位单片机开发核心板,是一个开源的、与Microduino其它模块扩展模块兼容的控制器模块。
- 其他硬件设备
- 面包板跳线 一盒
- 面包板 一块
- USB数据连接线 一根
实验原理
控制硬件定时器需要实例化HardwareTimer类。注意,PWM也是由定时器控制的,在同时使用定时器和PWM时,需要尽量避免共用一个定时器或触发器。
- 为了使用定时器中断,这里建议采用下面的步骤:
- 1)用pause()函数暂停定时器。
- 2)设定分频器与溢出值(也可用setPeriod()来设定)。
- 3)选择一个通道来处理中断,并将该通道工作模式设定为TIMER_OUTPUT_COMPARE。
- 4)设定选定通道的比较值,该值可以是0到溢出值之间的一个值,如果你不在乎具体什么值触发中断则可以忽略,默认会在计数器为1时触发。
- 5)连接中断到用于处理该定时器中断的函数。
- 6)用refresh()函数重置计数器。
- 7)用resume()函数恢复计数器计时。
下面我们结合上边的步骤用定时器来闪烁Microduino CoreSTM32上的LED。
程序
HardwareTimer timer1(1);
void setup()
{
pinMode(BOARD_LED_PIN, OUTPUT);
timer1.pause(); //暂停定时器
timer1.setPeriod(50000); //50ms,设置定时器的计时周期,该操作会设定分频器和溢出值,已获得尽可能接近指定周期的溢出周期
timer1.setMode(1,TIMER_OUTPUT_COMPARE); //设定比较器1触发中断
timer1.setCompare(1, 1); //设定比较器1的值为1,当计数器计数到1时触发比较器1
timer1.attachInterrupt(1,handler_led); //为通道1设置中断
timer1.refresh(); //重置定时器,恢复定时器的值为0,并更新溢出值与分频设置
timer1.resume(); //开始计数
}
void loop()
{}
void handler_led(void)
{
toggleLED();
}
程序说明:
- void setMode(int channel, timer_mode mode)
- 设定定时器的工作模式。
- 参数:channel定时器通道。
- mode定时器的工作模式有3种:TIMER_DISABLED(关闭)、TIMER_PWM(PWM,初始化后的默认模式)、TIMER_OUTPUT_COMPARE(由定时器触发中断)。
- void setCompare(int channel, uint16 compare)
- 参数:channel定时器通道。
- compare比较值,可以是0或溢出值-1。
- 设定定时器中指定通道的比较值,该值用于控制触发事件的相位,当比较值大于定时器溢出值时,会被设定为定时器的溢出值。定时器计数达到比较器的比较值时会触发操作,例如,PWM或是通过中断执行某个指定函数。
调试
把程序代码复制到Maple IDE编译下载到Microduino CoreSTM32观察实验现象。 大家可以尝试通过设置void setPrescaleFactor(uint32 factor)和void setOverflow(uint16 val)函数来设置定时器的计时周期。第一个函数是用来设置定时器的分频系数,取值范围在1-65536之间,第二个函数是用于设定定时器的溢出值,用于控制定时器计数周期。 Maple 的工作频率为72 MHz,若factor为1,则定时分辨率为13.89 ns(1 ns=10-9 s=10-6 ms=10-3 μs)。下表给出常见的定时器分频系数与分辨率、最长计时周期的关系。