PWM信号由一个固定频率的周期性脉冲序列组成,每个脉冲的宽度(持续时间)可以根据需要进行调节。调节脉冲宽度的比例可以改变平均电压或电流的大小,从而实现对设备的控制。
(相关资料图)
当谈论PWM时,以下三个关键术语经常被提及:
频率(Frequency):PWM信号的频率是指每秒钟内脉冲的数量。
周期(Period):PWM信号的周期是指一个完整脉冲序列所花费的时间。它是频率的倒数,以秒为单位表示。周期可以通过将频率的倒数计算得到,例如,一个10kHz的PWM信号的周期为0.1毫秒(100微秒)。
占空比(Duty Cycle):占空比是指PWM信号中脉冲宽度与周期之间的比例关系。它表示了脉冲在一个周期中所占据的时间比例,通常以百分比表示。占空比为0%意味着脉冲不存在(完全低电平),而占空比为100%表示脉冲持续时间占据了整个周期(完全高电平)。在实际应用中,占空比可以在0%到100%之间任意调整,以实现所需的控制效果。
pwm驱动是一个通用的驱动,SOC厂家都会在SDK里面默认打开
驱动文件所在位置:
drivers/pwm/pwm-rockchip.c
默认SDK已经加载好了PWM的驱动,下文我们主要注意PWM怎么使用
DTS 配置参考文档
Documentation/devicetree/bindings/pwm/pwm.txt
以下为一个例子的示例
Node name { compatible = "Driver matching character"; pwms = < &pwmX 0 25000 0 >; }; &pwmX { status = "okay"; pinctrl-names = "active"; pinctrl-0 = < &pwmX_pin_pull_down >; };
pwms的几个参数说明如下:
参数 1,表示 index (per-chip index of the PWM to request),一般是 0,因为我们 Rockchip PWM 每个chip 只有一个。
参数 2,表示 PWM 输出波形的时间周期,单位是 ns;例如下面配置的 25000 就是表示想要得到的
PWM 输出周期是 40K 赫兹。
参数 3,表示极性,为可选参数;下面例子中的配置为负极性。
PWM 提供了用户层的接口,在 /sys/class/pwm/ 节点下面,PWM 驱动加载成功后,会在/sys/class/pwm/ 目录下产生 pwmchip0 目录;向 export 文件写入 0,就是打开 pwm 定时器0,会产生一个 pwm0 目录,相反的往 unexport 写入 0 就会关闭 pwm 定时器了,同时 pwm0 目录会
被删除,该目录下有以下几个文件:
enable:写入 1 使能 pwm,写入 0 关闭 pwm;
polarity:有 normal 或 inversed两个参数选择,表示输出引脚电平翻转;
duty_cycle:在 normal 模式下,表示一个周期内高电平持续的时间(单位:纳秒),在
reversed 模式下,表示一个周期中低电平持续的时间(单位:纳秒);
period:表示 pwm 波的周期(单位:纳秒);[page]
以下是 pwmchip0 的例子,设置 pwm0 输出频率 100K,占空比 50%, 极性为正极性:
cd /sys/class/pwm/pwmchip0/echo 0 > exportcd pwm0echo 10000 > periodecho 5000 > duty_cycleecho normal > polarityecho 1 > enable
通常电子设备中应用pwm是比较常见的,比如风扇电机控制,电视背光控制, LED 照明调光、电动工具马达控制、汽车加热器等领域。
这里简单介绍一下pwm控制LED灯实现呼吸灯效果。
呼吸灯需要灯的驱动与PWM的驱动结合,两个驱动之间传递数据,我们可以在驱动中调用其他的驱动。
led是我需要的设备,这个设备用到了pwm,而pwm是用默认的驱动。
硬件上我们在开发板找到具有pwm功能的引脚
设备树的修改如下:
/{breathing_light {compatible = "lhd,breathing_light_test";backlight {pwms = < &pwm8 0 25000 0 >;pwm-names = "breathing_light"; };};};&pwm8 {status = "okay";};
写一个驱动。内部在使用PWM子系统。形成了包含驱动的驱动。
驱动程序
#include < linux/init.h >#include < linux/module.h >#include < linux/fs.h >#include < linux/cdev.h >#include < linux/uaccess.h >#include < linux/types.h >#include < linux/kernel.h >#include < linux/delay.h >#include < linux/ide.h >#include < linux/errno.h >#include < linux/gpio.h >//#include < asm/mach/map.h >#include < linux/of.h >#include < linux/of_address.h >#include < linux/of_gpio.h >#include < asm/io.h >#include < linux/device.h >#include < linux/platform_device.h >#include < linux/pwm.h >#define RED_LED_DTS_COMPATIBLE "lhd,breathing_light_test" /* 设备树节点匹配属性 */#define LED_PWM_CMD_SET_DUTY 0x01#define LED_PWM_CMD_SET_PERIOD 0x02#define LED_PWM_CMD_SET_BOTH 0x03#define LED_PWM_CMD_ENABLE 0x04#define LED_PWM_CMD_DISABLE 0x05struct led_pwm_param{ int duty_ns; int period_ns;};struct red_led_dev { dev_t dev_no; struct cdev chrdev; struct class *led_class; struct device_node *dev_node; struct pwm_device *red_led_pwm;};static struct led_pwm_param led_pwm;static struct red_led_dev led_dev;static int red_led_drv_open (struct inode *node, struct file *file){ int ret = 0; //pwm_set_periodnnn(led_dev.red_led_pwm, PWM_POLARITY_INVERSED);//设置PWM信号的极性pwm_enable(led_dev.red_led_pwm);//启用指定PWM设备,使其开始输出PWM信号。 printk("red_led_pwm open"); return ret;}static ssize_t red_led_drv_write (struct file *file, const char __user *buf, size_t size, loff_t *offset){ int err; if (size != sizeof(led_pwm)) return -EINVAL;err = copy_from_user(&led_pwm, buf, size); if (err > 0) return -EFAULT;pwm_config(led_dev.red_led_pwm, led_pwm.duty_ns, led_pwm.period_ns);//配置PWM设备的基本参数,如频率、占空比等。 printk("red_led_pwm write");return 1;}static long drv_ioctl(struct file *filp, unsigned int cmd, unsigned long arg){ int ret = 0; void __user *my_user_space = (void __user *)arg; switch (cmd) { case LED_PWM_CMD_SET_DUTY: ret = copy_from_user(&led_pwm.duty_ns, my_user_space, sizeof(led_pwm.duty_ns)); if (ret > 0) return -EFAULT; pwm_config(led_dev.red_led_pwm, led_pwm.duty_ns, led_pwm.period_ns); break; case LED_PWM_CMD_SET_PERIOD: ret = copy_from_user(&led_pwm.period_ns, my_user_space, sizeof(led_pwm.period_ns)); if (ret > 0) return -EFAULT; pwm_config(led_dev.red_led_pwm, led_pwm.duty_ns, led_pwm.period_ns); break; case LED_PWM_CMD_SET_BOTH: ret = copy_from_user(&led_pwm, my_user_space, sizeof(led_pwm)); if (ret > 0) return -EFAULT; pwm_config(led_dev.red_led_pwm, led_pwm.duty_ns, led_pwm.period_ns); break; case LED_PWM_CMD_ENABLE: pwm_enable(led_dev.red_led_pwm); break; case LED_PWM_CMD_DISABLE: pwm_disable(led_dev.red_led_pwm); break; } return 0;}static int red_led_drv_release(struct inode *node, struct file *filp){ int ret = 0; pwm_config(led_dev.red_led_pwm, 0, 5000);//配置PWM设备的基本参数,如频率、占空比等。 printk("led pwm dev close");// pwm_disable(led_dev.red_led_pwm); return ret;}static struct file_operations red_led_drv = {.owner = THIS_MODULE,.open = red_led_drv_open,.write = red_led_drv_write, .unlocked_ioctl = drv_ioctl, .release = red_led_drv_release,};/*设备树的匹配列表 */static struct of_device_id dts_match_table[] = { {.compatible = RED_LED_DTS_COMPATIBLE, }, {}, };static int led_red_driver_probe(struct platform_device *pdev){ int err; int ret; struct device *tdev; struct device_node *child; tdev = &pdev- >dev; child = of_get_next_child(tdev- >of_node, NULL); /* 获取设备树子节点 */if (!child) { return -EINVAL; } led_dev.red_led_pwm = devm_of_pwm_get(tdev, child, NULL); /* 从子节点中获取PWM设备,设备树获取这个设备就可以了 */ if (IS_ERR(led_dev.red_led_pwm)) { printk(KERN_ERR"can"t get breathing_light!!"); return -EFAULT; } ret = alloc_chrdev_region(&led_dev.dev_no, 0, 1, "breathing_light");//动态分配字符设备的主设备号if (ret < 0) {pr_err("Error: failed to register mbochs_dev, err: %d", ret);return ret;}cdev_init(&led_dev.chrdev, &red_led_drv);//初始化字符设备结构体cdevcdev_add(&led_dev.chrdev, led_dev.dev_no, 1);//将已经初始化的字符设备结构体cdev添加到系统中 led_dev.led_class = class_create(THIS_MODULE, "breathing_light");//创建一个设备类(device class)并注册到内核中err = PTR_ERR(led_dev.led_class);if (IS_ERR(led_dev.led_class)) { goto failed1;} tdev = device_create(led_dev.led_class , NULL, led_dev.dev_no, NULL, "breathing_light"); //创建一个设备实例并注册到设备类中 if (IS_ERR(tdev)) { ret = -EINVAL;goto failed2;} printk(KERN_INFO"%s %s line %d", __FILE__, __FUNCTION__, __LINE__); return 0;failed2: device_destroy(led_dev.led_class, led_dev.dev_no); class_destroy(led_dev.led_class);failed1: cdev_del(&led_dev.chrdev);unregister_chrdev_region(led_dev.dev_no, 1); return ret;}int led_red_driver_remove(struct platform_device *dev){ // pwm_disable(led_dev.red_led_pwm); // pwm_free(led_dev.red_led_pwm); printk(KERN_INFO"driver remove %s %s line %d", __FILE__, __FUNCTION__, __LINE__); device_destroy(led_dev.led_class, led_dev.dev_no);class_destroy(led_dev.led_class);unregister_chrdev_region(led_dev.dev_no, 1); cdev_del(&led_dev.chrdev); return 0;}static struct platform_driver red_led_platform_driver = { .probe = led_red_driver_probe, .remove = led_red_driver_remove, .driver = { .name = "lhd,breathing_light_test", .owner = THIS_MODULE, .of_match_table = dts_match_table, //通过设备树匹配 },};module_platform_driver(red_led_platform_driver);MODULE_AUTHOR("LHD");MODULE_LICENSE("GPL");
将上述驱动编译为ko文件然后push进3588开发板里面[page]
应用层程序
#include "stdio.h"#include < sys/types.h >#include < sys/stat.h >#include < fcntl.h >#include < unistd.h >#include < stdio.h >#include < string.h >#include < sys/ioctl.h >#include < poll.h >#include < stdint.h >#define DEV_NAME "/dev/breathing_light"#define LED_PWM_CMD_SET_DUTY 0x01#define LED_PWM_CMD_SET_PERIOD 0x02#define LED_PWM_CMD_SET_BOTH 0x03#define LED_PWM_CMD_ENABLE 0x04#define LED_PWM_CMD_DISABLE 0x05struct led_pwm_param { int duty_ns; int period_ns;};void sleep_ms(unsigned int ms){ struct timeval delay;delay.tv_sec = 0;delay.tv_usec = ms * 1000; select(0, NULL, NULL, NULL, &delay);}int main(int argc, char **argv){ int fd; int ret; /* 2. 打开文件 */fd = open(DEV_NAME, O_RDWR | O_NONBLOCK); // | O_NONBLOCKif (fd < 0){printf("can not open file %s, %d", DEV_NAME, fd);return -1;} int buf = 3;struct led_pwm_param led_pwm;led_pwm.duty_ns = 500;led_pwm.period_ns = 5000; write(fd, &led_pwm, sizeof(led_pwm)); sleep_ms(3000);while(1){if(led_pwm.duty_ns<=500){while(led_pwm.duty_ns< led_pwm.period_ns){ioctl(fd, LED_PWM_CMD_SET_DUTY, &led_pwm.duty_ns);sleep_ms(50);led_pwm.duty_ns += 300;}}else{while(led_pwm.duty_ns > 500){ioctl(fd, LED_PWM_CMD_SET_DUTY, &led_pwm.duty_ns);sleep_ms(50);led_pwm.duty_ns -= 300;}}}close(fd); return 0;}
使用3588自带的编译器将用户程序编译进开发板
prebuilts/gcc/linux-x86/aarch64/gcc-arm-10.3-2021.07-x86_64-aarch64-none-linux-gnu/bin/aarch64-none-linux-gnu-gcc apptest_breathing_light_.c -o testpwm
adb push path/testpwm /userdata
chmod 777 testpwm
./testpwm
最后可以看到灯明灭交替的效果
审核编辑:汤梓红
上一篇:环球最新:快来泰达植物资源库打卡 新晋“花王”绣球花盛放迎客
下一篇:最后一页
RK3588开发板(armsom-w3)之PWM实操
赤霞珠后劲大,因为是红葡萄酒用黑皮诺酿制的红葡萄酒是勃艮第(Burgun
天津北方网讯:芒种时节,继月季热烈开放后,在泰达植物资源库水芝园东
据美联社6月10日报道,哥伦比亚当局9日宣布,40天前,一架小型飞机由于
南方财经全媒体记者胡慧茵广州报道随着我国经济进入高质量发展阶段,我
建立健全网约车退出机制近日,长沙市交通运输部门发布消息称,已暂停受
洱源县气象局、洱源县自然资源局2023年6月10日09时55分联合发布地质灾
演讲中,阿尔特曼表示,未来十年,通用人工智能(ArtificialGeneralInt
南方财经全媒体见习记者刘琛广州报道6月9日,第12届中国(广州)国际金
原标题:中超-进球大战奥乌苏世界波力助沧州雄狮赢球央视网消息:中超
国宝说话!西安公安创意沙画再现“石椁归家记”---6月10日是2023年“文
1、1024*768是四比三的比例。2、分辨率可以从显示分辨率与图像分辨率两
1、譬如说,图纸的比例是1:100,图上1cm实际是100cm。2、按比例4:6分成,100
你们好,最近小信发现有诸多的小伙伴们对于刺激战场手游脚本,刺激战场
你们好,最近小活发现有诸多的小伙伴们对于影音先锋电影在线观看,影音
众所周知,王楠是国乒大满贯,昔日的女乒一姐,曾经是手握世界冠军最多
北京时间6月11日凌晨3点,欧冠决赛,曼城将和国米决出最后的冠军。若曼
中超第12轮,泰山1-1战平三镇,王大雷赛后表示,崔指导带领球队走上正
1 时间反复逼得我不得不承认,你是我不该爱的人。2 没有你的日子我
关于绵阳有什么土特产可以送礼的的内容,包含绵阳有什么特产可以带?黄
6月9日,国新办就首届中国国际供应链促进博览会筹备情况举行发布会。中
提到港口,你会想到什么?头戴安全帽的工人在操作吊机,还是一辆辆卡车
想必现在有很多小伙伴对于镀锌铁丝与不锈钢丝有什么区别方面的知识都比
你想要的,岁月都会给你。2023年高考即将到来,无数学子在历经千锤
参考消息网6月9日报道 美国《新闻周刊》网站5月20日刊发题为《三种
直播吧6月10日讯梅西加盟迈阿密国际。截至发稿时,迈阿密国际2天时间涨
北京时间6月10日,总决赛第四战打响,场边意外不断。第三节,篮筐一度
在股权转让、放弃表决权的同时,苏州丰瑞达拟通过现金方式认购ST南卫向
今年北京高考化学试题较简单?专家:稳中求进、稳中创新2023年6月9日,
解答:1、水晶棉是一种功能性织物,织物成分复杂,包括纯化纤织物和棉
本赛季,决赛在伊斯坦布尔进行,国米也是“客队”,要是在比赛中,国米
中国侨网广州6月10日电 (郭军 冯静静 王索)“今天,一个大写的中
6月12日,随着A股主要股指迎来样本股调整,已经上线运行一年之久的每经
原标题:546家企业获评省级专精特新中小企业近日,省工信厅公布了今年
中新网温州6月9日电2023年中国保龄球巡回赛温州公开赛9日进入第二比赛
父母的态度决定孩子的感受,父母怎么对待孩子,孩子就会用同样的方
1、绿都的BOSS有个书架的BOSS杀它就能的道灵介质 绿都的BOSS有个书架的
6月9日,广深铁路(601333)融资买入4030 41万元,融资偿还5049 24万元
中新网乌鲁木齐6月9日电(王小军刘一栋)“我建议建筑行业要有发散思维,
白酒度数有这些白酒度数从18度到78度,分4个档次:低度、中度、高度、
“孩子学校门口场地有限制,缺乏躲雨设施,暴雨天气接送孩子不方便。”
一场马拉松,点“燃”一座城凌晨5点许多城市都还在沉睡而贵阳已经“燃
1、满意答案Sarah Winner14级2009-10-041,简单通俗地来说,所有者权益
1、因为《巨轮2》是港剧属境外剧,根据广电总局的限外令,从2015年开始
《2023年中国本科生就业报告》显示,2022届本科、高职毕业生月收入分别
上篇引路:舞台幕后,这是一场紧张的演出…[演奏家]显得有些慌乱…“您
贷款还完 可以追究退回不合理利息吗
在生物医药界,教授 科学家被围堵不足为奇,自带光环的ADC也不例外。一
1、电脑打开,停在桌面上,准备启动。2、选择电脑上的一个浏览器,任何
1、这是个假消息。2、六小龄童都出来辟谣了。本文到此分享完毕,希望对
什么是单页面网页设计?随着移动互联网的发展,单页面网页设计成为了各
【在罚单中快速扩张的核子基因: 核子基因一个月开8家检验实验室 , 核
思想政治教育是围绕人做工作的,应该有直达人心、引发共鸣的效果,为扎
儿童福利和未成年人保护是一项充满温情和责任的事业。近年来,江苏省不
追梦:掘金可以横扫湖人,也可以击败我们,但有一队可以治他们!,湖人,
文旅新项目激活乡村振兴“一池春水”6月7日,三元区洋溪镇清枫谷景区内
证券时报·数据宝统计,今日主力资金净流入41 13亿元,其中创业板净流
作为A股速冻食品头部企业,安井食品(603345)6月9日晚间公告,拟在四川
1、这里我整理了beyond陈奕迅许嵩周杰伦林俊杰等歌星的所有歌曲。2、有
你们好,最近小信发现有诸多的小伙伴们对于小学生新年祝福卡片制作,小
6月8日早晨,紫阳县蒿坪镇派出所接到一起特殊警情,称辖区一幼儿园内有
1、董家渡地区位于上海老城厢与黄浦江南外滩之间,境内有上海现存最早
昨日,2023年“世界海洋日暨全国海洋宣传日”主场活动在广东汕头举行。
可能在未来,延寿和健康衰老都能依靠牛磺酸来实现
当大家在热切讨论插电混动如何替代燃油车时,不能插电的油电混动是不是
2022年9月16日,据企查查信息,深圳市中科微光医疗器械技术有限公司(
1、答:什么面料的毛衣又保暖又轾又显瘦又不起球?2、正宗的羊毛绒毛衣
解答:1 在手机主界面找到“设置”应用,点击进入。2 在“设置”界面,
1、70CC:鞋子+6 5%移速,头肩+3 5攻速,套装属性移速+5 5%攻速+5 5
中交地产最新股东户数5 98万户,低于行业平均水平。公司户均持有流通股
近年来,随着生态环境的明显改善以及野生动物保护宣传力度的不断加大,
近日,为充分发挥校企双方资源优势,重庆对外经贸学院实训基地揭牌仪式
1、如果满意请在采纳的时候给一个满意评价··谢谢一一+····。本文
你们好,最近小活发现有诸多的小伙伴们对于播控云是什么技术,播控云这
南京绿环召开机械化清扫专项研讨及实操演练扬子晚报网6月9日讯(通讯员
根据以下资料,回答1-5题。图2014-2019年全国生活垃圾清运量(万吨)2019
龙里县2023年面向社会公开招聘城市社区工作者笔试工作已结束,根据《龙
根据工作安排,兹定于2023年6月17日组织阳原县2023年公开招聘社区工作
按照《关于印发的通知》(闽人发〔2006〕11号)和《2022年福建幼儿师范高
商洛新闻网讯:今天(6月9日)下午,陕西省气象台发布大风蓝色预警信号
来源:格隆汇格隆汇6月9日丨Coinbase(COIN US)盘前跌超1%,报54 26美元
日前,中国人寿保险股份有限公司(以下简称“中国人寿寿险公司”)发布了
为了普及牙齿防治知识,培养社区儿童从小养成良好的口腔习惯,6月9日,
现在京享值是京东商城根据用户的多方面综合计算得出的分值,是每日更
澳优佳贝艾特羊奶粉推新,与伊利产业链深化协同,澳优,伊利,羊奶粉,产业
养老保险交哪个档次好,要根据自己得实际情况来确定。接下来跟社保网小
居民可以根据自身实际情况选择合适的缴费档次来进行参保,接下来跟社保
截至2023年6月9日收盘,丰山集团(603810)报收于13 46元,下跌0 88%,换
仁和药业:公司九届十三次临时董事会决议公告
挪威拟向深海采矿开放北冰洋地区海域,目标成首个从海底提取电池金属的
象舞指数|体育短视频周榜(5月28日—6月3日)---中央广播电视总台“象
通合科技公告,拟在石家庄高新区投资建设石家庄总部扩建项目(包括但不
北京时间6月8日下午,2024年u20女足亚洲杯预选赛第二阶段b组第二轮比赛
快科技6月9日消息,在浏览网页时,你是否曾见到过类似这样的链接?(下
快科技6月9日消息,全新雷克萨斯GX正式发布,该车与全新丰田兰德酷路泽
1、理解父母的想法。我们需要了解父母为什么不让孩子上学。这可能是因
1、找到和父母交谈的最佳时机。你要选个合适的时间和地点跟父母谈谈。
北京市气象台9日6时发布:今天白天晴转多云,北部山区有雷阵雨,北风二
本报讯(记者赵晓松)昨天下午,2024年U20女足亚洲杯预选赛第二阶段B组
今天小编岚岚来为大家解答以上的问题。蜜蜡怎么辨别真假视频教程,蜜蜡
X 关闭
银行理财产品是什么?银行理财产品有哪些种类?
降准指的是什么意思?降准对老百姓意味着什么?
国债是怎么赚钱的?国债利率下降会不会亏损呢?
国债收益率下跌说明什么?国债收益率下跌还可以买入吗?
X 关闭