今天我们要说一下 Arduino 如何输出 PWM

Arduino 通过封装函数 analogWrite() 来输出 PWM, 但这个函数并不是可以用在任何一个引脚，而是仅可以应用在标记了 ~ 的引脚上, analogWrite 函数并不能真正输出一个模拟量，取而代之的是 PWM 信号。

A PWM (Pulse Width Modulation) signal is a pulsed binary signal. As it is binary it can only have two output states “HIGH” and “LOW”. The analog information is not on the signal levels but on the width of the generated pulses.We define Pulse Width as the width of the HIGH pulses and Duty Cycle, represented with a lower case delta letter, as the fraction of the Pulse Width to the total period T of the signal. The frequency of the PWM signal is defined as the inverse of the period.

The mean value of the PWM signal depends on the Duty Cycle and the voltage values associated to the HIGH and LOW levels:

Fast PWM on Timer 1

If the maximum 976 Hz that stock Arduino analogWrite is not enough, we need to develop our own PWM functionality. Timer 1 is a good candidate as it has three available compare channels and don’t mess with Arduino delay functions. You should take care if you use the Servo library because it also uses Timer 1.

Timer 1 is based arround a 16 bit counter. That means that it can count from 0 up to 65535 before overflowing. The timer has several modes of operations that include 12 PWM modes. The fastest PWM mode available is single slope 8 bits counting between 0 and 255. As single slope is faster that dual slope, it is also called Fast PWM mode.

You can also have 9 bits and 10 bits PWM modes with 511 and 1023 terminal counts that can operate on single and dual slope modes. Three bit modes 8, 9 and 10 for single and dual slope PWM gives a total of 6 PWM modes. The other 6 additional PWM modes use programmable terminal counts that can be any 16 bit value and is not restricted to 255, 511 or 1023.

The timer gets its clock from the global MCU prescaler that provides five frequencies from the system clock. The divide ratios are 1, 8, 64, 256 and 1024. That gives, using the 16MHz Arduino Leonardo system clock, the fiveclock and single slope frequencies shown below for standard 8, 9 and 19 bit modes: