Luckfox Pico PWM 使用教程

PWM使用介绍

PWM,全称为脉冲宽度调制(Pulse Width Modulation),是一种通过控制信号的脉冲宽度来实现模拟信号输出的技术。它常用于嵌入式系统和电子设备中,用于控制电机速度、LED 亮度、音频信号生成等应用。在 Linux 系统中,PWM 设备通常通过 sysfs 文件系统进行管理和配置,其设备目录通常位于 /sys/class/pwm/目录下。
查看开发板pwm引脚分布

由于引脚复用,会有引脚功能冲突,所以开发板默认开启的PWM如下:
- PWM0_0 - 34 号引脚
- PWM1_0 - 4 号引脚
- PWM10_1 - 54 号引脚
- PWM11_1 - 55 号引脚
查看设备目录

在 /sys/class/pwm/ 目录中,每个 PWM 设备都有一个独立的子目录,其名称通常以 pwmchipX 的形式命名,其中 X 是 PWM 设备的编号。您可使用如下命令查看:
将PWM10_M1导出到用户空间

查看设备属性

- 查看PWM10单个通道的属性文件
- 属性文件通过使用这些属性文件,您可以轻松地配置和控制 PWM 通道,使其适应不同的应用场景和需求。其中一些关键的属性如下:
- enable:用于启用或禁用PWM通道。
- period:用于设置PWM信号的周期时间。
- duty_cycle:用于设置PWM信号的占空比。
- polarity:用于配置PWM信号的极性。
- power/control:用于启用或禁用PWM通道的电源管理(通常用于省电模式)。
shell控制PWM

- 设置PWM周期单位为ns,比如 1KHz 频率的周期就是 1000000ns(注意,在任何的情况下都得保证 period 的值大于等于 duty_cycle 的值)
- 设置占空比(小于等于 period )
- 设置PWM极性正常或翻转
- 使能和关闭PWM
- 取消导出PWM到用户空间
在成功导出 PWM 的一个通道后,会在该 PWM 的设备目录下生成单个通道的目录,其中有这个通道对应的属性文件,用户可以通过修改这些文件的内容来配置和控制特定 PWM 通道的各个参数,以实现对 PWM 信号的精确控制。这提供了一个方便的接口,使用户能够与 PWM 硬件进行交互并调整 PWM 信号的特性。
语言控制PWM




在前文中,我们演示了如何使用 echo 命令控制 PWM。实际上也可以使用 vi 编辑器对文件进行修改,修改时需注意用户权限。此外,我们还可以使用C库函数或系统调用来读写设备文件,以达到控制设备的目的。请注意,为了在特定的嵌入式系统上运行程序,通常需要使用交叉编译工具来编译代码,以生成可在目标开发板上执行的可执行文件。接下来,让我们一起探讨具体的实施步骤。
通过附件中的程序,可以实现控制PWM10输出。
1.导出PWM通道到用户空间
这段代码通过向 /sys/class/pwm/pwmchip10/export 写入设备索引(通常为0),以导出指定的PWM通道供用户空间控制。
FILE *pwm_export = fopen(PWM_PATH "/export", "w");
if (!pwm_export) {
perror("Failed to open PWM export");
return 1;
}
fprintf(pwm_export, "0");
fclose(pwm_export);
2.设置PWM周期
这段代码通过向 /sys/class/pwm/pwmchip10/pwm0/period 写入周期值 “1000000”(以纳秒为单位),以设置PWM的周期为1KHZ。
FILE *period_file = fopen(PWM_PATH "/pwm0/period", "w");
if (!period_file) {
perror("Failed to open PWM period");
return 1;
}
fprintf(period_file, "%d", PERIOD_NS);
fclose(period_file);
3.使能PWM
这段代码通过向 /sys/class/pwm/pwmchip10/pwm0/enable 文件写入值"1",以启用PWM信号的输出。
FILE *enable_file = fopen(PWM_PATH "/pwm0/enable", "w");
if (!enable_file) {
perror("Failed to open PWM enable");
return 1;
}
fprintf(enable_file, "1");
fclose(enable_file);
4.使用PWM实现呼吸灯
这段代码打开 /sys/class/pwm/pwmchip10/pwm0/duty_cycle 文件,并且通过不断改变 duty_cycle_ns 变量的值,实现了PWM占空比从0%逐渐增加到100%,然后再从100%逐渐减小到0%的呼吸灯效果。duty_cycle_ns 的变化在0到1000000之间,以控制占空比的变化。当占空比达到最小值或最大值时,它会反转方向,以实现往复运动。此外,usleep(50000) 函数用于控制呼吸灯的速度,您可以根据需要调整此值以改变呼吸速度。
int direction = 1;
int duty_cycle_ns = 0;
while (1) {
duty_cycle_ns += 10000 * direction;
if(duty_cycle_ns == MAX_DUTY_CYCLE_NS)
direction = -1;
else if(duty_cycle_ns == MIN_DUTY_CYCLE_NS)
direction = 1;
FILE *duty_cycle_file = fopen(PWM_PATH "/pwm0/duty_cycle", "w");
if (!duty_cycle_file) {
perror("Failed to open PWM duty cycle");
return 1;
}
fprintf(duty_cycle_file, "%d", duty_cycle_ns);
fclose(duty_cycle_file);
usleep(50000);
}
5.取消导出PWM通道到用户空间
这段代码通过向 /sys/class/pwm/pwmchip10/unexport 写入设备索引,取消导出指定的PWM通道到用户空间。
FILE *pwm_unexport = fopen(PWM_PATH "/unexport", "w");
if (!pwm_unexport) {
perror("Failed to open PWM unexport");
return 1;
}
fprintf(pwm_unexport, "0");
fclose(pwm_unexport);
交叉编译






- 指定交叉编译工具首先,我们要将交叉编译工具的路径添加到系统的 PATH 环境变量中,以便可以在任何地方使用交叉编译工具,您可以在shell配置文件中添加以下行(通常是 ~/.bashrc 或 ~/.bash_profile 或 ~/.zshrc,具体取决于您使用的shell),注意 PATH= 后的路径为交叉编译工具所在的目录。
- gcc路径
- 打开shell配置文件
- 将交叉编译工具的路径添加到系统的PATH环境变量中,将 <SDK Directory> 修改为自己的 SDK 路径,如 /home/mxf/linux/luckfox-pico/
- 重新加载shell配置文件,使更改生效
<SDK Directory>/tools/linux/toolchain/arm-rockchip830-linux-uclibcgnueabihf/bin/arm-rockchip830-linux-uclibcgnueabihf-gcc
vi ~/.bashrc
export PATH=<SDK Directory>/tools/linux/toolchain/arm-rockchip830-linux-uclibcgnueabihf/bin:$PATH
例如
export PATH=/home/mxf/linux/luckfox-pico/tools/linux/toolchain/arm-rockchip830-linux-uclibcgnueabihf/bin:$PATH
source ~/.bashrc
- 使用交叉编译工具编译程序
arm-rockchip830-linux-uclibcgnueabihf-gcc pwm.c -o pwm
- 交叉编译成功后,将在当前目录下生成可在开发板运行的可执行文件
#ls
pwm pwm.c
运行程序

- 文件传输先将 pwm 从虚拟机传输到 Windows,再通过 TFTP 或 ADB 传输到开发板,将文件从 Windows 通过 ADB 将文件传输到开发板的步骤如下:
adb push 文件所在路径 开发板存储路径
eg:(将当前目录下pwm文件传输到开发板的根目录)
adb push pwm /
- 运行程序修改 pwm 文件的操作权限后运行程序
# chmod 777 pwm
# ./pwm
- 实验现象控制PWM10输出,实现呼吸灯,详细见附件视频。











