PWM 实战
本篇目标:理解 PWM 是什么,并用手头的 sysfs 接口输出一个可调占空比的方波。典型用途:调 LCD 背光亮度、控速风扇/电机、蜂鸣器发声。
什么是 PWM
PWM(脉冲宽度调制)= 让一个引脚高速地在高/低之间翻转,并通过改变”高电平持续时间占整个周期的比例”(占空比)来等效控制”平均电压/功率”。
- 周期 period:一个完整高低循环的时间(纳秒 ns)。频率 = 1/period。
- 占空比 duty_cycle:高电平持续的时间(ns)。占空比 = duty_cycle / period。
- 例:period=1000ns(1MHz),duty=500ns → 50% 占空比,平均电压约为一半。
背光就是靠改占空比来调亮度的:占空比越大越亮。
板子的 PWM 资源
ypt153evb 的使用了多个 pwm 控制器。出厂设备树里:
pwm2_7,对应引脚 PD23,专门用于背光,配置为pwms = <&pwm2 7 25000 1>(周期 25000ns = 40kHz)。pwmcs0_4, 对应引脚 PB13,作为 cpu 调频接口pwmcs0_0, 对应引脚 PB8,未使用,排针区域引出

ypt153evb 可用的 PWM 控制器 pwmcs0(寄存器基址 0x20a0000)。有 8 个通道 pwmcs0_0 ~ pwmcs0_7
第一步:配置设备树
device/config/chips/t153/configs/t153_nand_base/linux-5.10-origin/board.dts 下找到 pwmcs0_0 启用并配置 PB8 引脚
pwmcs0_0_pins_active: pwmcs0_0@0 {
pins = "PB8";
function = "pwm0_0";
drive-strength = <20>;
};
pwmcs0_0_pins_sleep: pwmcs0_0@1 {
pins = "PB8";
function = "gpio_in";
bias-pull-down;
};
...
&pwmcs0_0 {
pinctrl-names = "active", "sleep";
pinctrl-0 = <&pwmcs0_0_pins_active>;
pinctrl-1 = <&pwmcs0_0_pins_sleep>;
status = "okay";
};重新编译内核并烧录(见底层篇《系统编译》)。
第二步:找到 PWM 控制器
# ls /sys/class/pwm/
pwmchip0 pwmchip16 pwmchip8每个 pwmchipN 代表一个 PWM 控制器。先确认它有多少通道:
# cat /sys/class/pwm/pwmchip0/npwm
8第三步:导出通道并输出
以控制背光通道 0(PB8)为例:
# 1. 导出通道 0(首次使用才需要,导出后会在 pwmchip0 下出现 pwm0 目录)
echo 0 > /sys/class/pwm/pwmchip0/export
cd /sys/class/pwm/pwmchip0/pwm0
# 2. 设置周期,单位是纳秒
echo 1000000 > period
# 3. 设置占空比,单位是纳秒,必须 <= period
echo 500000 > duty_cycle
# 4. 使能输出
echo 1 > enable连接示波器检查 PB8 的 pwm 输出

pwm0 目录下常用文件:
| 文件 | 含义 |
|---|---|
period |
周期(ns),写时须 ≥ duty_cycle |
duty_cycle |
占空比(ns),须 ≤ period |
enable |
1=输出,0=关闭 |
polarity |
极性(normal/inversed),一般不动 |
写
period和duty_cycle的顺序:先写 period,再写 duty_cycle,且 duty_cycle 不能超过 period,否则写会报参数错误。
排障
| 现象 | 处理 |
|---|---|
/sys/class/pwm/ 为空 |
内核未启用 pwm;确认设备树 &pwmcs status=okay |
export 后没有 pwmX 目录 |
通道号超出 npwm 范围;确认 cat npwm |
写 duty_cycle 报 Invalid argument |
duty_cycle > period;先设 period 再设 duty |
下一篇
附:真实设备树片段(PWM / 背光)
来自基础层 board-base.dtsi 的真实节点,印证上面的资源说明:
backlight0: backlight0 {
compatible = "pwm-backlight";
status = "okay";
default-brightness-level = <180>;
enable-gpios = <&pio PD 22 GPIO_ACTIVE_HIGH>;
pwms = <&pwm2 7 25000 1>; // 通道7,周期25000ns(40kHz),极性1
};
&pwm2 { status = "okay"; }; // PWM 控制器(14 通道)
&pwm2_7 {
pinctrl-0 = <&pwm2_7_pins_active>;
pinctrl-1 = <&pwm2_7_pins_sleep>;
status = "okay";
};
pwm2_7_pins_active: pwm2_7@0 { pins = "PD23"; function = "pwm2_7"; };《UART 串口实战》:除了调试串口,板子还有 ttyAS2 用户串口,怎么接线、用 microcom 收发、做回环测试。
作者:Mai 创建时间:2026-10-20 16:47
最后编辑:陈柏林 更新时间:2026-11-05 14:56
最后编辑:陈柏林 更新时间:2026-11-05 14:56