STM32快速入门(定时器之输出PWM波形)

STM32快速入门(定时器之输出PWM波形)

前言

本节主要讲解STM32利用通用定时器,利用CCR和CNT寄存器,输出指定占空比和频率的PWM波形。其功能的应用有:实现LED呼吸灯的效果、控制步进电机、控制直流电机转速等。

导航

图98 通用定时器框图:

TimerPWM

图片引自STM32 F1XX系列的中文参考手册。在通用定时器章节的定时器架构图中,本章讲解的定时器输出功能位于右下角的红色矩形中。

定时器实现PWM输出的实现细节

参考中文手册,实现细节图125如下:

PWM

它内部实现是:输出模式控制器通过比较TIMx_CCR1(比较捕获寄存器)和TIMx_CNT(计数器)的值,由输出模式控制器来确定输出高(有效)电平,还是低(无效)电平,用户可以通过改变TIMx_CCR1寄存器的值来改变PWM的占空比。这通常会将输出模式控制器配置成PWM模式1或PWM模式2,两种模式就是互为取反的关系,同时这两种模式也是输出模式控制器最常用的配置。

对于原理图125左侧的输出模式控制器:

该部分作用是:控制输出模式控制器的输出行为。这里将输出模式控制器的输出标记为OC1REF。

输出模式控制器有7种配置,这些配置是通过操作 TIMx_CCMR1.OC1M[6:4] 实现,7种配置在中文手册中的描述如下,手册中的描述可能太晦涩,配合江科的表格会更友好:

TIMx_CCMR1__OC1M2

TIMx_CCMR1__OC1M1

对于原理图125右侧:

右侧包括一个极性选择器和输出使能电路。

该部分作用是:1、对输出电压的极性进行控制。2、控制输出电路的使能。

我们可以通过配置 TIMx_CCER.CC1P[1] 控制选择器是直接选择OC1REF波形(输出模式控制器的输出)还是选择OC1REF的反相波形。也就是说,输出模式控制器配置成PWM1/WPM2可以实现对OC1REF的反相,配置 TIMx_CCER.CC1P[1] 间接配置选择器也能实现对OC1REF的反相。通过配置 TIMx_CCER.CC1E[0] 可以实现对输出电路的使能。

由定时器输出PWM的原理可以得出调节占空比的公式,PWM频率就是定时器溢出的周期、占空比就是TIMx_CCR1的值,其计算公式如下:

PWMFrequency

关于定时器的PWM模块还需提一句的是,有三个寄存器存在缓冲寄存器/影子寄存器的概念的,这三个寄存器分别是:ARR、PSC、CCRx。影子寄存器的存在延续旧值的生命周期,这样让旧值继续该时期的使命。如果用户提供的新值立马生效,系统就会出于一种未定义的状态。有了缓冲寄存器/影子寄存器的概念,在一个更新周期中真正起作用的是影子寄存器,而用户想要修改预分频控制寄存器,会先将值写到缓冲器中,待这个更新周期过去,才会将缓冲器的值给到影子寄存器

下面中文手册的的两张时序图可以很好的说明了:

Shadow

缓冲寄存器 ----> 预分频控制寄存器

影子寄存器 ----> 预分频缓冲器

还需注意的是:TIMx_CR1.ARPE[7]TIMx_CCMR1.OC1PE[3]寄存器可以让用户选择ARR、CCRx是否启用影子寄存器的功能,而PSC寄存器默认必须使用影子寄存器的功能,但是用户可以通过TIM_PrescalerConfig函数动态配置计数器的预分频系数,它的第三个参数可以选择TIM_PSCReloadMode_Immediate,这会让定时器立即产生一个更新事件,间接实现了立即更新的效果。

定时器实现PWM输出的步骤

综上,可以总结出配置定时器输出部分的套路:

  1. 我们需要把 TIMx_CCMR1.CC1S[1:0] 配置为00,这样CC1通道就被配置为输出

  2. 通过配置 TIMx_CCMR1.OC1M[6:4] ,这里将输出模式控制寄存器配置成PWM1模式。即110。

  3. 配置原理图右部分是否开启反相 TIMx_CCER.CC1P[1] ,这里配置为0不反相。

  4. 最后使能 TIMx_CCER.CC1E[0] 位,来使能原理图右边的输出使能电路。

一般的话,我门还会配置 TIMx_CCMR1.OC1PE[3]TIMx_CR1.ARPE[7],分别启用TIMx_CCR1、TIMx_ARR寄存器的影子功能。

定时器实现PWM输出的库函数实现

因为我的开发板LED0被焊在了PB5所以,所以需要将定时器的PWM波形输出到PB5上。经过查表需要对TIM3_CH2输出进行一个重映射;此外还要将PB5配置成复用推挽输出的状态。

GPIOCfg

IORemap

定时器PWM输出配置,实例代码如下:

void LunarInitTIM3() {
	TIM_TimeBaseInitTypeDef TIM3_Cfg;
	GPIO_InitTypeDef GPIOB5_Cfg;
	TIM_OCInitTypeDef TIM3_OCCfg;

    // 定时器时基配置   BEGIN

	// 打开TIM3所需要的时钟 APB1
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
	TIM_TimeBaseStructInit(&TIM3_Cfg);
	// 配置使用内部时钟 72M Hz
	TIM_InternalClockConfig(TIM3);

    // 这里配置定时器更新频率是1000HZ
	TIM3_Cfg.TIM_CounterMode = TIM_CounterMode_Up;
	TIM3_Cfg.TIM_Period = 100 - 1;
	TIM3_Cfg.TIM_Prescaler = 720 - 1;

	TIM_TimeBaseInit(TIM3, &TIM3_Cfg);
	// 因为TIM_TimeBaseInit会置TIMx_EGR.UG[0]为1,手动产生一个更新事件,
	// 同时会同步影子寄存器的值,而该更新事件又会产生一个多余的中断,所以,
	// 我们需要在开启中断之前,手动清楚更新事件标志位
	TIM_ClearFlag(TIM3, TIM_FLAG_Update);

    // 定时器时基配置   END


	// 配置GPIO 	BEGIN

	// 开启复用时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
	// 部分重映射
	GPIO_PinRemapConfig(GPIO_PartialRemap_TIM3, ENABLE);
	// 初始化GPIOB5为推挽复用输出
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);

 	GPIOB5_Cfg.GPIO_Mode = GPIO_Mode_AF_PP;
 	GPIOB5_Cfg.GPIO_Pin = GPIO_Pin_5;
 	GPIOB5_Cfg.GPIO_Speed = GPIO_Speed_2MHz;

 	GPIO_Init(GPIOB, &GPIOB5_Cfg);

	// 配置GPIO 	END


	// 配置TIM3的PWM输出	BEGIN

	TIM_OCStructInit(&TIM3_OCCfg);

	TIM3_OCCfg.TIM_OCMode = TIM_OCMode_PWM1;
	TIM3_OCCfg.TIM_OCPolarity = TIM_OCPolarity_High;
	TIM3_OCCfg.TIM_OutputState = TIM_OutputState_Enable;
	TIM3_OCCfg.TIM_Pulse = 0;

	TIM_OC2Init(TIM3, &TIM3_OCCfg);

	// 配置TIM3的PWM输出	END

	// 使能arr和ccr寄存器的影子功能
	TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable);
	TIM_ARRPreloadConfig(TIM3, ENABLE);

	// 使能更新中断
	// TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE);
	// 开启定时器
	TIM_Cmd(TIM3, ENABLE);
}

int main() {

	// 初始化定时器
	LunarInitTIM3();
    // 初始化系统定时器
	SYSTick_Init();

	int dir = 0, cr = 0;

	while(1) {
		TIM_SetCompare2(TIM3, cr);
		Delay_Ms(20);

		if (dir == 0) {
			cr++;
			if (cr > 99) {
				dir = 1;
				cr = 99;
			}
		} else {
			cr--;
			if (cr < 0) {
				dir = 0;
				cr = 0;
			}
		}
	}

	return 0;
}

实验结果就是PB5处的LED灯实现了呼吸的效果。


本章完结

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

基于FPGA的NC图像质量评估verilog实现,包含testbench和MATLAB辅助验证程序

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 5.算法完整程序工程 1.算法运行效果图预览 vivado2019.2和matlab2022a测试&#xff0c;结果如下&#xff1a; 2.算法运行软件版本 vivado2019.2 matlab2022a 3.部分核心程序 timescale …

解决vue3项目打包后部署后某些静态资源图片不加载问题

目录 问题 原因 解决方案 问题 开发完项目打包并部署 然后访问时发现导航栏背景图片没加载 打开浏览器控制台发现这张图片报错404 原因 可能是因为在部署后的服务器环境中对中文文件名的支持不完善。服务器在解析 URL 时可能无法正确识别或编码中文字符&#xff0c;导致无…

高精度原理介绍及代码实现

目录 高精度 引入 使用场景 实现原理 高精度加法 数据存储 加法实现 总代码 高精度减法 与加法的不同点&#xff1a; 总代码 高精度乘法 总代码 高精度除法 总结 总注意点 减法注意点 高精度 引入 所谓高精度并不是很高级难懂的东西&#xff0c;只是对传统的…

Kubernetes 核心概念

kubernetes的对象 Kubernetes 包含多种类型的资源对象&#xff1a;Pod、Label、Service、Replication Controller 等。 所有的资源对象都可以通过 Kubernetes 提供的 kubectl 工具进行增、删、改、查等操作&#xff0c;并将其保存在 etcd 中持久化存储。 Kubernets其实是一个…

【JAVA进阶篇教学】第十三篇:Java中volatile关键字讲解

博主打算从0-1讲解下java进阶篇教学&#xff0c;今天教学第十三篇&#xff1a;volatile关键字讲解。 在 Java 中&#xff0c;volatile关键字是一种轻量级的同步机制&#xff0c;用于确保变量的可见性和禁止指令重排序。本文将详细解释volatile关键字的工作原理、可见性保证以及…

对称加密介绍

一、什么是对称加密 对称密钥算法(Symmetric-key algorithm)&#xff0c;又称为对称加密、私钥加密、共享密钥加密&#xff0c;是密码学中的一类加密算法。 对称加密的特点是&#xff0c;在加密和解密时使用相同的密钥&#xff0c;或是使用两个可以简单地相互推算的密钥。 这…

Zynq开发-使用PYNQ快速入门摄像头MIPI驱动(OV5640)-overlay设计

目录 1. 简介 2. Overlay 设计 2.1 总体设计 2.2 MIPI 子系统 2.3 去马赛克 2.4 AXI_IIC 3. 注意事项 4. 总结 1. 简介 本文是关于《Zynq开发-使用PYNQ快速入门摄像头MIPI驱动(OV5640)-CSDN博客》的博客文章&#xff0c;涉及了overlay设计的Vivado工程细节。在使用PYN…

iZotope RX 11 for Mac 激活版:让您的音频焕发生机!

在追求音频完美的道路上&#xff0c;iZotope RX 11 for Mac是您的得力助手。它凭借先进的音频修复技术和丰富的音频增强工具&#xff0c;让您的音频作品焕发出前所未有的生机与活力。无论您是专业的音频工程师&#xff0c;还是业余的音乐爱好者&#xff0c;都能在这款工具中找到…

【Spring】验证 @ServerEndpoint 的类成员变量线程安全

文章目录 前言猜想来源验证方法Controller 的情况ServerEndpoint 的情况 后记 前言 最近有 websocket 的需求。探索 ServerEndpoint 的类成员变量特点。 这里类比 Controller 讨论 ServerEndpoint 类成员变量是否线程安全。 猜想来源 网上的教程大多数都这么展示程序&#…

OBS插件--音频采集

音频采集 音频采集是一款 源 插件,类似于OBS的win-capture/game-capture&#xff0c;允许从特定应用程序捕获音频&#xff0c;而不是捕获整个系统的音频。避免了因为特定音频的采集而需要引入第三方软件&#xff0c;而且时延也非常低。 下面截图演示下操作步骤&#xff1a; 首…

HCIP-Datacom-ARST自选题库_06_排障【28道题】

一、单选题 1.如果面对复杂的网络故障&#xff0c;并经过评估认为短时间内无法完成排障&#xff0c;而此时用户又急需恢复网络的可用性&#xff0c;那么正确的做法是? 告诉用户这是不可能实现的 不通知客户的情况下&#xff0c;直接搭建替代的网络环境 始终尝试排除故障&a…

前端AJAX与后台交互技术知识点及案例(续2)

以下笔记均为学习哔站黑马程序员AJAX视频所得&#xff01;&#xff01;&#xff01; AJAX作用&#xff1a;浏览器和服务器之间通信&#xff0c;动态数据交互 axios函数 先引入axios库&#xff0c;可在bootcdn中寻找相关js文件或者对应的script标签 axios({url:http://hmajax…

最大子矩阵:前缀和、动态规划

最近在学习动态规划&#xff0c;在牛客上刷题时碰到了这一题。其实最初的想法是暴力和前缀和&#xff0c;但是时间复杂度极高&#xff0c;需要套4层循环。后来去网上搜了一下相关的题解和做法&#xff0c;进而了解到了前缀和&#xff0b;线性动态规划的做法。但是在成功做出这题…

【爬虫基础1.1课】——requests模块上

目录索引 requests模块的作用&#xff1a;实例引入&#xff1a; 特殊情况&#xff1a;锦囊1&#xff1a;锦囊2: 这一个栏目&#xff0c;我会给出我从零开始学习爬虫的全过程。感兴趣的小伙伴可以关注一波&#xff0c;用于复习和新学都是不错的选择。 那么废话不多说&#xff0c…

接搭建仿美团、代付系统源码搭建教程

最近很多粉丝催更、分享一下地球号&#xff1a;xiaobao0214520(WX) 现在大家都很流行搞网恋&#xff0c;我们搭建一个跟美团相似的系统 然后开发一个好友代付&#xff0c;我们在点单的时候转发链接让网恋对象付钱 若只是单点外卖的话&#xff0c;能榨出的油水还是太少。 所以…

Redis的数据淘汰策略——Java全栈知识(19)

Redis的数据淘汰策略 什么是数据淘汰策略 数据过期策略是 redis 中设置了 TTL 的数据过期的时候 Redis 的处理策略。数据淘汰策略是 Redis 内存不够的时候&#xff0c; 数据的淘汰策略&#xff1a;当 Redis 中的内存不够用时&#xff0c;此时在向 Redis 中添加新的 key, 那么…

免费思维13招之八:跨行业思维

免费思维13招之八:跨行业思维 免费思维的另一大战略思维——跨行业型思维。 跨行业型思维有两种:一种是通过跨行业,把自己的产品免费掉,从而赚取其他行业的利润。另一种是通过跨行业,把别人的主流产品免费掉,从而增大自己产品的销量。 第一种,把自己的产品免费,从而赚…

ONES 功能上新 | 近期产品新功能一览

支持在 ONES Project 中通过弹窗查看、编辑 ONES Wiki 页面。 应用场景&#xff1a; 当需要在 ONES Project 中查看 ONES Wiki 的页面内容时&#xff0c;可以直接点击工作项关联的 ONES Wiki 页面或项目文档组件中的页面&#xff0c;即可在 ONES Project 中通过弹窗查看 ONES W…

问题解决记录 | 内存溢出

报错截图&#xff1a; 处理方式&#xff1a; 增大PDI工具的内存 打开Spoon.bat配置文件 修改配置

【Linux 网络】网络编程套接字 -- 详解

⚪ 预备知识 1、理解源 IP 地址和目的 IP 地址 举例理解&#xff1a;&#xff08;唐僧西天取经&#xff09; 在 IP 数据包头部中 有两个 IP 地址&#xff0c; 分别叫做源 IP 地址 和目的 IP 地址。 如果我们的台式机或者笔记本没有 IP 地址就无法上网&#xff0c;而因为…