OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 4440|回复: 0

《I.MX6U嵌入式Linux C应用编程指南 V1.1》第二十二章 WM应用编程

[复制链接]

1118

主题

1129

帖子

2

精华

超级版主

Rank: 8Rank: 8

积分
4672
金钱
4672
注册时间
2019-5-8
在线时间
1224 小时
发表于 2021-8-26 14:59:36 | 显示全部楼层 |阅读模式
本帖最后由 正点原子运营 于 2021-8-26 15:22 编辑

1)实验平台:正点原子阿尔法Linux开发板
2)  章节摘自【正点原子】《I.MX6U嵌入式Linux C应用编程指南 V1.1》

3)购买链接:https://detail.tmall.com/item.htm?id=609033604451
4)全套实验源码+手册+视频下载地址:http://www.openedv.com/docs/boards/arm-linux/zdyz-i.mx6ull.html
5)正点原子官方B站:https://space.bilibili.com/394620890
6)正点原子阿尔法Linux交流群:1027879335 QQ群.png

原子哥.jpg

微信公众号.png




第二十二章 WM应用编程


本章我们将学习如何对开发板上的PWM设备进行应用编程。


22.1应用层如何操控PWM
与LED设备一样,PWM同样也是通过sysfs方式进行操控,进入到/sys/class/pwm目录下,如下所示:
第二十二章 WM应用编程107.png
图 22.1.1 /sys/class/pwm目录下的内容
这里列举出了8个以pwmchipX(X表示数字0~7)命名的文件夹,这八个文件夹其实就对应了I.MX6U的8个PWM控制器,I.MX6U总共有8个PWM控制器,大家可以通过查询I.MX6U参考手册得知。
我们随便以其中一个为例,进入到pwmchip0目录下:
第二十二章 WM应用编程312.png
图 22.1.2 pwmchip0目录下的内容
在这个目录下我们重点关注的是export、npwm以及unexport这三个属性文件,下面一一进行介绍:
npwm:这是一个只读属性,读取该文件可以得知该PWM控制器下共有几路PWM输出,如下所示:
第二十二章 WM应用编程481.png
图 22.1.3 读取npwm属性文件
I.MX6U每个PWM控制器只有1路PWM输出,所以总共有8路PWM,分别对应I.MX6U的PWM1~PWM8这8路输出(pwmchip0对应PWM1,pwmchip1对应PWM2,以此类推,在阿尔法开发板出厂烧录的系统,PWM1已经被用作LCD背光控制了,应用层不能直接对它进行控制了;而其它PWM均不能使用,原因在于I/O资源不够,为了满足板子上其它外设对I/O引脚的需求,取舍情况下只能如此!所以本章无法在出厂系统中进行测试)。
export:与GPIO控制一样,在使用PWM之前,也需要将其导出,通过export属性进行导出,以下所示:
  1. echo 0 > export
复制代码


第二十二章 WM应用编程835.png
图 22.1.4 导出PWM
0表示一个编号,注意,每个PWM控制器(pwmchipX)下,使用export属性文件导出PWM时,编号都是从0开始;因为I.MX6U每个控制器都只有一路PWM,所以都只能使用编号0,如下所示:
  1. echo 0 > /sys/class/pwm/pwmchip0/export                #导出PWM1
  2. echo 0 > /sys/class/pwm/pwmchip1/export                #导出PWM2
  3. echo 0 > /sys/class/pwm/pwmchip2/export                #导出PWM3
  4. echo 0 > /sys/class/pwm/pwmchip3/export                #导出PWM4
  5. echo 0 > /sys/class/pwm/pwmchip4/export                #导出PWM5
  6. echo 0 > /sys/class/pwm/pwmchip5/export                #导出PWM6
复制代码


导出成功后会在pwmchipX(X表示数字0~7)目录下生成一个名为pwm0的目录,如图 22.1.4所示,稍后介绍。
unexport:将导出的PWM删除。当使用完PWM之后,我们需要将导出的PWM删除,譬如:
  1. echo 0 > unexport
复制代码


写入到unexport文件中的编号与写入到export文件中的编号是相对应的;需要注意的是,export文件和unexport文件都是只写的、没有读权限。
如何控制PWM
通过export导出之后,便会生成pwm0这个目录,我们进入到该目录下看看:
第二十二章 WM应用编程1561.png
图 22.1.5 pwm0目录下的内容
该目录下也有一些属性文件,我们重点关注duty_cycle、enable、period以及polarity这四个属性文件,接下来一一进行介绍。
enable:可读可写,写入"0"表示禁止PWM;写入"1"表示使能PWM。读取该文件获取PWM当前是禁止还是使能状态。
  1. echo 0 > enable                        #禁止PWM输出
  2. echo 1 > enable                        #使能PWM输出
复制代码


通常配置好PWM之后,再使能PWM。
polarity:用于设置极性,可读可写,可写入的值如下:
  1. "normal":普通;
  2. "inversed":反转;
  3. echo normal > polarity                        #默认极性
  4. echo inversed > polarity                        #极性反转
复制代码


很多SoC的PWM外设其硬件上并不支持极性配置,所以对应的驱动程序中并未实现这个接口,应用层自然也就无法通过polarity属性文件对PWM极性进行配置,阿尔法I.MX6U开发板出厂系统便是如此!
period:用于配置PWM周期,可读可写;写入一个字符串数字值,以ns(纳秒)为单位,譬如配置PWM周期为10us(微秒):
  1. echo 10000 > period                #PWM周期设置为10us(10 * 1000ns)
复制代码


duty_cycle:用于配置PWM的占空比,可读可写;写入一个字符串数字值,同样也是以ns为单位,譬如:
  1. echo 5000 > duty_cycle                #PWM占空比设置为5us
复制代码


22.2编写应用程序
通过上面的介绍,我们来编写一个简单的示例代码,如下所示:
示例代码 22.2.1 pwm应用程序示例代码
  1. /***************************************************************
  2. Copyright © ALIENTEK Co., Ltd. 1998-2021. All rights reserved.
  3. 文件名 : pwm.c
  4. 作者 : 邓涛
  5. 版本 : V1.0
  6. 描述 : PWM应用程序示例代码
  7. 其他 : 无
  8. 论坛 : <a href="www.openedv.com" target="_blank">www.openedv.com</a>
  9. 日志 : 初版 V1.0 2021/6/15 邓涛创建
  10. ***************************************************************/

  11. #include <stdio.h>
  12. #include <stdlib.h>
  13. #include <sys/types.h>
  14. #include <sys/stat.h>
  15. #include <fcntl.h>
  16. #include <unistd.h>
  17. #include <string.h>

  18. static char pwm_path[100];

  19. static int pwm_config(const char *attr, const char *val)
  20. {
  21.     char file_path[100];
  22.     int len;
  23.     int fd;

  24.     sprintf(file_path, "%s/%s", pwm_path, attr);
  25.     if (0 > (fd = open(file_path, O_WRONLY))) {
  26.         perror("open error");
  27.         return fd;
  28.     }

  29.     len = strlen(val);
  30.     if (len != write(fd, val, len)) {
  31.         perror("write error");
  32.         close(fd);
  33.         return -1;
  34.     }

  35.     close(fd);  //关闭文件
  36.     return 0;
  37. }

  38. int main(int argc, char *argv[])
  39. {
  40.     /* 校验传参 */
  41.     if (4 != argc) {
  42.         fprintf(stderr, "usage: %s <id> <period> <duty>\n",
  43.                 argv[0]);
  44.         exit(-1);
  45.     }

  46.     /* 打印配置信息 */
  47.     printf("PWM config: id<%s>, period<%s>, duty<%s>\n",
  48.             argv[1], argv[2],
  49.             argv[3]);

  50.     /* 导出pwm */
  51.     sprintf(pwm_path, "/sys/class/pwm/pwmchip%s/pwm0", argv[1]);

  52.     if (access(pwm_path, F_OK)) {//如果pwm0目录不存在, 则导出

  53.         char temp[100];
  54.         int fd;

  55.         sprintf(temp, "/sys/class/pwm/pwmchip%s/export", argv[1]);
  56.         if (0 > (fd = open(temp, O_WRONLY))) {
  57.             perror("open error");
  58.             exit(-1);
  59.         }

  60.         if (1 != write(fd, "0", 1)) {//导出pwm
  61.             perror("write error");
  62.             close(fd);
  63.             exit(-1);
  64.         }

  65.         close(fd);  //关闭文件
  66.     }

  67.     /* 配置PWM周期 */
  68.     if (pwm_config("period", argv[2]))
  69.         exit(-1);

  70.     /* 配置占空比 */
  71.     if (pwm_config("duty_cycle", argv[3]))
  72.         exit(-1);

  73.     /* 使能pwm */
  74.     pwm_config("enable", "1");

  75.     /* 退出程序 */
  76.     exit(0);
  77. }
复制代码


main()函数中,首先对传参进行校验,执行该应用程序的时候需要用户传入3个参数,分别是编号(0、1、2、3等,分别表示I.MX6U的PWM1、PWM2、PWM3…)、周期(以ns为单位)、PWM占空比(以ns为单位)。譬如:
  1. ./testApp 0 500000 250000
复制代码


接下来需要导出pwm,首先使用access()函数判断pwm0目录是否存在,如果存在表示pwm已经导出,如果不存在,则表示未导出,那么就需要通过export文件将其导出。
导出成功之后,接着配置PWM周期、占空比,最后使能PWM。
编译示例代码:
第二十二章 WM应用编程4613.png
图 22.2.1 编译应用程序
22.3在开发板上测试
编译好之后就可以在开发板上进行测试了,前面提到了,阿尔法开发板出厂系统没法测试PWM,如果大家想要测试PWM,可以对出厂系统的内核源码进行配置,只需修改设备树,禁用LCD和backlight背光设备(status属性设置为disabled即可),修改完之后重新编译设备树,用编译得到的设备树镜像文件(dtb文件)替换掉开发板启动文件中的dtb文件。大家也可以参考《I.MX6U嵌入式Linux驱动开发指南》第七十三章内容,自行配置PWM。
将上小节编译得到的可执行文件testApp拷贝到开发板Linux用户家目录下,然后运行:
第二十二章 WM应用编程4947.png
图 22.3.1 运行测试程序
本实验测试的是PWM1,笔者已经对设备树进行了配置,将LCD和backlight背光禁用了,阿尔法I.MX6U出厂系统已经将PWM1输出绑定到了GPIO1_IO08引脚,该引脚已经通过开发板上的扩展口引出,如下所示:
第二十二章 WM应用编程5117.png
图 22.3.2 GPIO1_IO08引脚
接下来使用示波器来检测GPIO1_IO08引脚的电平变换,如下所示:
第二十二章 WM应用编程5219.png
图 22.3.3 PWM波形
此时GPIO1_IO08引脚输出了PWM波形,其周期为500us(也就是500000ns),对应的频率为2KHz,占空比为50%,与我们配置的情况是一样的。
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2024-11-25 17:36

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表