itop-3568 开发板系统编程学习笔记(21)PWM 应用编程

news2025/9/8 1:38:58

【北京迅为】嵌入式学习之Linux系统编程篇 https://www.bilibili.com/video/BV1zV411e7Cy/ 个人学习笔记

文章目录

  • 在设备树打开 PWM
  • sysfs 方式控制 PWM
  • PWM 应用编程

在设备树打开 PWM

RK3568 有 16 个 PWM 控制器,本文件将以 PWM0 为例进行实验,为什么一定要用 PWM0 呢?之前 LED 和 GPIO 我们都是用 GPIO0_B7 作为实验对象,其实这个 IO 还有 PWM 功能:

在这里插入图片描述

iTOP-3568 开发板的 PWM0 默认是关闭的,需要修改设备树,将其打开(将 pwm0 节点的 status 属性改为 “okay”),

在 pwm0 节点中,通过 pinctrl 指定其 pin 脚为 pwm0m0_pins,pwm0m0_pins 定义在 rk3568-pinctrl.dtsi 中,我们可以看到 pwm0m0_pins 对应的 pin 就是 GPIO0_B7,

在这里插入图片描述

最后,还需要屏蔽设备树中其他用到 GPIO0_B7 的配置,比如 leds(前面 GPIO 编程时已经进行了屏蔽)

在这里插入图片描述

sysfs 方式控制 PWM

进入 /sys/class/pwm 目录,可以看到多个 pwmchipx,x 为编号数字,我的开发板上有 4个 pwmchipx,说明设备树中打开了 4 个 PWM,

在这里插入图片描述

系统会将已经打开的 PWM 按照 PWM 编号顺序放置在 /sys/class/pwm 目录,所以 PWM0 对应的是 pwmchip0(但 pwmchip1 不一定对应 PWM1,因为 PWM1 可能没有被开启),进入 pwmchip0,

在这里插入图片描述

该目录下有七个文件,比较重要的是 export,npwm,和 unexport 三个文件,

npwm 是一个只读文件,可以通过该文件读到 PWM 控制器下有多少路 PWM 输出,当前我的系统读出来的值是 1

在这里插入图片描述

export 在 GPIO 编程中有学到这个文件,用于导出一个新的可操作文件,比如 echo 0 > export 会在 pwmchip0 目录下新建一个 pwm0 文件夹(由于上面已经知晓 npwm 为 1,所以只能导出 pwm0,不存在 pwm1…)

在这里插入图片描述

unexport 是 export 的反向操作,用于删除已经导出的 pwm 设备,它们都是只写文件,

进入 pwm0 目录,又能看到七个文件,比较重要的是 polarity,period,duty_cycle 和 enable,

在这里插入图片描述

duty_cycle 用于配置 PWM 占空比,单位为 ns,
enable 为 1 时使能 PWM 输出,为 0 时关闭 PWM 输出,
period 用于配置 PWM 周期,单位为 ns,
polarity 用于配置 PWM 极性,“normal” (普通输出),“inversed” (反转输出)。

Tip:必须先设置 period 周期后才可以设置其他属性,

PWM 应用编程

实验代码:

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>

#define PWM_PATH "/sys/class/pwm/pwmchip0/pwm0"

int main(int argc, char** argv)
{
	int fd1, fd2, fd3;
	int ret = 0;
	char tmp_path[60] = {0};
	
	// 参数个数判断
	if(argc != 4)
	{
		printf("The right format: ./app period duty enable.\n");		
		return 0;
	}
	
	// PWM_PATH 不存在
	if(access(PWM_PATH, F_OK)) 
	{
		int fd, ret;
		fd = open("/sys/class/pwm/pwmchip0/export", O_WRONLY);
		if(fd < 0)
		{
			printf("/sys/class/pwm/pwmchip0/export open failed.\n");
			return 0;
		}
		printf("/sys/class/pwm/pwmchip0/export open successfully.\n");
		
		ret = write(fd, "0", 1);
		if(ret < 0)
		{
			printf("/sys/class/pwm/pwmchip0/export write failed.\n");
			return 0;
		}
		close(fd);
	}
	
	// 打开 /sys/class/pwm/pwmchip0/pwm0/period
	sprintf(tmp_path, "%s/period", PWM_PATH);
	fd1 = open(tmp_path, O_WRONLY);
	if(fd1 < 0)
	{
		printf("%s open failed.\n", tmp_path);
		return 0;
	}
	printf("%s open successfully.\n", tmp_path);
	
	
	// 打开 /sys/class/pwm/pwmchip0/pwm0/duty_cycle
	sprintf(tmp_path, "%s/duty_cycle", PWM_PATH);
	fd2 = open(tmp_path, O_WRONLY);
	if(fd2 < 0)
	{
		printf("%s open failed.\n", tmp_path);
		return 0;
	}
	printf("%s open successfully.\n", tmp_path);
	
	// 打开 /sys/class/pwm/pwmchip0/pwm0/enable
	sprintf(tmp_path, "%s/enable", PWM_PATH);
	fd3 = open(tmp_path, O_WRONLY);
	if(fd3 < 0)
	{
		printf("%s open failed.\n", tmp_path);
		return 0;
	}
	printf("%s open successfully.\n", tmp_path);
	
	
	// 设置 period
	ret = write(fd1, argv[1], strlen(argv[1]));
	if(ret < 0)
	{
		printf("%s/period write failed.\n", PWM_PATH);
		return 0;
	}
	printf("%s/period write successfully.\n", PWM_PATH);
	
	// 设置 duty_cycle
	ret = write(fd2, argv[2], strlen(argv[2]));
	if(ret < 0)
	{
		printf("%s/duty_cycle write failed.\n", PWM_PATH);
		return 0;
	}
	printf("%s/duty_cycle write successfully.\n", PWM_PATH);
	
	// 设置 enable
	ret = write(fd3, argv[3], strlen(argv[3]));
	if(ret < 0)
	{
		printf("%s/enable write failed.\n", PWM_PATH);
		return 0;
	}
	printf("%s/enable write successfully.\n", PWM_PATH);

	// 关闭设备文件
	close(fd1);
	close(fd2);
	close(fd3);
	return 0;
}

实验结果:

在这里插入图片描述
上面三种情况下 LED 现象:(/sys/class/pwm/pwmchip0/pwm0/polarity 为 “normal” 的前提下测试)
第一种情况:LED 微亮,第二种情况:LED 高亮,第三种情况:LED 灭。


发现一件奇怪的事,polarity 默认为 inversed(反向),这种情况下,先控制 PWM 让 LED 点亮,然后将 enable 置 0 或 置 1,LED 都不会灭,且后续再操作 pwm 会出现失灵现象。

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

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

相关文章

如何在PowerShell中查找、添加、修改和删除环境变量:解决手动设置环境变量后报命令失效的问题

简介 PowerShell是Windows平台上的一种命令行工具&#xff0c;它可以方便地查找、添加、修改和删除环境变量。在本文中&#xff0c;LZ将介绍如何在PowerShell中进行这些操作。 查找环境变量 在PowerShell中查找环境变量非常简单。只需要使用Get-ChildItem命令&#xff0c;以…

LED驱动 中断

1、用字符设备驱动框架和平台设备驱动框架实现LED驱动 1.1 用字符设备驱动框架-----》led2 控制led2闪烁 1.应用层&#xff1a; 1 open&#xff08;“/dev/haha0”&#xff09; 2 while&#xff08;1&#xff09; ioctl&#xff08;fd&#xff0c;LED_ON&#xff09;&#xff…

java的社区养老服务系统 ssm空巢老人

创新点&#xff1a; 1、根据时间、类型统计用户下单记录&#xff0c;形成可视化图形&#xff08;饼状图&#xff09; 2、根据用户爱好推荐项目 包含模块&#xff1a;关于我们、联系我们、外链信息、资讯类型、服务资讯、服务类型、服务项目、案例类型、服务案例、讨论类型、讨论…

引入Tuning function design的自适应反步控制方法 上篇

引入Tuning function design的自适应反步控制方法 上篇 目录 引入Tuning function design的自适应反步控制方法 上篇尝试用推迟参数设计解决高阶不匹配系统的控制器设计问题问题描述控制器设计小结上一篇文章写了如何通过推迟参数设计的方法来解决不匹配条件下的系统反步控制设…

【原型设计模式详解】C/Java/JS/Go/Python/TS不同语言实现

简介 原型模式&#xff08;Prototype Pattern&#xff09;是一种创建型设计模式&#xff0c;使你能够复制已有对象&#xff0c;而无需使代码依赖它们所属的类&#xff0c;同时又能保证性能。 这种模式是实现了一个原型接口&#xff0c;该接口用于创建当前对象的克隆。当直接创…

IT项目管理之软件测试

1. 定义 软件测试是使用人工或者自动的手段来运行或者测定某个软件系统的过程&#xff0c;其目的在于检验它是否满足规定的需求或弄清预期结果与实际结果之间的差别。 在软件投入使用前&#xff0c;要经过一系列的严格测试&#xff0c;才能保证交付质量。 2. QC & QA &a…

会声会影导入视频是黑色的 会声会影导入视频只有声音

会声会影是一款功能很成熟的视频编辑软件&#xff0c;其友好的界面设计能照顾到初学者的需求&#xff0c;同时配置的强大功能可满足进阶者的需要。不过由于或硬件或软件的原因&#xff0c;可能会出现会声会影导入视频是黑色的&#xff0c;会声会影导入视频只有声音的问题。本文…

Docker的实际应用

一、 数据持久化 我们什么情况下要做数据持久化呢&#xff1f; 一定是在做容器之前先预判好哪些文件是要永久存储的&#xff0c; 而不会跟着它容器的一个生命周期而消失。 比如说配置文件、 日志文件、 缓存文件或者应用数据等等。 数据初始化有三种类型。 第一种 volumes&…

浏览器缓存策略:强缓存和协商缓存

浏览器缓存&#xff1a;其实就是在本地使用的计算机中开辟一个内存区&#xff0c;同时也开辟一个硬盘区&#xff0c;作为数据传输的缓冲区&#xff0c;然后利用这个缓冲区来暂时保护用户以前访问的信息通常浏览器的缓存策略分为两种&#xff1a;强缓存和协商缓存&#xff0c;强…

Vmware 搭建 Bitnami GitLab CE

Vmware 搭建 Bitnami GitLab CE 下载 Bitnami GitLab CE导入到 Vmwaressh 登录到虚拟机获取 root 用户密码访问 GitLab CE关机命令扩展磁盘配置 tls 证书安装 GitLab Runner注册 GitLab Runner其他&#xff0c;配置 docker 信任自签名证书 下载 Bitnami GitLab CE 下载地址&am…

Photoshop如何使用基础功能?

文章目录 0.引言1.菜单栏2.工具箱 0.引言 笔者从开始科研时就接触过Photoshop&#xff08;PS&#xff09;&#xff0c;这么多年一直用着感觉有些陌生&#xff0c;在每次使用PS时总感觉有些抵触&#xff0c;这状态说明还未入门。为了入门PS&#xff0c;笔者从头熟悉PS的菜单和工…

一文弄懂Jupyter的配置与使用(呕心沥血版)

Jupyter 是一个基于 Web 的交互式计算平台&#xff0c;使用户能够创建和共享文档&#xff0c;这些文档包含实时代码、方程式、可视化图表和解释文字。Jupyter 在数据分析领域被广泛应用&#xff0c;它提供了一个直观、交互式的操作界面&#xff0c;使得用户能够更容易地探索数据…

MybatisPlus入门和分页和条件查询里面的条件和null值的处理方式和查询投影和查询条件设置

MybatisPlus 简化了mybatis之前的在springboot整合MyBatis时需要自己写sql语句在接口中&#xff0c;现在只需要让接口继承BaseMapper<实体类>&#xff0c;然后在测试类中接口.增删改查方法&#xff08;&#xff09;即可 不用像springboot整合mybatis一样勾选spring web…

【Python】【进阶篇】9、Django路由系统精讲

目录 Django路由系统精讲1. Django 路由系统应用1&#xff09;配置第一个URL实现页面访问2&#xff09;正则与正则分组使用3&#xff09;正则捕获组使用 2. path()与re_path() Django路由系统精讲 在《URL是什么》一节中&#xff0c;我们对 URL 有了基本的认识&#xff0c;在本…

易基因:禾本科植物群落的病毒组丰度/组成与人为管理/植物多样性变化的相关性 | 宏病毒组

大家好&#xff0c;这里是专注表观组学十余年&#xff0c;领跑多组学科研服务的易基因。 现代农业通过简化生态系统、引入新宿主物种和减少作物遗传多样性来影响植物病毒的出现。因此&#xff0c;更好理解农业生态中种植和未种植群落中的病毒分布&#xff0c;以及它们之间的病…

解析Mybaits核心配置文件属性

目录 1.environment 2.transactionManager 3.dataSource 4.peoperties 5.mapper 先来看看mybatis核心配置文件代码 <?xml version"1.0" encoding"UTF-8"?> <!DOCTYPE configurationPUBLIC "-//mybatis.org//DTD Config 3.0//EN&qu…

02- stable diffusion的基本使用

stable diffusion的基本使用 对应视频 https://www.bilibili.com/video/BV1Q14y1f7XJ/https://www.bilibili.com/video/BV1av4y1E74C/ 一、下载 1.1 官方github&#xff1a; 官方github&#xff1a; GitHub - Stability-AI/stablediffusion: High-Resolution Image Synth…

Linux进程命令

目录 前言 基本命令 PS命令 语法 字段解释 栗子 top命令 语法 参数解释 栗子 kill命令 语法 参数解释 栗子 前言 进程是正在执行的一个程序或命令&#xff0c;每一个进程都是一个运行的实体&#xff0c;都有自己的地 址空间&#xff0c;并占用一定的系统资源。 基本命…

滑动奇异频谱分析:数据驱动的非平稳信号分解工具(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

线程池四种拒绝机制 实现 及执行日志

目录 目录 目录 创建线程池 测试代码 运行线程 全量代码 日志 AbortPolicy 报出异常模式 DiscardPolicy 放弃机制啥也不处理 DiscardOldestPolicy 放弃机制&#xff0c;放弃列队最早进入的 CallerRunsPolicy 交给主线程执行 创建线程池 public static ExecutorServi…