嵌入式Linux:使用sysfs控制PWM
文章目录一、概述设备树配置二、命令行三、用户空间应用代码测试一、概述从上一篇嵌入式Linux:Qt5+触摸屏+点灯(使用sysfs控制gpio)第一次使用了sysfs控制GPIO现在使用同样的方式控制PWM。设备树配置配置sun8i-v3s.dtsipwm0_pins: pwm0 {pins = "PB4";function = "pwm0";};pwm1_pins: pwm1{
·
一、概述
从上一篇嵌入式Linux:Qt5+触摸屏+点灯(使用sysfs控制gpio)第一次使用了sysfs控制GPIO现在使用同样的方式控制PWM。
设备树配置
配置sun8i-v3s.dtsi
pwm0_pins: pwm0 {
pins = "PB4";
function = "pwm0";
};
pwm1_pins: pwm1{
pins = "PB5";
function = "pwm1";
};
pwm: pwm@1c21400 {
compatible = "allwinner,sun8i-v3s-pwm",
"allwinner,sun7i-a20-pwm";
reg = <0x01c21400 0x400>;
clocks = <&osc24M>;
#pwm-cells = <3>;
status = "okay";
};
配置sun8i-v3s-licheepi-zero.dts
&pwm{
pinctrl-names = "default";
pinctrl-0 = <&pwm0_pins>,<&pwm1_pins>;
status = "okay";
};
上电运行,目录下查看:
# cd /sys/class/pwm
# ls
pwmchip0
二、命令行
- 1.
echo 0 > /sys/class/pwm/pwmchip0/export
/*设置PWM4输出,调出pwm0目录下设备节点,用于以下配置 */
运行命令前
device export npwm power subsystem uevent unexport
运行命令后
device npwm pwm0 uevent export power subsystem unexport
-
2.
echo 1000000 >/sys/class/pwm/pwmchip0/pwm0/period
/*设置PWM4一个周期的持续时间,单位为ns,即1K Hz */ -
3.
echo 500000 >/sys/class/pwm/pwmchip0/pwm0/duty_cycle
/*设置一个周期中的”ON”时间,单位为ns,即占空比=duty_cycle/period=50% */ -
4.
echo 1 >/sys/class/pwm/pwmchip0/pwm0/enable
/*设置PWM4使能 */
OK,灯亮了!
三、用户空间应用代码测试
#include "stdlib.h"
#include "stdio.h"
#include "string.h"
#include "unistd.h"
#include "fcntl.h" //define O_WRONLY and O_RDONLY
//user_pin: PB4
#define SYSFS_PWM_EXPORT "/sys/class/pwm/pwmchip0/export"
#define SYSFS_PWM0 "0"
#define SYSFS_PWM1 "1"
#define SYSFS_PWM0_STATE "/sys/class/pwm/pwmchip0/pwm0/enable"
#define SYSFS_PWM1_STATE "/sys/class/pwm/pwmchip0/pwm1/enable"
#define SYSFS_PWM0_PERIOD "/sys/class/pwm/pwmchip0/pwm0/period"
#define SYSFS_PWM0_PERIOD_VAL "1000000" /*ns*/
#define SYSFS_PWM0_DUTY_CYCLE "/sys/class/pwm/pwmchip0/pwm0/duty_cycle"
#define SYSFS_PWM0_DUTY_CYCLE_VAL "500000" /*ns*/
#define SYSFS_PWM_EANBLE "1"
#define SYSFS_PWM_DISANBLE "0"
int main()
{
int fd;
//使能PWM0:echo 0 > /sys/class/pwm/pwmchip0/export
fd = open(SYSFS_PWM_EXPORT, O_WRONLY);
if(fd == -1)
{
printf("ERR: PWM pin open error.\n");
return EXIT_FAILURE;
}
write(fd, SYSFS_PWM0 ,sizeof(SYSFS_PWM0));
close(fd);
//设置周期:echo 1000000 > /sys/class/pwm/pwmchip0/pwm0/period
fd = open(SYSFS_PWM0_PERIOD, O_RDWR);
if(fd == -1)
{
printf("ERR: PWM period direction open error.\n");
return EXIT_FAILURE;
}
write(fd, SYSFS_PWM0_PERIOD_VAL, sizeof(SYSFS_PWM0_PERIOD_VAL));
close(fd);
//设置占空比: echo 500000 > /sys/class/pwm/pwmchip0/pwm0/duty_cycle
fd = open(SYSFS_PWM0_DUTY_CYCLE, O_RDWR);
if(fd == -1)
{
printf("ERR: PWM duty cycle pin value open error.\n");
return EXIT_FAILURE;
}
write(fd, SYSFS_PWM0_DUTY_CYCLE_VAL, sizeof(SYSFS_PWM0_DUTY_CYCLE_VAL));
close(fd);
// 使能PWM通道:echo 1 > /sys/class/pwm/pwmchip0/pwm0/enable
fd = open(SYSFS_PWM0_STATE, O_RDWR);
if(fd == -1)
{
printf("ERR: pwm open error.\n");
return EXIT_FAILURE;
}
while(1)
{
write(fd, SYSFS_PWM_EANBLE, sizeof(SYSFS_PWM_EANBLE));
usleep(1000000);
write(fd, SYSFS_PWM_DISANBLE, sizeof(SYSFS_PWM_DISANBLE));
usleep(1000000);
}
close(fd);
printf("INFO: PWM pin value open error.\n");
return 0;
}
编译代码
arm-linux-gnueabihf-gcc pwm.c -o pwm
拷贝到开发板运行代码
./pwm
板子上的灯动起来了:一秒钟亮暗!
四、Qt+触摸屏+滑块+灯亮度变化
核心Qt代码:
void MainWindow::execCmd1(int duty)
{
QString path = PWM_LED_PATH;
/* 由于system函数只能用char类型,所以进行了转换 */
/* config */
QString cmd_config = "echo 0 > /sys/class/pwm/pwmchip0/export";
QByteArray cmdby_off = cmd_config.toLatin1();
char* charCmd_config = cmdby_off.data();
system(charCmd_config);
/* period */
QString cmd_period = "echo 10000 > /sys/class/pwm/pwmchip0/pwm0/period";
QByteArray cmdby_period = cmd_period.toLatin1();
char* charCmd_period = cmdby_period.data();
system(charCmd_period);
/* duty cycle */
QString cmd_duty = "echo "+ QString::number(duty, 10) +" > /sys/class/pwm/pwmchip0/pwm0/duty_cycle";
QByteArray cmdby_duty = cmd_duty.toLatin1();
char* charCmd_duty = cmdby_duty.data();
system(charCmd_duty);
/* enable */
QString cmd_enable = "echo 1 > /sys/class/pwm/pwmchip0/pwm0/enable";
QByteArray cmdby_enable = cmd_enable.toLatin1();
char* charCmd_enable = cmdby_enable.data();
system(charCmd_enable);
}
// 滑块配置灯的亮度
void MainWindow::on_horizontalSlider_valueChanged(int value)
{
ui->label->setText(QString::number(value));
execCmd1(value);
}
更多推荐
已为社区贡献13条内容
所有评论(0)