深入 PWM
来自Jack's Lab
从上文 Arduino I/O 之模拟输出 可以看到,数字 I/O 口也能用于输出不同占空比的方波,模拟 analogWrite 行为,但这种方法需要 CPU 100% 地投入,而且不能被中断打断。因此,现代的单片机一般都带有数个用于 PWM 输出的定时器,Arduino 使用的 ATMEGA 系列也不例外。
以 ATMEGA 168/328 为例,其带有 3 个 timer,分别为:8 位的 Timer/Counter0,16 位的 Timer/Counter1,8 位的 Timer/Counter2
这些定时器用来定时产生输出,经软件配置可以生成不同占空比的方波,而且能产生“变频”的方波
以 Timer/Counter0 为例,其组成为:
- TCNT0 (Timer/Counter0 Register) 一个 8 位计数寄存器,每个时钟滴答自动增 1
- OCR0A 和 OCR0B (Output Compare Register) 两个 8 位比较值计数器,对应 2 个输出引脚。使用时,当 TCNT0 的值等于其中之一时,就会抛出中断
- TCCR0A 和 TCCR0B 两个 8 位控制寄存器,用于配置 Timer/Counter0 的运行参数
- TIFR0 (Timer/Counter0 Interrupt Flag Register) 中断状态寄存器,8 位,指示中断是 OCR0B match 了,还是 OCR0A match 了,亦或是 TCNT0 溢出了
- TIMSK0 (Timer/Counter0 Interrupt Mask Register) 中断屏蔽寄存器,8 位,对应 OCR0B match,OCR0A match 和 TCNT0 overflow,对应位为 1 表示使能该中断
Timer/Counter0 的工作模式由 TCCR0A 和 TCCR0B 共同决定,这是两个 8 位寄存器。其中 TCCR0A 有如下位:
COM0A1 COM0A0 | COM0B1 COM0B0 | | WGM01 WGM00
TCCR0B 有如下位:
| WGM02 | CS02 | CS01 | CS00
COM0A1 COM0A0 这两位决定输出通道 A (管脚 3)的 Compare Output Match 模式
COM0B1 COM0B0 这两位决定输出通道 B (管脚 5)的 Compare Output Match 模式
即当 Compare Match 时,输出管脚的电平怎么变化
WGM02 WGM01 WGM00 这三位决定生成的波形模式(Waveform Generation Mode),一共 6 种模式:
- Normal
- CTC
- Fast PWM
- Phase Correct PWM
- Fast PWM (Varying the timer top limit)
- Phase Correct PWM (Varying the timer top limit)
CS02 | CS01 | CS00 则决定 Timer/Counter0 相对于系统 clock 的倍频,可取值 1, 1/8, 1/64, 1/256, 1/1024