Arduino - 脉冲宽度调制
Arduino: 理解脉冲宽度调制 (PWM)
Section titled “Arduino: 理解脉冲宽度调制 (PWM)”脉冲宽度调制 (PWM) 是一种强大的技术,用于通过数字信号控制模拟设备。PWM 不是输出连续的模拟电压,而是快速地在数字引脚的HIGH和LOW之间切换。信号处于HIGH状态的时间百分比被称为占空比,它会产生一个平均电压,从而实现诸如调暗LED或控制直流电机速度等效果。
核心 PWM 概念
Section titled “核心 PWM 概念” HIGH |----------| |----------| | | | | LOW +----------+----------+----------+ <-- Ton ---><--Toff--><-- Ton ---> <------- Period ------>- 高电平时间 (Ton): 信号处于HIGH状态的持续时间。
- 低电平时间 (Toff): 信号处于LOW状态的持续时间。
- 周期: 一个周期的总时间(周期 = Ton + Toff)。周期的倒数即为 PWM 频率。
- 占空比: 信号处于HIGH状态的周期百分比。
占空比 = (Ton / 周期) * 100%。
0% 占空比意味着信号始终为 LOW(平均电压为0V)。100% 占空比意味着信号始终为 HIGH(平均电压为5V)。50% 占空比意味着信号在周期的一半时间内为 HIGH,产生2.5V的平均电压。
analogWrite() 函数
Section titled “analogWrite() 函数”Arduino 提供了 analogWrite(pin, value) 函数,可以轻松生成 PWM 信号。在使用 PWM 引脚时,你无需在其之前调用 pinMode()。
analogWrite(pin, value);pin: 你想要使用的具备 PWM 功能的引脚。在 Arduino UNO 上,这些引脚标有波浪线~(引脚 3、5、6、9、10、11)。请务必查阅你开发板的文档以了解其 PWM 引脚。value: 占空比,指定为从0(0% 占空比) 到255(100% 占空比) 的整数值。
大多数 Arduino 开发板的默认 PWM 频率约为 490 Hz,但有些引脚(例如 UNO 上的 5 和 6 号引脚)运行在 980 Hz。ESP32 等更高级的开发板提供可配置的 PWM 频率。
示例项目:使用电位器渐变LED亮度
Section titled “示例项目:使用电位器渐变LED亮度”这个经典示例演示了如何从电位器读取模拟值,并使用它通过 PWM 控制LED的亮度。
- 1 × Arduino UNO
- 1 × 电位器 (任意阻值,10kΩ 常见)
- 1 × LED
- 1 × 220Ω 电阻
// 电位器接线// 电位器有3个引脚。// 将两个外部引脚连接到电源和地。// 中心引脚(“滑动端”)是输出电压。
Potentiometer Pin 1 --- Arduino GNDPotentiometer Pin 2 (Wiper) --- Arduino Analog Pin A0Potentiometer Pin 3 --- Arduino 5V
// LED 接线Arduino PWM Pin ~9 --- [220Ω Resistor] --- [LED Anode (+)]Arduino GND --- [LED Cathode (-)]带有 map() 函数的代码
Section titled “带有 map() 函数的代码”analogRead() 函数返回 0-1023 范围的值,而 analogWrite() 需要 0-255 范围的值。我们可以使用方便的 map() 函数将输入范围映射到输出范围。
/** * @文件 pwm_potentiometer_control.ino * @简介 使用电位器通过 PWM 控制 LED 亮度。 * @作者 现代化教程 */
constexpr int LED_PIN = 9; // 必须是 PWM 引脚 (~)constexpr int POT_PIN = A0; // 电位器输入引脚
void setup() { // 当使用 analogWrite 时,LED_PIN 不需要 pinMode。 // 模拟输入引脚不需要 pinMode。 Serial.begin(9600);}
void loop() { // 1. 从电位器读取值 (0 到 1023) int potValue = analogRead(POT_PIN);
// 2. 将 10 位模拟输入范围 (0-1023) 映射到 // 8 位 PWM 输出范围 (0-255)。 int pwmValue = map(potValue, 0, 1023, 0, 255);
// 3. 将映射后的值写入 LED 引脚。 analogWrite(LED_PIN, pwmValue);
// 可选:将值打印到串口监视器以进行调试。 Serial.print("电位器:"); Serial.print(potValue); Serial.print("\t PWM 值:"); Serial.println(pwmValue);
delay(10); // 短暂延迟以保持稳定性}超越LED:其他 PWM 应用
Section titled “超越LED:其他 PWM 应用”PWM 功能非常多样:
- 直流电机速度控制: 通过使用电机驱动芯片(如 L298N 或 TB6612),您可以使用 PWM 来控制发送给电机的有效电压,从而控制其速度。
- 舵机控制: Arduino
Servo库使用 PWM 信号来告诉舵机移动到哪个角度。 - 生成音调:
tone()函数使用 PWM 通过蜂鸣器或扬声器创建不同频率的声音。