1回答

0收藏

[评测分享] 【更适合初学者的开发板ELF 1】+ 5.PWM设备驱动舵机

#板卡评测 #板卡评测 2880 人阅读 | 1 人回复 | 2023-12-17

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.代码设计
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <unistd.h>
  4. #include <fcntl.h>
  5. #include <string.h>

  6. #define PWM_PATH "/sys/class/pwm/pwmchip1"  
  7. #define PWM_PIN "pwm0"  

  8. void setPWM(int duty_cycle) {
  9.     char path[100];
  10.     int fd;

  11.     // 构建duty_cycle文件路径
  12.     snprintf(path, sizeof(path), "%s%s/duty_cycle", PWM_PATH, PWM_PIN);

  13.     // 打开duty_cycle文件
  14.     fd = open(path, O_WRONLY);
  15.     if (fd < 0) {
  16.         perror("Error opening duty_cycle");
  17.         exit(-1);
  18.     }

  19.     // 写入duty_cycle值
  20.     dprintf(fd, "%d", duty_cycle);

  21.     // 关闭文件
  22.     close(fd);
  23. }

  24. int main() {
  25.     char period_path[100];
  26.     int period_fd;

  27.     // 构建period文件路径
  28.     snprintf(period_path, sizeof(period_path), "%s%s/period", PWM_PATH, PWM_PIN);

  29.     // 打开period文件
  30.     period_fd = open(period_path, O_WRONLY);
  31.     if (period_fd < 0) {
  32.         perror("Error opening period");
  33.         exit(-1);
  34.     }

  35.     // 设置PWM周期
  36.     dprintf(period_fd, "%d", 20000000); // 假设周期为20ms

  37.     // 关闭文件
  38.     close(period_fd);

  39.     // 循环控制舵机来回转动
  40.     while (1) {
  41.         setPWM(1500000); // 设置占空比为1.5ms
  42.         usleep(1000000); // 延时1秒

  43.         setPWM(2000000); // 设置占空比为2.0ms
  44.         usleep(1000000); // 延时1秒
  45.     }

  46.     return 0;
  47. }
复制代码
4.验证




分享到:
回复

使用道具 举报

回答|共 1 个

倒序浏览

您需要登录后才可以回帖 注册/登录

本版积分规则

1326 积分
16 主题
+ 关注
热门推荐
关闭

站长推荐上一条 /3 下一条