【STM32开发之寄存器版】(七)-PWM脉冲宽度调制

一、前言

PWM简介

PWM(脉宽调制)是一种通过调节信号的脉冲宽度来控制功率输出的技术。其基本原理是保持固定频率的信号,将其高电平和低电平的持续时间调整,达到控制平均功率的目的。应用方面,PWM广泛用于电机控制、LED调光、音频放大、以及电源管理等领域,因为它能有效提高能效并减少热量生成。

STM32F103ZET6的PWM

STM32F103ZET6的定时器,除了TIM6和TIM7,都可以用来产生PWM。高级定时器1和8甚至同时可以产生7路PWM输出,通用定时器也可以同时各自产生4路PWM输出。STM32定时器的脉冲宽度调制模式可以产生一个由TIMx_ARR寄存器确定频率、由TIMx_CCRx寄存器确定占空比的信号。如下图所示:

图中显示的是向上计数模式的PWM,且当 CNT<CCRx 时,输出 0,当 CNT>=CCRx 时输出 1。那么就可以得到如上的 PWM示意图:当 CNT 值小于 CCRx 的时候,IO 输出低电平(0),当 CNT 值大于等于 CCRx 的时候,IO 输出高电平(1),当 CNT 达到 ARR 值的时候,重新归零,然后重新向上计数,依次循环。改变 CCRx 的值,就可以改变 PWM 输出的占空比,改变 ARR 的值,就可以改变 PWM 输出的频率,这就是 PWM 输出的原理。

本次DEMO目标

本次DEMO我们将使用TIM3的CH2,并将CH2重映射到PB5,产生PWM来控制DS0的亮度。

二、时钟树分析

对于时钟树的分析与【STM32开发之寄存器版】(六)-通用定时器中断 相同,供给TIM3的时钟TIM3CLK=72MHz,具体的时钟树配置如下图所示:

三、寄存器介绍

对于PWM的设置主要涉及以下几个寄存器:

寄存器作用
TIMx_CCMR1/2捕获/比较模式寄存器1/2
TIMx_CCER捕获/比较使能寄存器
TIMx_CCR1-4捕获/比较寄存器1-4
AFIO_MAPR复用重映射和调试I/O配置寄存器

下面将对这四个寄存器进行一一介绍:

3.1 TIMx_CCMR捕获/比较模式寄存器

《STM32中文参考手册》对TIMx_CCMR寄存器的描述如下:

TIMx_CCMR寄存器总共有 2 个,TIMx _CCMR1和 TIMx _CCMR2。TIMx_CCMR1 控制 CH1 和 2,而 TIMx_CCMR2 控制 CH3 和 4。本文使用PB5,即TIM3_CH2,故仅需关注TIMx _CCMR1即可

TIMx_CCMR1中的某些位,在输入和输出模式下具备不同的功能,因此将这个寄存器分为2层,上面这层表示输出,下面这层表示输入,本次DEMO仅需关注输出PWM。这里我们需要说明的是模式设置位 OCxM,此部分由 3 位组成。总共可以配置成 7 种模式,我们使用的是 PWM 模式,所以这 3 位必须设置为 110/111。这两种 PWM 模式的区别就是输出电平的极性相反。另外 CCxS 用于设置通道的方向(输入/输出)默认设置为 0,就是设置通道作为输出使用。

3.2 TIMx_CCER捕获/比较使能寄存器

《STM32中文参考手册》对TIMx_CCER寄存器的描述如下:

对于这个寄存器,我们只用到了CC2E位,该位是输入/捕获 2 输出使能位,要想PWM 从 IO 口输出,这个位必须设置为 1

3.3 TIMx_CCR捕获/比较寄存器

《STM32中文参考手册》对TIMx_CCR寄存器的描述如下:

对于TIM3,CCR寄存器共有4个,分别对应CH1-CH4,本文使用的PB5对应CH2,故我们仅需关注TIM3_CCR2寄存器。在输出模式下,该寄存器的值与 CNT 的值比较,根据比较结果产生相应动作。利用这点,我们通过修改这个寄存器的值,就可以控制 PWM 的输出脉宽了。本章,我们使用的是 TIM3 的通道 2,所以我们需要修改 TIM3_CCR2 以实现脉宽控制 DS0 的亮度。

3.4 AFIO_MAPR复用重映射和调试I/O配置寄存器

《STM32中文参考手册》对AFIO_MAPR寄存器的描述如下:

由于本文要使用TIM3的CH2输出PWM来控制DS0的亮度,但是TIM3_CH2默认接在PA7上面,而DS0接在PB5上面,因此需要通过重映射功能,将TIM3_CH2映射到PB5上。描述重映射的寄存器是AFIO_MAPR,我们只需要关注其TIM3_REMAP[1:0]位。在本DEMO中,我们要将TIM3_REMAP[1:0]设置为10,部分映像可以将CH2通道映射到PB5引脚上。

四、程序设计

本DEMO的程序主要涉及定时器3的PWM功能初始化和轮询主函数。

4.1 定时器3的PWM功能初始化

该部分代码位于HARDWARE/timer.c/TIM3_PWM_Init(),主要功能是完成定时器3时钟使能、PB5复用功能配置、PWM模式配置和使能。具体代码如下所示:

//TIM3 PWM部分初始化 
//PWM输出初始化
//arr:自动重装值
//psc:时钟预分频数
void TIM3_PWM_Init(u16 arr,u16 psc)
{		 					 //此部分需手动修改IO口设置RCC->APB1ENR|=1<<1; 	//TIM3时钟使能    RCC->APB2ENR|=1<<3;    	//使能PORTB时钟	GPIOB->CRL&=0XFF0FFFFF;	//PB5输出GPIOB->CRL|=0X00B00000;	//复用功能输出 	  	 RCC->APB2ENR|=1<<0;     //开启辅助时钟	   AFIO->MAPR&=0XFFFFF3FF; //清除MAPR的[11:10]AFIO->MAPR|=1<<11;      //部分重映像,TIM3_CH2->PB5TIM3->ARR=arr;			//设定计数器自动重装值 TIM3->PSC=psc;			//预分频器不分频TIM3->CCMR1|=7<<12;  	//CH2 PWM2模式		 TIM3->CCMR1|=1<<11; 	//CH2预装载使能	   TIM3->CCER|=1<<4;   	//OC2 输出使能	   TIM3->CR1=0x0080;   	//ARPE使能 TIM3->CR1|=0x01;    	//使能定时器3 											  
}  	 

4.2 轮询主函数 

该部分代码位于USER/test.c,具体作用是不断改变TIM3的CCR2装载值,从而改变PWM占空比,实现DS0的亮度调整。具体代码如下所示:

#include "sys.h"
#include "delay.h"
#include "usart.h" 
#include "led.h" 
#include "timer.h" int main(void)
{					   u16 led0pwmval=0;    u8 dir=1;	Stm32_Clock_Init(9);	//系统时钟设置uart_init(72,115200);	//串口初始化为115200delay_init(72);	   	 	//延时初始化 LED_Init();		  		//初始化与LED连接的硬件接口TIM3_PWM_Init(899,0);	//不分频。PWM频率=72000/(899+1)=80Khzwhile(1){delay_ms(10);	 if(dir)led0pwmval++;else led0pwmval--;	 if(led0pwmval>300)dir=0;if(led0pwmval==0)dir=1;	   					 LED0_PWM_VAL=led0pwmval;	   }
}

五、上机实验

将代码烧录到STM32F103ZET6,可以观察到DS0的呼吸灯效果。如下所示:

至此完成PWM呼吸灯实验! 

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

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

相关文章

C语言基础题(大合集1)

1. Hello World! 写一个程序 &#xff0c; 在控制台上输出 &#xff1a; Hello World! #include <stdio.h> int main() {printf("Hello World!\n");return 0; }main 函数是程序的入口 &#xff0c; 一个工程有且仅有一个 main函数 代码是从 main 函数的第一行开…

数学概念算法-打印100以内的素/质数

素数&#xff1a;只能被1和自己整除的数 暴力破解 埃氏筛选 找到第一个数字&#xff0c;如果它是素数&#xff0c;则把它的倍数全部划掉 比如数字2是素数&#xff0c;那么 4,6,8,10,12。这些数字肯定不是素数&#xff0c;所以不用再考虑&#xff0c;直接划掉即可 第二步&#…

SQL注入靶场sqli-labs less-4

sqli-labs靶场第三关less-4 1、确定注入点 http://192.168.128.3/sq/Less-4/?id1 http://192.168.128.3/sq/Less-4/?id2 有不同回显&#xff0c;判断可能存在注入&#xff0c; 2、判断注入类型 输入 http://192.168.128.3/sq/less-4/?id1 and 11 http://192.168.128.3/sq/l…

C++(异常)

目录 C语言传统的处理错误的方式 传统的错误处理机制 C异常概念 异常的使用 异常的抛出和捕获 异常的抛出和匹配原则 在函数调用链中异常栈展开匹配原则 异常的重新抛出 异常安全 异常规范 自定义异常体系 C标准库的异常体系 异常的优缺点 C异常的优点 C异常的缺…

DB_GPT excel研究

DB_GPT excel研究 摘要视频简介源码分析excel文档上传预处理对话 摘要 DB_GPT集成了很多对话方式&#xff0c;其中呢就有关于excel对话的模块&#xff0c;我搜集各大web好像都没有关于这个模块的研究&#xff0c;于是乎就自行研究了对于excel对话的的功能 如果是想看与数据库…

Golang | Leetcode Golang题解之第462题最小操作次数使数组元素相等II

题目&#xff1a; 题解&#xff1a; func partition(a []int, l, r int) int {x : a[r]i : l - 1for j : l; j < r; j {if a[j] < x {ia[i], a[j] a[j], a[i]}}a[i1], a[r] a[r], a[i1]return i 1 }func randomPartition(a []int, l, r int) int {i : rand.Intn(r-l1…

毕设 大数据电影数据分析与可视化系统(源码+论文)

文章目录 0 前言1 项目运行效果2 设计概要3 最后 0 前言 &#x1f525;这两年开始毕业设计和毕业答辩的要求和难度不断提升&#xff0c;传统的毕设题目缺少创新和亮点&#xff0c;往往达不到毕业答辩的要求&#xff0c;这两年不断有学弟学妹告诉学长自己做的项目系统达不到老师…

51 单片机最小系统

一、51 单片机最小系统概述 51 单片机最小系统是一个基于 51 单片机的最小化电路系统&#xff0c;它包含了使单片机能够正常工作的最少元件。这个系统主要用于学习和实验目的&#xff0c;帮助学习者在没有复杂电路的情况下快速了解 51 单片机的工作原理&#xff0c;其重要性不…

动态规划算法专题(四):子串、子数组系列

目录 1、最大子数组和 1.1 算法原理 1.2 算法代码 2、环形子数组的最大和 2.1 算法原理 2.2 算法代码 3、乘积最大子数组 3.1 算法原理 3.2 算法代码 4、乘积为正数的最长子数组长度 4.1 算法原理 4.2 算法代码 5、等差数列划分 5.1 算法原理 5.2 算法代码 6、…

java语言基础案例-cnblog

java语言基础案例 象棋口诀 输出 package nb;public class XiangQi {public static void main(String[] args) {char a 马;char b 象;char c 卒;System.out.println(a"走日"b"走田""小"c"一去不复还");} }输出汇款单 package nb…

30 树 · 二叉树

目录 一、树 &#xff08;一&#xff09;树的概念与结构 &#xff08;二&#xff09;树相关术语 &#xff08;三&#xff09;树的表示 &#xff08;四&#xff09;树形结构的实际应用场景 二、二叉树 &#xff08;一&#xff09;概念与结构 &#xff08;二&#xff09;…

【LeetCode】每日一题 2024_10_7 最低加油次数(堆、贪心)

前言 每天和你一起刷 LeetCode 每日一题~ 大家国庆节快乐呀~ LeetCode 启动&#xff01; 国庆最后一天&#xff0c;力扣还在加油站&#xff0c;怕不是国庆回家路上堵车了 题目&#xff1a;最低加油次数 代码与解题思路 func minRefuelStops(target int, startFuel int, st…

刷题 双指针 滑动窗口

面试经典 150 题 - 双指针 ⭐️125. 验证回文串 学会内部字母处理函数的使用 class Solution { public:bool isPalindrome(string s) {int left 0, right s.size() - 1;while (left < right) {// 处理左边字符if (!isalnum(s[left])) {left;continue;}// 处理右边字符if…

C(十五)函数综合(一)--- 开公司吗?

在这篇文章中&#xff0c;杰哥将带大家 “开公司”。 主干内容部分&#xff08;你将收获&#xff09;&#xff1a;&#x1f449; 为什么要有函数&#xff1f;函数有哪些&#xff1f;怎么自定义函数以及获得函数的使用权&#xff1f;怎么对函数进行传参&#xff1f;函数中变量的…

C语言 | Leetcode C语言题解之第462题最小操作次数使数组元素相等II

题目&#xff1a; 题解&#xff1a; static inline void swap(int *a, int *b) {int c *a;*a *b;*b c; }static inline int partition(int *nums, int left, int right) {int x nums[right], i left - 1;for (int j left; j < right; j) {if (nums[j] < x) {swap(…

Linux 外设驱动 应用 1 IO口输出

从这里开始外设驱动介绍&#xff0c;这里使用的IMX8的芯片作为驱动介绍 开发流程&#xff1a; 修改设备树&#xff0c;配置 GPIO1_IO07 为 GPIO 输出。使用 sysfs 接口或编写驱动程序控制 GPIO 引脚。编译并测试。 这里假设设备树&#xff0c;已经配置好了。不在论述这个问题…

【英语】5. 考研英语语法体系

文章目录 前言句字的成分一、常规句型简单句&#xff08;5 种&#xff09;1. 定义&#xff1a;句子中只包含 *一套主谓结构* 的句子。&#xff08;一个句子只能有一个谓语动词&#xff09;2. 分类 并列句&#xff08;由关联词组成&#xff09;&#xff08;3 种&#xff09;基本…

二分图算法总结 C++实现

总体概念 染色法 基本思路步骤 将所有的边及其相接的边用邻接表存储起来&#xff1b;遍历所有的点&#xff0c;找到未上色的点&#xff1b;用BFS将该点及其相接的点迭代上色&#xff1b;在上述染色步骤中&#xff0c;如果相邻点的颜色相同则无法形成二分图&#xff1b; 题目…

继电保护之电压重动、电压并列和电压切换

实践&#xff1a;以某开关室10kV母联隔离柜为例&#xff1a; ZYQ-824为PT并列装置&#xff0c;装置内包含一系列继电器&#xff0c;用于PT重动及并列。按照装置编号原则&#xff0c;交流电压切换箱一般命名为7n。 ​下图为装置内继电器线圈部分接线&#xff1a; 下图为装置内…

销售秘籍:故事+观点+结论

在销售的浩瀚宇宙中&#xff0c;隐藏着一个不朽的秘诀——利用人类共有的“错失恐惧”&#xff0c;激发客户内心的渴望与行动。正如村上春树所言&#xff0c;每个故事都深深植根于灵魂&#xff0c;而大仲马则揭示&#xff0c;灵魂之眼所见&#xff0c;比肉眼更为长久铭记。 错…