1.PWM原理
PWM是Pulse-Width Modulation的简称,中文译作脉冲宽度调制。作为一种调制技术,PWM的原理是通过调整周期性波形的高电平时间宽度,从而改变有效信号的占空比,实现对设备的供电控制。PWM技术的常见应用领域包括屏幕背光亮度调节、电机转速控制和风扇转速控制等。 Linux内核支持PWM驱动框架,该驱动框架采用结构体数据类型对PWM控制器和PWM信号进行了抽象,提供了PWM驱动框架核心代码和sysfs接口代码。PWM驱动开发者可以方便地利用该驱动框架,添加特定PWM控制器的驱动程序,并使用sysfs接口进行功能调试。 2.PWM驱动
Linux 内核提供了个 PWM 子系统框架,编写 PWM 驱动的时候一定要符合这个框架。 PWM子系统的核心是 pwm_chip 结构体,定义在文件 include/linux/pwm.h 中:
struct pwm_ops结构体,包括PWM控制器的操作函数。其中应该由驱动开发者实现的2个基础函数为apply函数和get_state函数;apply函数用于配置PWM控制器,包括配置PWM信号的使能状态、周期、占空比、极性等;get_state函数用于在注册PWM控制器时获取指定PWM通道信号的初始状态,包括使能状态、周期、占空比、极性等:
舵机驱动: 舵机的控制一般需要一个20ms左右的时基脉冲,该脉冲的高电平部分一般为0.5ms-2.5ms范围内的角度控制脉冲部分,总间隔为2ms。以180度角度伺服为例,那么对应的控制关系是这样的: 0.5ms--------------0度; 1.0ms------------45度; 1.5ms------------90度; 2.0ms-----------135度; 2.5ms-----------180度; 硬件设计原理图,由芯片连接到蜂鸣器,如下所示: 同时在扩展IO中也引出了PWM引脚,连接示意图: 3.代码设计 - #include <stdio.h>
- #include <stdlib.h>
- #include <unistd.h>
- #include <fcntl.h>
- #include <string.h>
- #define PWM_PATH "/sys/class/pwm/pwmchip1"
- #define PWM_PIN "pwm0"
- void setPWM(int duty_cycle) {
- char path[100];
- int fd;
- // 构建duty_cycle文件路径
- snprintf(path, sizeof(path), "%s%s/duty_cycle", PWM_PATH, PWM_PIN);
- // 打开duty_cycle文件
- fd = open(path, O_WRONLY);
- if (fd < 0) {
- perror("Error opening duty_cycle");
- exit(-1);
- }
- // 写入duty_cycle值
- dprintf(fd, "%d", duty_cycle);
- // 关闭文件
- close(fd);
- }
- int main() {
- char period_path[100];
- int period_fd;
- // 构建period文件路径
- snprintf(period_path, sizeof(period_path), "%s%s/period", PWM_PATH, PWM_PIN);
- // 打开period文件
- period_fd = open(period_path, O_WRONLY);
- if (period_fd < 0) {
- perror("Error opening period");
- exit(-1);
- }
- // 设置PWM周期
- dprintf(period_fd, "%d", 20000000); // 假设周期为20ms
- // 关闭文件
- close(period_fd);
- // 循环控制舵机来回转动
- while (1) {
- setPWM(1500000); // 设置占空比为1.5ms
- usleep(1000000); // 延时1秒
- setPWM(2000000); // 设置占空比为2.0ms
- usleep(1000000); // 延时1秒
- }
- return 0;
- }
复制代码4.验证
|