4. PWM信号频率与占空比测试
任务目标
在ESP32上配置LEDC PWM通道,输出指定频率(例如10 kHz)和占空比(例如60%),并通过示波器测量GPIO引脚的实际波形,验证频率与占空比误差在可接受范围内(频率误差<1%,占空比误差<2%)。
环境与依赖
- 硬件:ESP32开发板(如ESP32-DevKitC)、USB转串口、示波器(带宽≥20 MHz)
- 软件:ESP-IDF v5.x 或 Arduino ESP32 核心 2.x(本案例使用ESP-IDF原生驱动)
- 接线:示波器探头接GPIO2(默认LEDC通道输出引脚),GND共地
关键完整代码
#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/ledc.h"
#include "esp_err.h"
#define PWM_GPIO 2
#define PWM_FREQ_HZ 10000 // 目标频率 10 kHz
#define PWM_DUTY_PCT 60 // 目标占空比 60%
#define LEDC_TIMER LEDC_TIMER_0
#define LEDC_CHANNEL LEDC_CHANNEL_0
#define LEDC_MODE LEDC_LOW_SPEED_MODE
#define LEDC_DUTY_RES LEDC_TIMER_13_BIT // 分辨率 13 位 (0~8191)
void app_main(void)
{
// 1. 配置定时器
ledc_timer_config_t timer_conf = {
.speed_mode = LEDC_MODE,
.duty_resolution = LEDC_DUTY_RES,
.timer_num = LEDC_TIMER,
.freq_hz = PWM_FREQ_HZ,
.clk_cfg = LEDC_AUTO_CLK
};
ESP_ERROR_CHECK(ledc_timer_config(&timer_conf));
// 2. 配置通道
ledc_channel_config_t ch_conf = {
.gpio_num = PWM_GPIO,
.speed_mode = LEDC_MODE,
.channel = LEDC_CHANNEL,
.intr_type = LEDC_INTR_DISABLE,
.timer_sel = LEDC_TIMER,
.duty = 0,
.hpoint = 0
};
ESP_ERROR_CHECK(ledc_channel_config(&ch_conf));
// 3. 计算并设置占空比(13位分辨率:8191 * 60% = 4914)
uint32_t duty_val = (1 << 13) * PWM_DUTY_PCT / 100;
ESP_ERROR_CHECK(ledc_set_duty(LEDC_MODE, LEDC_CHANNEL, duty_val));
ESP_ERROR_CHECK(ledc_update_duty(LEDC_MODE, LEDC_CHANNEL));
printf("PWM输出已启动: GPIO%d, %d Hz, %d%% 占空比\n", PWM_GPIO, PWM_FREQ_HZ, PWM_DUTY_PCT);
printf("理论占空比寄存器值: %lu (13位分辨率)\n", (unsigned long)duty_val);
// 保持运行
while (1) {
vTaskDelay(pdMS_TO_TICKS(1000));
}
}
编译与烧录
idf.py set-target esp32
idf.py build
idf.py -p /dev/ttyUSB0 flash monitor
验证方法与判定标准
- 示波器探头接GPIO2,地线接GND,设置时基10 µs/div,垂直刻度2 V/div。
- 观察波形应为方波,高电平约3.3 V,低电平接近0 V。
- 测量频率:读取示波器频率测量值,应在9.90~10.10 kHz范围内(误差<1%)。
- 测量占空比:使用示波器占空比测量功能,读数应在58%~62%之间(误差<2%)。
- 若超出范围,检查电源稳定性、探头补偿是否校准、GPIO2是否被其他外设占用。
常见问题
- 无波形输出:确认GPIO2在开发板上未被占用(部分板载LED连接GPIO2,需断开跳线或换用GPIO4/5并同步修改代码)。
- 频率偏差较大:LEDC时钟源精度有限,实测频率与配置值存在±0.5%以内偏差属正常;若偏差过大,检查是否误用LEDC_HIGH_SPEED_MODE(ESP32不支持)。
- 占空比边缘不陡:示波器探头接地线过长会引入振铃,使用接地弹簧缩短地线回路。