Linux PWM 开发指南

news2024/10/6 13:00:49

Linux PWM 开发指南

1 概述

1.1 编写目的

介绍 PWM 模块的详细设计方便相关人员进行 PWM 模块的代码设计开发。

1.2 使用范围

适用于 Linux-3.10,linux-4.4 和 Linux-4.9 内核,Linux-5.4 内核。

1.3 相关人员

PWM 驱动的开发人员/维护人员等

2 术语及概念

2.1 术语定义及缩略语

术语解释说明
Sunxi指 Allwinner 的一系列 SOC 硬件平台
频率PWM 的频率决定了所模拟电平的平滑度(逼真度),人耳感知的频率范围为 20Hz-16Khz,注意 PWM 的频率不要落在这个区间
占空比决定了一个周期内 PWM 信号高低的比例,进而决定了一个周期内的平均电压,也就是所模拟的电平的电压
极性决定了是高占空比的信号输出电平高,还是低占空比信号输出电平高。假设一个信号 的占空比为 100%,如果为正常极性,则输出电平最大,如果为翻转的极性,则输出 电平为 0
开关控制 PWM 信号是否输出
PWM对电机等硬件需要两路脉冲信号来控制其正常运转,一般两路极性相关,频率,占空比 参数相同的 PWM 构成一个 PWM 对
PWM死区控制时间大功率电机,变频器等由大功率管,IGBT 等元件组成 H 桥或 3 相桥,每个桥的上 半桥和下半桥是绝对不能导通的,在 PWM 信号驱动这些元件时,往往会由于没有延 迟而造成未关断某路半桥,这样会造成功率元件的损坏,在 PWM 中加入死区时间的 控制即是让上半桥关断后,自动插入一个事件,延迟后再打开下半桥

2.2 概念阐述

  1. 脉冲宽度调制(PWM)是一种对模拟信号电平进行数字编码的方法。通过高分辨率计数器的 使用,方波的占空比被调制用来对一个具体模拟信号的电平进行编码。
    1. PWM 模块属于 PWM 子系统,会调用 PWM 子系统的相关接口(详情可以查看 PWM 子系 统知识)

3 模块描述

3.1 模块功能

image-20221120190940471

图 3-1: 模块功能

不同平台上拥有不同个数的 PWM 通道,其中两个为一个 PWM 对(平台通道数不相同,PWM 对也就不相同,具体细节可以查看对应方案的 spec)。其中 PWM 具有以下特点:

• 支持脉冲,周期和互补对输出 • 支出捕捉输入

• 带可编程死区发生器,死区时间可控

• 0-24M/100M 输出频率范围。0%-100% 占空比可调,最小分辨率 1/65536

• 支持 PWM 输出和捕捉输入产生中断

3.2 模块位置

PWM 模块属于硬件驱动层,直接与硬件通信

3.3 模块配置

3.3.1 linux-4.9

在 linux-4.9 中, 在命令行中进入内核根目录,执行 make ARCH=arm(arm64) menuconfig 进入配置主界面,并按以下步骤操作:

  1. 首先,选择 Device Drivers 选项进入下一级配置,如下图所示:
  2. image-20221120191004435
图 3-2: Device Drivers
  1. 选择 Pulse-Width Modulation (PWM) Support 进入下一步配置,如下图所示:

image-20221120191036989

图3-3: Pulse-Width Modulation (PWM) Support

3.选择 SUNXI PWM SELECT 进入下一步配置,如下图所示:

image-20221120191124148

图3-4: SUNXI PWM SELECT

4.选择 Sunxi Enhance PWM support 配置

image-20221120191147248

图 3-5: Sunxi Enhance PWM support

在 4.9 内核选择该配置,选择的是对应目录中的 pwm-sunxi-new.c 文件。也可以有以下配置; 在第 3 步中直接选择 Allwinner PWM support 选项,选择的是对应目录中的 pwm-sun4i.c 文件

在第 4 步中选择 Sunxi PWM Support 选项,选择的是对应目录中的 pwm-sunxi.c 文件

3.3.2 linux-5.4

linux5.4 平台中, 在命令行中进入内核根目录,执行./build.sh menuconfig 进入配置主界面, 并按以下步骤操作:

  1. 首先,选择 Device Drivers 选项进入下一级配置,如下图所示:

    image-20221120191213928

    图 3-6: Device
  2. 选择 Pulse-Width Modulation (PWM) Support 进入下一步配置,如下图所示

    image-20221120191231809

    图 3-7: Pulse-Width Modulation (PWM) Suppor
  3. 选择 SUNXI PWM SELECT 进入下一步配置,如下图所示:

    image-20221120191247355

    图3-8: SUNXI PWM SELECT
  4. 选择 Sunxi PWM group support 配置

    image-20221120191310080

    图3-9: Sunxi PWM group support

3.4 设备树配置

3.4.1 linux-4.9

PWM 模块在设备树中的配置如下所示:

	pwm: pwm@0300a000 { 
		ompatible = "allwinner,sunxi-pwm"; 
		reg = <0x0 0x0300a000 0x0 0x3c>; //寄存器地址配置 
		pwm-number = <1>; //pwm的个数 
		pwm-base = <0x0>; //pwm的起始序号 
		pwms = <&pwm0>, <&pwm1>; 
	}; 
	s_pwm: s_pwm@0300a000 { 
		compatible = "allwinner,sunxi-s_pwm"; 
		reg = <0x0 0x0300a000 0x0 0x3c>; 
		pwm-number = <1>; 
		pwm-base = <0x10>; 
		pwms = <&spwm0>; 
	};

注意,如果在模块配置中选择了 Sunxi PWM support 选项 (具体参数可以查看相关源文件),则 需要配置以下设备树:

	pwm0: pwm0@01c23400 { 

		compatible = "allwinner,sunxi-pwm0"; 
		pinctrl-names = "active", "sleep"; 
		reg_base = <0x01c23400>; 
		reg_peci_offset = <0x00>; 
		reg_peci_shift = <0x00>; 
		reg_peci_width = <0x01>; 
		reg_pis_offset = <0x04>; 
		reg_pis_shift = <0x00>; 
		reg_pis_width = <0x01>; 
		reg_crie_offset = <0x10>; 
		reg_crie_shift = <0x00>; 
		reg_crie_width = <0x01>; 
		reg_cfie_offset = <0x10>; 
		reg_cfie_shift = <0x01>; 
		reg_cfie_width = <0x01>; 
		reg_cris_offset = <0x14>; 
		reg_cris_shift = <0x00>; 
		reg_cris_width = <0x01>; 
		reg_cfis_offset = <0x14>; 
		reg_cfis_shift = <0x01>; 
		reg_cfis_width = <0x01>; 
		reg_clk_src_offset = <0x20>; 
		reg_clk_src_shift = <0x07>;
		reg_clk_src_width = <0x02>;
        reg_bypass_offset = <0x20>;
        reg_bypass_shift = <0x05>;
        reg_bypass_width = <0x01>;
        reg_clk_gating_offset = <0x20>;
        reg_clk_gating_shift = <0x04>;
        reg_clk_gating_width = <0x01>;
        reg_clk_div_m_offset = <0x20>;
        reg_clk_div_m_shift = <0x00>;
        reg_clk_div_m_width = <0x04>;
        reg_pdzintv_offset = <0x30>;
        reg_pdzintv_shift = <0x08>;
        reg_pdzintv_width = <0x08>;
        reg_dz_en_offset = <0x30>;
        reg_dz_en_shift = <0x00>;
        reg_dz_en_width = <0x01>;
        reg_enable_offset = <0x40>;
        reg_enable_shift = <0x00>;
        reg_enable_width = <0x01>;
        reg_cap_en_offset = <0x44>;
        reg_cap_en_shift = <0x00>;
        reg_cap_en_width = <0x01>;
        reg_period_rdy_offset = <0x60>;
        reg_period_rdy_shift = <0x0b>;
        reg_period_rdy_width = <0x01>;
        reg_pul_start_offset = <0x60>;
        reg_pul_start_shift = <0x0a>;
        reg_pul_start_width = <0x01>;
        reg_mode_offset = <0x60>;
        reg_mode_shift = <0x09>;
        reg_mode_width = <0x01>;
        reg_act_sta_offset = <0x60>;
        reg_act_sta_shift = <0x08>;
        reg_act_sta_width = <0x01>;
        reg_prescal_offset = <0x60>;
        reg_prescal_shift = <0x00>;
        reg_prescal_width = <0x08>;
        reg_entire_offset = <0x64>;
        reg_entire_shift = <0x10>;
        reg_entire_width = <0x10>;
        reg_active_offset = <0x64>;
        reg_active_shift = <0x00>;
        reg_active_width = <0x10>;
};

PWM 模块在 sys_config.fex 的配置如下所示:

    [pwm0]
    pwm_used = 1
    pwm_positive = port:PB2<3><0><default><default>
    [pwm0_suspend]
    pwm_positive = port:PB2<7><0><default><default>

3.4.2 linux-5.4

PWM 模块在设备树中的配置如下所示:

    pwm: pwm@2000c00 {
        #pwm-cells = <0x3>;
        compatible = "allwinner,sunxi-pwm";
        reg = <0x0 0x02000c00 0x0 0x400>;
        clocks = <&ccu CLK_BUS_PWM>;
        resets = <&ccu RST_BUS_PWM>;
        pwm-number = <8>;
        pwm-base = <0x0>;
        sunxi-pwms = <&pwm0>, <&pwm1>, <&pwm2>, <&pwm3>, <&pwm4>,
        <&pwm5>, <&pwm6>, <&pwm7>;
    };
    pwm0: pwm0@2000c10 {
        compatible = "allwinner,sunxi-pwm0";
        pinctrl-names = "active", "sleep";
        reg = <0x0 0x02000c10 0x0 0x4>;
        reg_base = <0x02000c00>;
    };
    pwm1: pwm1@2000c11 {
        compatible = "allwinner,sunxi-pwm1";
        pinctrl-names = "active", "sleep";
        reg = <0x0 0x02000c11 0x0 0x4>;
        reg_base = <0x02000c00>;
    };
    pwm2: pwm2@2000c12 {
        compatible = "allwinner,sunxi-pwm2";
        pinctrl-names = "active", "sleep";
        reg = <0x0 0x02000c12 0x0 0x4>;
        reg_base = <0x02000c00>;
    };
    pwm3: pwm3@2000c13 {
        compatible = "allwinner,sunxi-pwm3";
        pinctrl-names = "active", "sleep";
        reg = <0x0 0x02000c13 0x0 0x4>;
        reg_base = <0x02000c00>;
    };
    pwm4: pwm4@2000c14 {
        compatible = "allwinner,sunxi-pwm4";
        pinctrl-names = "active", "sleep";
        reg = <0x0 0x02000c14 0x0 0x4>;
        reg_base = <0x02000c00>;
	};
    pwm5: pwm5@2000c15 {
        compatible = "allwinner,sunxi-pwm5";
        pinctrl-names = "active", "sleep";
        reg = <0x0 0x02000c15 0x0 0x4>;
        reg_base = <0x02000c00>;
    };
    pwm6: pwm6@2000c16 {
        compatible = "allwinner,sunxi-pwm6";
        pinctrl-names = "active", "sleep";
        reg = <0x0 0x02000c16 0x0 0x4>;
        reg_base = <0x02000c00>;
    };
    pwm7: pwm7@2000c17 {
        compatible = "allwinner,sunxi-pwm7";
        pinctrl-names = "active", "sleep";
        reg = <0x0 0x02000c17 0x0 0x4>;
        reg_base = <0x02000c00>;
    };

在板级目录下的配置:

    pwm3_pin_a: pwm3@0 {
        pins = "PB0";
        function = "pwm3";
        drive-strength = <10>;
        bias-pull-up;
    };
    pwm3_pin_b: pwm3@1 {
        pins = "PB0";
        function = "gpio_in";
        bias-disable;
    };
    pwm7_pin_a: pwm7@0 {
        pins = "PD22";
        function = "pwm7";
        drive-strength = <10>;
        bias-pull-up;
    };
    pwm7_pin_b: pwm7@1 {
        pins = "PD22";
        function = "gpio_out";
    };
    &pwm3 {
        pinctrl-names = "active", "sleep";
        pinctrl-0 = <&pwm3_pin_a>;
        pinctrl-1 = <&pwm3_pin_b>;
        status = "okay";
    };
    &pwm7 {
        pinctrl-names = "active", "sleep";
        pinctrl-0 = <&pwm7_pin_a>;
        pinctrl-1 = <&pwm7_pin_b>;
        status = "okay";
	};

具体通道配置按照需求进行配置.

3.5 源码结构

PWM 驱动的源代码位于内核的 drivers/pwm 目录下,具体的路径如下所示:

3.5.1 linux-4.9

drivers/pwm/
├── pwm-sunxi-new.c // Sunxi Enhance PWM support对应的PWM驱动
├── pwm-sunxi.c // Sunxi PWM support对应的PWM驱动
├── pwm-sun4i.c // Allwiner PWM support对应的PWM驱动
├── sysfs.c //PWM子系统的文件系统相关文件
├── core.c //PWM子系统的核心文件

3.5.2 linux-5.4

drivers/pwm/
├── pwm-sunxi-group.c // Sunxi GROUP PWM support对应的PWM驱动
├── sysfs.c //PWM子系统的文件系统相关文件
├── core.c //PWM子系统的核心文件

3.6 调试接口

可以直接在 linux 内核中调试 pwm 模块,具体如下: 进入/sys/class/pwm 目录,该目录是 linux 内核为 pwm 子系统提供的类目录,遍历该目录:

/sys/class/pwm # ls
pwmchip0

可以看到,上述 pwmchip0 就是我们注册的 pwm 控制器,进入该目录,然后遍历该目录:

/sys/class/pwm # cd pwmchip0/
/sys/devices/platform/soc/1c23400.pwm/pwm/pwmchip0 # ls
device export npwm subsystem uevent unexport

其中 npwm 文件储存了该 pwm 控制器的 pwm 个数,而 export 和 unexport 是导出和删除某 个 pwm 设备的文件,下面演示导出 pwm1。

/sys/devices/platform/soc/1c23400.pwm/pwm/pwmchip0 # cat npwm
2
/sys/devices/platform/soc/1c23400.pwm/pwm/pwmchip0 # echo 1 > export
/sys/devices/platform/soc/1c23400.pwm/pwm/pwmchip0 # ls
device export npwm pwm1 subsystem uevent unexport

可以看到目录中多出 pwm1 目录,进入该目录,遍历:

/sys/devices/platform/soc/1c23400.pwm/pwm/pwmchip0 # cd pwm1/
/sys/devices/platform/soc/1c23400.pwm/pwm/pwmchip0/pwm1 # ls
capture duty_cycle enable period polarity uevent

该目录中,enable 是使能 pwm,duty_cycle 是占空比,period 是周期,polarity 是极性,可 以配置相关的 pwm 并且使能:

/sys/devices/platform/soc/1c23400.pwm/pwm/pwmchip0/pwm1 # echo 1000000000 > period
/sys/devices/platform/soc/1c23400.pwm/pwm/pwmchip0/pwm1 # echo 500000000 > duty_cycle
/sys/devices/platform/soc/1c23400.pwm/pwm/pwmchip0/pwm1 # echo normal > polarity
/sys/devices/platform/soc/1c23400.pwm/pwm/pwmchip0/pwm1 # echo 1 > enable

如果相关引脚接上了示波器等,可以看到波形。最后返回上层目录,删除该 pwm 设备:

/sys/devices/platform/soc/1c23400.pwm/pwm/pwmchip0/pwm1 # cd ..
/sys/devices/platform/soc/1c23400.pwm/pwm/pwmchip0 # ls
device export npwm pwm1 subsystem uevent unexport
/sys/devices/platform/soc/1c23400.pwm/pwm/pwmchip0 # echo 1 > unexport
/sys/devices/platform/soc/1c23400.pwm/pwm/pwmchip0 # ls
device export npwm subsystem uevent unexport

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/366059.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

2022 赣育杯 CTF --- Crypto Lost_N wp

文章目录前言题目解题过程解题代码前言 这是去年江西省赛一道有点小坑的密码题&#xff0c;当时没做出来&#xff0c;今天回想起来重新做一下并且记录一下。 题目 Lost_N.py import gmpy2 from Crypto.Util.number import * # part1 flag bSangFor{} d getPrime(435) cou…

一篇文章弄清楚啥是数组和集合

数组和集合多语言都有&#xff0c;数组是集合的一种&#xff0c;是一种有序的集合&#xff0c;不面向对象&#xff0c;面向过程的也有。1.数组逻辑结构&#xff1a;线性的物理结构&#xff1a;顺序的存储结构申请内存&#xff1a;一次申请一大段连续的空间&#xff0c;一旦申请…

JAVA虚拟机JVM之内存模型

内存模型 java 内存模型 很多人将【java 内存结构】与【java 内存模型】傻傻分不清&#xff0c;【java 内存模型】是 Java Memory Model&#xff08;JMM&#xff09;的意思。 关于它的权威解释&#xff0c;请参考 https://download.oracle.com/otn-pub/jcp/memory_model-1.0…

【C++】string的9道OJ题

要么庸俗&#xff0c;要么孤独… 文章目录一、仅仅反转字母二、字符串中的第一个唯一字符&#xff08;计数排序的思想&#xff09;三、字符串相加&#xff08;做好加进位的工作即可&#xff09;四、把字符串转换成整数五、反转字符串中的单词 III六、字符串相乘&#xff08;高…

惠普庆祝在中国40年,强化中国发展战略

中国北京&#xff0c;2023年2月23日 ——今日&#xff0c;“品质信赖向未来” 惠普在中国40年系列活动启动仪式及惠普打印春季新品发布会在北京盛大举行。现场&#xff0c;惠普回顾了40年来与中国经济及产业共同发展的历程&#xff0c;并再次强调了惠普一以贯之的“在中国&…

3.GORM介绍和使用

目录 来源 什么是ORM ORM的优缺点 gorm介绍 安装 连接数据库 连接MySQL 连接PostgreSQL 连接Sqlite3 连接SQL Server GORM基本示例 Docker快速创建MySQL实例 创建数据库 GORM操作MySQL GORM Model定义 gorm.Model 模型定义示例 结构体标记&#xff08;tags&a…

力扣-文章浏览

大家好&#xff0c;我是空空star&#xff0c;本篇带大家了解一道简单的力扣sql练习题。 文章目录前言一、题目&#xff1a;1148. 文章浏览二、解题1.正确示范①提交SQL运行结果2.正确示范②提交SQL运行结果3.正确示范③提交SQL运行结果4.其他总结前言 一、题目&#xff1a;1148…

立项近7年,索尼产品经理分享PS VR2开发背后的故事

备受期待的索尼PS VR2终于正式发售&#xff0c;VR爱好者们终于有机会体验到《地平线&#xff1a;山之呼唤》等PS VR2独占的VR大作。近期&#xff0c;为了解PS VR2头显诞生背后的故事&#xff0c;外媒AV Watch采访到PS VR2的开发负责人Yasuo Takahashi&#xff0c;在本次采访中&…

尚医通 (二十二)微信支付

目录一、微信支付介绍1、微信扫码支付申请2、开发文档3、微信支付SDK二、微信支付开发2、微信支付前端整合三、订单支付后处理一、微信支付介绍 1、微信扫码支付申请 微信扫码支付是商户系统按微信支付协议生成支付二维码&#xff0c;用户再用微信“扫一扫”完成支付的模式。…

若依框架整合JSP

今天接到组长任务要求SpringbootJSP完成页面渲染&#xff0c;因为是用的若依框架&#xff0c;一上午零零散散的找了很多资料和视频&#xff0c;没有达到理想的结果&#xff0c;在下午中午弄出来了&#xff0c;于是整理出来供大家查看引用。&#xff08;单纯Springboot项目怎么建…

webRTC学习-基础知识

webRTC学习1、webRTC简介1.1什么是webRTC&#xff1f;1.2、作用2、webRTC通信原理2.1、媒体协商&#xff08;SDP&#xff09;2.2、网络协商&#xff08;candidate&#xff09;2.2.1、STUN2.2.2、TURN2.3、媒体协商网络协商数据的交换通道webRTC官网1、webRTC简介 1.1什么是web…

wiblogic托管服务器 节点管理 日志文件

创建和配置托管服务器 配置托管服务器 启动托管服务器 startManagedWebLogic.cmd server1 http://localhost:7001 startManagedWebLogic.cmd server3 http://localhost:7001 配置和使用节点管理器 创建 计算机 配置机器 启动节点管理器 startNodeManager.cmd 验…

百度财报解读:营收持平净利增,“文心一言”站C位

ChatGPT之火&#xff0c;点燃了投资者对AI赛道的热情。 而自百度宣布生成式AI产品“文心一言”&#xff08;ERNIE Bot&#xff09;将于3月推出以来&#xff0c;这家公司一直处于市场关注的焦点。 2月22日&#xff0c;百度发布了2022年第四季度及全年财报。财报显示&#xff0c…

力扣79.单词搜索

文章目录力扣79.单词搜索题目描述方法一&#xff1a;回溯深搜力扣79.单词搜索 题目描述 给定一个 m x n 二维字符网格 board 和一个字符串单词 word 。如果 word 存在于网格中&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 单词必须按照字母顺序&#x…

STM32f103 CubeMX封装 led程序

本文代码使用 HAL 库。 文章目录前言一、LED 原理图二、CubeMX创建工程三、LED 相关函数1. 输出电平函数&#xff1a;2. 延时函数&#xff1a;3. 翻转电平函数&#xff1a;四、详细代码实验现象 &#xff1a;总结代码 源码&#xff1a;前言 从这篇文章开始&#xff0c;我们讲解…

6 Namespace,分组和DataID三者之间的关系

命名空间&#xff08;Namespace&#xff09; 用于进行租户粒度的配置隔离。不同的命名空间下&#xff0c;可以存在相同的 Group 或 Data ID 的配置。Namespace 的常用场景之一是不同环境的配置的区分隔离&#xff0c;例如开发测试环境和生产环境的资源&#xff08;如配置、服务…

python 利用装饰器实现类似于flask路由

例子1&#xff1a; def f1():print(1111)def f2():print(2222)if __name__ __main__:print(33)打印结果&#xff1a; 33 在例子1中&#xff0c;f1() 与f2() 都没有被调用&#xff0c;只执行了print(33) f1与f2&#xff0c;是没有被调用的&#xff0c;但是如果f1 和 f2 上面…

R统计绘图 | 物种组成堆叠面积图(绝对/相对丰度,ggalluvial)

一、数据准备 数据使用的不同处理土壤样品的微生物组成数据&#xff0c;包含物种丰度&#xff0c;分类单元和样本分组数据。此数据为虚构&#xff0c;可用于练习&#xff0c;请不要作他用。 # 1.1 设置工作路径 #knitr::opts_knit$set(root.dir"D:\\EnvStat\\PCA")…

pyhon笔记——Anaconda安装

一、简介 Anaconda包括Conda、Python以及一大堆安装好的工具包&#xff0c;比如&#xff1a;numpy、pandas等 Miniconda包括Conda、Python conda是一个开源的包、环境管理器&#xff0c;可以用于在同一个机器上安装不同版本的软件包及其依赖&#xff0c;并能够在不同的环境之…

教你如何搭建培训机构-学员管理系统,demo可分享

1、简介1.1、案例简介本文将介绍&#xff0c;如何搭建培训机构-学员管理。1.2、应用场景学员信息报表展示所有正式学员信息&#xff0c;可对学员进行分配班级、转课、续课、扩科、退课、阶段测评等操作。2、设置方法2.1、表单搭建1&#xff09;新建表单【学员】&#xff0c;字段…