RK3588开发板(armsom-w3)之PWM实操
PWM介绍
专栏总目录PWM是脉宽调制(Pulse Width Modulation)的缩写。它是一种用于控制电子设备的技术,通过改变电信号的脉冲宽度来实现对设备的控制。PWM基本概念
PWM信号由一个固定频率的周期性脉冲序列组成,每个脉冲的宽度(持续时间)可以根据需要进行调节。调节脉冲宽度的比例可以改变平均电压或电流的大小,从而实现对设备的控制。
(资料图片仅供参考)
当谈论PWM时,以下三个关键术语经常被提及:
频率(Frequency):PWM信号的频率是指每秒钟内脉冲的数量。
周期(Period):PWM信号的周期是指一个完整脉冲序列所花费的时间。它是频率的倒数,以秒为单位表示。周期可以通过将频率的倒数计算得到,例如,一个10kHz的PWM信号的周期为0.1毫秒(100微秒)。
占空比(Duty Cycle):占空比是指PWM信号中脉冲宽度与周期之间的比例关系。它表示了脉冲在一个周期中所占据的时间比例,通常以百分比表示。占空比为0%意味着脉冲不存在(完全低电平),而占空比为100%表示脉冲持续时间占据了整个周期(完全高电平)。在实际应用中,占空比可以在0%到100%之间任意调整,以实现所需的控制效果。
PWM驱动
pwm驱动是一个通用的驱动,SOC厂家都会在SDK里面默认打开
驱动文件
驱动文件所在位置:
drivers/pwm/pwm-rockchip.c
默认SDK已经加载好了PWM的驱动,下文我们主要注意PWM怎么使用
DTS 节点配置
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使用
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 波的周期(单位:纳秒);
以下是 pwmchip0 的例子,设置 pwm0 输出频率 100K,占空比 50%, 极性为正极性:
cd /sys/class/pwm/pwmchip0/echo 0 > exportcd pwm0echo 10000 > periodecho 5000 > duty_cycleecho normal > polarityecho 1 > enablePWM应用实例
通常电子设备中应用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开发板里面
应用层程序
#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实操
- 2023年国家医保目录调整征求意见:6月底前获批药物均可参与 谈判最早9月
- 气泡水和苏打水的区别和危害 气泡水和苏打水的区别
- 仙人掌的基本资料_仙人掌的资料大全简介
- 官方:本菲卡与奥塔门迪续约至2025年
- 佐鸣漫画游泳课后_佐鸣漫画
- 广西启动防汛Ⅳ级应急响应_全球快看
- 美股多数高开 纳指涨0.56% 每日热议
- b2h是什么_B2G是什么意思 做什么的 B2G和B2A一样吗
- 我的老婆是学生会长第一季 我的老婆是学生会长第二季 今头条
- 热资讯!异界少女召唤术漫画结局_异界少女召唤术漫画
- 广州市上市公司高质量发展基金将设立 目标规模200亿元 焦点短讯
- 世界速读:世龙实业:截至2023年5月31日,公司股东总户数为1.42万户
- 35岁女士双肾多发结石,微创中心寻踪觅迹揪出颈部“元凶”_世界微速讯
- 国乒17人参赛名单出炉!樊振东成夺冠最大热门,王楚钦孙颖莎参赛
- 一张图:2023/06/09黄金原油外汇股指"枢纽点+多空占比"一览
- 全球报道:第五批全国检察业务专家揭晓 湖北3人入选
- 金牛座最佳朋友星座(金牛座和什么座最配做朋友)
- 当前观察:提供1100个岗位!徐州市举办2023首场高校毕业生医药卫生类专场招聘会
- 文博会福田区配套活动|第五届深圳现代音乐艺术节本周日启幕
- 天天看点:英国要办AI峰会,英媒操心“请不请中国”
- 消防操作证书_消防操作证
- 医护狂奔6楼10分钟急救高考生 考前吹了一夜空调
- 董家庄村_关于董家庄村的简介 全球简讯
- 上海市全民数字素养与技能提升月收官,开展各类活动上千场
- 精选!低落伤心难过的时候网名取什么名字好呢_处于低谷期状态的网名 满是委屈的难过昵称
- 全球观察:保利发展首5月签约额涨23.5%至1966.6亿 近期新增5地产项目
- 资讯:高考前身份证丢了 别着急!民警帮您想办法
- 诊刮子宫内膜一般要休息多久_诊刮和清宫一样吗
- 特朗普又要被起诉?特朗普被检方明确通知是调查目标|世界消息
- 李云泽:将正式启动上海再保险国际版|环球焦点
- 完善全品类布局 一汽奔腾加速冲锋头部阵营
- 2023年5月新能源汽车销量预估解读,中国车企当仁不让扛把子-全球聚焦
- 蔚蓝锂芯(002245):6月8日北向资金减持12.63万股 全球焦点
- 拯救珊瑚、追迹海丝,世界海洋日专场在广州黄埔举办
- 高收益下如何控回撤?深挖招银理财“固收+权益”产品投资策略丨机警理财日报
- 一张蓝图绘到底!中国人寿寿险公司深入推进“科技国寿”战略
- 全球时讯:朝阳多个小区即将进行拆迁旧改!多地拆迁问题官方也答复了!
- 北京22家校企共建产教联合体!企业优秀员工可特招读研|今日报
- 屠光绍:上海自贸区促进全国高水平对外开放迈向新台阶-环球快播
- 小说结尾的作用阅读答案(小说结尾的作用)
- 安切洛蒂:解雇马尔蒂尼 不尊重米兰传统 这样的俱乐部注定会失败_天天快播
- 《暗黑破坏神4》M站仅5.8分:无聊重复 不值这个价! 天天新动态
- 天天热推荐:勇士试训了大四锋线老将,他正是球队急需的足尺寸3D类型球员?
- 造梦西游1无敌版手机版一击秒杀在哪_造梦西游1无敌版 天天热推荐
- 图灵看市6.8晚-黄金短期修复、空头将测试前低
- 全球热头条丨路演现场挥洒热情,高效对接创造精彩瞬间(投融界第695期创投对接微路演成功举办)
- 云南经济持续恢复稳中向好,多项指标增速高于全国-世界最资讯
- 2元仅能冲洗30秒!游客吐槽在青岛一海水浴场冲脚要扫码支付,景区回应:没有免费的|全球热资讯
- 20年“老慢支”顽疾竟是肺内古董在作祟 环球最新
- 当前看点!如何拿第一?一汽奔腾NAT青岛节能挑战赛冠军访谈
- 全球热推荐:长沙生态动物园门票购买入口汇总
- 首批路测牌照发放,无人驾驶加速落地,这些概念股机构关注_每日快播
- 麻栗坡县气象台发布暴雨黄色预警信号【Ⅲ级/较重】【2023-06-08】
- 淮安市首发淮安市农村土地承包经营权不动产权证书-世界独家
- “5亿高中生”案出现“神秘女子”,检方传唤讯问2小时,身份随后曝光
- 中国电信广东客服:经紧急抢修,受影响的用户正逐步恢复
- Doris为什么那么快?
- 将“青少年模式”纳入标准 网络表演直播短视频领域再出新“团标”
- 日本:东京玩具展开幕
- 朗进科技:公司拥有成熟的液冷技术及产品,公司坚持持续创新,不断研发新技术和新产品,更好的满足客户需求-每日看点
- 新疆持续优化营商环境 紧贴民生推动高质量发展
- rf网盘停止服务_rf网盘_世界速看料
- 如通股份: 董事集中竞价减持股份结果公告
- 乘联会:5月全国乘用车市场零售达174.2万辆 同比增长28.6% 环比增长7.3%
- 【天天速看料】“幼”见交警 安全“童”行:合肥幼教集团世茂首府幼儿园开展交通警察进课堂活动
- 雄安新区第四届“智绘未来”创新创业大赛启动
- 公积金提取额度是多少?_公积金提取额度是多少
- ml-1676打印机驱动下载_ml1676打印机驱动下载
- 陈道明:每个人的人生都是主旋律_观焦点
- 印尼东爪哇南部海域6.0级地震 喷发中的默拉皮火山未受影响 全球百事通
- 鞋子简笔画儿童画_鞋子简笔画 速读
- 有哪些松的古诗 4.描写松的古诗词_环球快播
- 中央气象台:继续发布强对流天气蓝色预警
- 全球播报:线上线下拥抱非遗 动静之间收获惊喜
- 今夜利空!半导体龙头遭大减持 剑桥科技二股东康宜桥拟清仓减持 关注
- 中国5月末外汇储备报3.1765万亿美元
- 快看:郑州城市防洪排涝监测预警中枢系统正式投用
- 天天热消息:2023年高考那些防弊黑科技——磁弹枪在考点现场出现
- 苹果手机输入法怎么改成九键的键盘_苹果手机输入法怎么改成九键的|微动态
- 关注:机构:韩国将垄断中大尺寸OLED发光材料需求至2027年
- 全球快报:江西:118家法院少年法庭全覆盖
- 沙特额外减产无法盖过需求忧虑!国际油价延续跌势
- 编纂与编撰的读音_编撰和编纂的读音
- 【天天快播报】乐享缤纷童年,唐昌镇幼儿园载歌载舞欢庆六一!
- 河南各地加强服务保障 确保收割机顺利跨区作业
- 【法网】王欣瑜/谢淑薇晋级女双四强
- 焦点速读:聚力打造鲁北地区生物医药产业创新高地
- 刚柔并济 软硬兼施_软硬兼施的意思
- 看热讯:盈康生命旗下医院引入山西省首台纳米刀(IRE)肿瘤消融系统
- 热消息:天源环保:公司生产制造的纳滤、反渗透集成装备可用于盐湖提锂过程中的工艺单元 公司尚未涉及该类业务
- 东岳硅材:目前,公司单体车间有计划内的部份设备停工检修及更换,单体车间其他在运行装置负荷正常,开工率处于正常合理水平-环球热讯
- 焦点短讯!兽不足到此人何取而自贻患耶_兽不足道,此人何取而自贻患耶翻译
- 三年复习资料全丢失,无法复习的高考生急得直掉泪,后来……
- 天天快报!东方电气国内单机容量最大冲击式水电机组完成国产化改造
- 焦点日报:廉江市气象台发布雷雨大风黄色预警【III级/较重】【2023-06-07】
- 乌克兰卡霍夫卡水电站大坝遭破坏,外交部:严重关切
- 广西南宁警方回应“女子被当街强奸”:传言与事实不符 每日消息
- 收盘丨A股三大指数走势分化,创业板指跌1.61%
- 速讯:广东省发文进一步完善和落实积极生育支持措施
广告
广告
- 世界滚动:中光防雷(300414):独立董事提名人声明(一)
- 全球头条:外媒:乌克兰富豪总资产较俄乌冲突前缩水逾200亿美元
- 全球焦点!回首·2022 | 长江黄河、黑土湿地……纵览2022美丽中国新画卷
- 当前视点!3299起我要冠军版!红米K60Pro还是你的菜吗?
- 今日视点:日本长期利率调整的市场效应
- 【全球热闻】跨越8800公里,爱尔兰面包蟹爬上中国人的餐桌
- 全球今头条!铜陵有色:公司没有独立的镍矿资源,公司的镍产品是冶炼的副产品之一,作为资源综合回收利用
- 资讯:倒计时5天!多家“重庆造”新能源汽车应声涨价
- 天天微动态丨2023年将成钠电产业化元年
- 天天最新:【和讯期货早报】大有期货-油脂-12月26日
- 【环球时快讯】赛升药业(300485.SZ)参股公司康乐卫士北交所上市获审核通过
- 世界通讯!捷信超贷贷款逾期1个月不还会上征信吗
- 前沿资讯!平安新一贷逾期12个月会不会上征信啊
- 【独家】三维通信: 三维通信公司章程(2022年12月)
- 今日讯!息县公安局扎实推进今冬明春禁种铲毒工作
- 环球精选!我阳了...
- 每日焦点!节能风电: 中节能风力发电股份有限公司章程(第十三次修订)
- 世界热消息:英诺特董秘回复:目前公司的联合检测产品需要在符合国家检验资质的医疗机构使用
- 环球微头条丨货币政策、流动性、房地产 央行这场重磅会议都说到了!
- 今头条!美吉姆最新公告:股东张源减持到期已减持300万股 拟再减持不超1.98%股份






