Arduino与Proteus仿真实例计时器延时仿真
Arduino与Proteus仿真实例-计时器延时仿真
计时器延时仿真
1、Arduino计时器介绍
1)什么是计时器
作为 Arduino 程序员,您肯定在不知情的情况下使用过定时器和中断。 那是因为所有底层硬件的东西都被已经封装好的 Arduino 函数隐藏了。 许多 Arduino 函数都使用定时器,例如时间函数:delay、millis、micros delayMicroseconds。 他们都在后台使用 Arduino 计时器。 其他功能如 PWM 模拟写入也使用定时器。 音调和 noTone 功能甚至伺服电机控制库也是如此。 那么,这个计时器是什么?
计时器是 Arduino 控制器中内置的一块硬件,根据型号的不同,它可以有不同数量的计时器。 例如,Arduino UNO 有 3 个定时器,Timer0、Tmer1 和 Timer2。 这就像一个时钟,可以用来测量时间事件。 定时器可以由一些特殊寄存器编程,就像编程时钟一样。
2)预分频器
可以把定时器想象成一个计数脉冲的计数器。 这个定时器由系统时钟提供,对于 Arduino UNO 来说,它可以是 16Mhz 的晶体时钟,或者根据引导加载程序也可以是一个 8MHz 的内部振荡器。 在定时器计数器和系统时钟之间,有另一个称为预标量的硬件。 这个预标量将来自系统时钟的脉冲数除以自定义的数字,可能是 8、64、256 等等,稍后将看到如何定义这个预标量分频数。
现在假设主系统时钟是 16Mhz 晶体,它将产生一个 16Mhz 方波信号。 每个脉冲为 62.5ns,对吗? 你把它提供给预标量,可以说设置为 8。因此,来自预标量的输出信号将慢 8 倍,即 500ns。 所以每8个来自系统时钟的脉冲,我们的定时器就会增加1。可以使用相关寄存器为每个定时器配置预分频器。
可以用这些定时器做什么?Arduino的定时器 0 和 2 是 8 位,这意味着它可以从 0 计数到 255;定时器 1 是 16 位,因此它可以从 0 计数到 65536。一旦定时器达到最大值,它将返回到 0 或根据所选模式开始减少。 所以基本上它会创建一个锯齿形曲线。 定时器从 0 开始增加它的值。当达到 255 时,如果是 8 位寄存器,我们回到 0 并再次增加。 这将创建一个三角形曲线,因此可以使用它来创建我们的中断。
3)计时器的中断服务
每个定时器可以产生一个或多个中断。 一种类型的中断是比较匹配。 我可以在不同的寄存器中写入一个值,当定时器值等于比较值时,它会触发中断。 例如,我们将比较匹配寄存器设置为 100,每次定时器 0 到达 100 时,都会产生中断。 另一种中断类型用于溢出。 在这种情况下,每次定时器溢出时都会触发中断,这意味着它从最大值返回到 0,在 8 位定时器的情况下,每次达到 255 时都会发生这种情况。 最后,我们有输入捕获中断, 对于 Arduino UNO,可以在计时器 1 上实现。在这种情况下,计时器可以将其值存储在不同的寄存器中,每次在 Arduino 引脚之一上发生外部事件时。
4)设置预分频器
设置预分频器时,需要更改的第一个寄存器是预标量。 为了控制定时器,Arduino有两个主要寄存器,TCCRA 和 TCCRB,每个寄存器都有定时器的编号。 所以对于定时器 1,有 TCCR1A 和 TCCR1B。 TCCRA 寄存器用于控制 PWM 模式,因此对于定时器 1,可以控制与引脚 9 和 10 上的 PWM 信号相关的 OC1A。在使用中断时,不需要这个寄存器,但需要设置它的所有位 为 0,因为 Arduino 默认将它们设置为 1。因此,将所有这些设置为 0 将禁用引脚 9 和 10 上的 PWM 信号。
接着,需要更改 TCCRB 寄存器。 在这里,我们只关心用于定义 prescaar 值的前 3 位。 如下表所示,使用 CS10、CS11 和 CS12 位,可以禁用预分频器或将其设置为 1,除以 8、64、256、1024 甚至使用外部时钟源。 对于定时器 0 和 2,必须使用 TCCR0B 和 TCCR2B 以及位 CS00、CS01、CS02 和位 CS20、CS21 和 CS22。

TCCRB 寄存器

设置示例代码如下:
1 | void setup() { |
5)设置中断(比较匹配)
通过设置 TIMSK 寄存器可以激活比较匹配中断。如下表所示:

2、仿真电路原理图

在系统时钟为16MHz、预分频器为256时,创建500ms延时的定时器1的值计算公式如下:
1 | Timer 1 speed = 16Mhz/256 = 62.5 Khz |
1 | bool LED_STATE = true; |
上面代码实现了每 500 毫秒中断一次。 每次触发中断,我们就去相关的ISR向量。 由于Arduino UNO有 3 个计时器,因此有 6 个 ISR 向量,每个计时器两个,它们具有以下名称:TIMER1_COMPA_vect
- TIMER1_COMPB_vect
- TIMER2_COMPA_vect
- TIMER2_COMPB_vect
- TIMER3_COMPA_vect
- TIMER4_COMPB_vect
4、仿真结果

文章来源: https://iotsmart.blog.csdn.net/article/details/120842019