11.[STM32]PWM脉宽调制-呼吸灯

本文介绍了STM32使用PWM通过TIM3控制LED灯实现呼吸灯效果。详细讲解了PWM的工作原理,配置了TIM3的捕获/比较模式寄存器、使能寄存器和比较寄存器,并提供了配置代码示例。通过改变比较寄存器的值调整占空比,从而实现LED亮度的变化。
摘要由CSDN通过智能技术生成

🍌
🍌🍌
作者简介:大家好啊,我叫DW,每天分享一些我新学到的知识,期待和大家一起进步
🍋
🍋🍋
系列专栏:STM32
🍎
🍎🍎
🍎🍎🍎
🌞小实验目标:使得LED灯由亮到暗再由暗到亮(呼吸灯)🌞
🍊如有写得不好的地方欢迎大家指正🍊
创作时间:🍊🍊🍊2022年4月29日🍊🍊🍊

今天又是新的一天,早起码字发文章。通过这些天的分享,学到了挺多东西的,也认识很多优秀的伙伴,发表文章的同时,也加深了自己对整个知识的理解,自己动手查查资料,收货了很多,这个月最后一篇文章了,希望下个月能发表更多高质量的文章,与大家共同进步!!

1. PWM简介

脉冲宽度调制(PWM),简称脉宽调制,就是对脉冲宽度的控制。
PWM原理图

在这里插入图片描述
假定TIM定时器采取向上计数PWM模式,当 CNT小于CCRx 时,PWM输出逻辑1(高电平),当 CNT大于等于CCRx 时PWM输出逻辑0(低电平)。当 CNT达到 ARR 值的时候,重新归零,然后重新向上计数,一直循环。我们只需要改变 CCRx 的值,就可以改变 PWM 输出的占空比,改变 ARR 的值,就可以改变 PWM 输出的频率,这就是 PWM 输出的原理。

频率与周期关系

关系:f=1/T。(其中f为频率,T为周期)。
频率:物质在1s内完成周期性变化的次数叫做频率,常用f表示。符号为Hz。通俗来说,可以认为你一秒钟可以投篮三次,三次就是所谓的频率,故频率为3。
周期:物体作往复运动或物理量作周而复始的变化时,重复一次所经历的时间。由上图可以知道,高低电平持续的时间就是一个周期,即周期T=t1+t2,频率f=1/T。

常见的转换关系
1Mhz = 1000Khz = 1000 000hz;
1s = 1000ms = 1000 000us = 1000 000 000ns

本次实验使用的是通用定时器TIM3,我们使用没有重映像功能的PA6,PA6对应着通道一(CH1)
在这里插入图片描述

2. PWM配置

本次使用三个寄存器来控制 PWM 的输出。这三个寄存器分别是:
捕获/比较模式寄存器(TIMx_CCMR1/2)
捕获/比较使能寄存器(TIMx_CCER)
捕获/比较寄存器(TIMx_CCR1~4)

2.1捕获/比较模式寄存器

该寄存器总共有2 个TIMx _CCMR1和 TIMx _CCMR2。TIMx_CCMR1 控制 CH1 和 CH2,而 TIMx_CCMR2 控制 CH3 和 CH4。该寄存器的各位描述如下图所示:
在这里插入图片描述
我们使用的是PWM2模式OC1M[2:0]3位必须设置为111。PWM1和PWM2两种模式的区别就是输出电平的极性相反。
在这里插入图片描述

2.2 捕获/比较使能寄存器

该寄存器控制着各个输入输出通道的开关。该寄存器的各位描述如下图所示:
在这里插入图片描述
我们这里只用到了位0(CC1E 位),该位是输入/捕获 1 输出使能位,要想PWM从IO口输出,这个位必须设置为1,所以我们需要设置该位为1。
在这里插入图片描述

2.3 捕获/比较寄存器

该寄存器总共有 4 个,对应着4个输通道CH1至CH4
在这里插入图片描述
在输出模式下,该寄存器的值与 CNT 的值比较,根据比较结果产生相应动作。利用这点,我们通过修改这个寄存器的值,就可以控制 PWM 的输出脉宽了。本章,我们使用的是 TIM3的通道1(CH1),所以我们需要修改 TIM3_CCR1 以实现脉宽控制LED灯的亮度。

🎵🎵 小提示
如果是通用定时器,则配置以上三个寄存器就够了,但是如果是高级定时器,则还需要配置:刹车和死区寄存器(TIMx_BDTR)

2.3 PWM配置

本次用到的寄存器已经全部说完,我们TIM3_CH1输出PWM来控制LED的亮度。配置步骤如下:
(1)开启TIM3时钟,配置PA6为复用输出。
(2)设置 TIM3 的ARR和PSC。
(3)设置TIM3_CH1的PWM模式及通道方向, 使能TIM3的CH1输出。
(4)使能 TIM3。
(5)修改 TIM3_CCR1 来控制占空比。

🎵🎵 小提示
高级定时器,我们还需要使能刹车和死区寄存器(TIM1_BDTR)的 MOE 位,以使能整个 OCx(即 PWM)输出。数的设置函数为:

TIM_CtrlPWMOutputs(TIM1,ENABLE);// MOE 主输出使能
#define CH1 GPIO_Pin_6
#define PWM_PROT GPIOA

void PWM_UserConfig(u16 Period,u16 Prescaler){
	
	
	GPIO_InitTypeDef GPIO_InitStructure;
	TIM_TimeBaseInitTypeDef  TIM_InitStructure;
	TIM_OCInitTypeDef PWM_InitStructure;
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_AFIO,ENABLE);
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);
	
	//PA1 TIM2_CH2
	GPIO_InitStructure.GPIO_Pin = CH1;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;//复用推挽输出
	GPIO_Init(PWM_PROT,&GPIO_InitStructure);
	
	TIM_InitStructure.TIM_Period = Period;
	TIM_InitStructure.TIM_Prescaler = Prescaler;
	TIM_InitStructure.TIM_ClockDivision = TIM_CKD_DIV1;//不分割
	TIM_InitStructure.TIM_CounterMode = TIM_CounterMode_Up;//向上计数
	TIM_InitStructure.TIM_RepetitionCounter = DISABLE;//不重复计数
	TIM_TimeBaseInit(TIM3,&TIM_InitStructure);
	TIM_Cmd(TIM3,ENABLE);//开启全局使能

	//PWM配置
	PWM_InitStructure.TIM_OCMode = TIM_OCMode_PWM2;
	PWM_InitStructure.TIM_OutputState = TIM_OutputState_Enable;//输出使能
	PWM_InitStructure.TIM_OCPolarity = TIM_OCPolarity_High;//输出极性高
	TIM_OC1Init(TIM3,&PWM_InitStructure);//通道几就选oc几
	
	TIM_OC1PreloadConfig(TIM3,ENABLE);//预装在寄存器 
	TIM_SetCompare1(TIM3,0);//控制占空比
}

🎵🎵 小提示

PW1模式和PWM2模式区别:
假定TIM_OCPolarity_High,则起始波形为高电位。

PWM1:
当计时器值小于比较器设定值时则TIMX输出脚此时输出有效高电位。
当计时器值大于或等于比较器设定值时则TIMX输出脚此时输出低电位。

PWM2:
当计时器值小于比较器设定值时则TIMX输出脚此时输出有效低电位。
当计时器值大于或等于比较器设定值时则TIMX输出脚此时输出高电位。

2.4 主函数配置

我们设置频率为50hz(20ms),那么怎么可以实现LED的呼吸灯功能呢?我们利用标志位,然后利用占空比调制函数:

`TIM_SetCompare1(TIM3,time);`

其中time是不断变化的,至此就实现了呼吸灯的功能



#include "sys.h"
#include "delay.h"
#include "pwm.h"


 int main(void)
 {		
	 
	 u8 flag = 0,time = 0;
	 
	 delay_init();
	 PWM_UserConfig(200-1,7200-1);//50hz 20ms
	 
	 while(1){
		 
		 delay_ms(10);//去掉这个延时,速度太快,没有效果
		 if(flag==0)
		{
		 
			 time++;
		 
		 }
		 else
		 {
			 time--;
		 
		 }
		 if(time>=100) flag=0;
		 if(time<=0)   flag=0;
		 TIM_SetCompare1(TIM3,time);
		 
 }
}

最后,我们可以看到LED由亮变暗再由暗变亮。

如何计算脉宽请基本定时器

3.结语

今天的分享就到这里,谢谢大家的耐心阅读,如果觉得有用的话给个👍👍👍

🌜🌜🌜本章结束,我们下一章见🌜🌜🌜

参考资料:
1.STM32固件库手册、正点原子STM32不完全手册_库函数版本
2.学习视频链接

资料已上传,需要自取

  • 7
    点赞
  • 35
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
STM32 PWM 呼吸灯代码通常用于基于STM32微控制器的项目中,它通过周期性调整PWM脉宽调制)信号的占空比来模拟灯的明暗变化,实现类似呼吸效果。这里我将简要概述一个基本的代码结构: ```c #include "stm32f10x.h" // 引入STM32 HAL库 // 定义PWM参数和GPIO引脚 GPIO_TypeDef* GPIOx = GPIOA; // GPIOA通道 uint16_t LED_Pin = GPIO_PIN_0; // LED引脚 TIM_HandleTypeDef htim1; // 定义定时器1结构体 void setup_pwm(uint16_t freq) { // 配置GPIO HAL_GPIO_Init(GPIOx, &GPIO_InitStruct); HAL_TIM_Base_Init(&htim1); // 初始化定时器1 // 设置PWM参数 TIM_OC_InitTypeDef sConfig; sConfig.OCMode = TIM_OCMODE_PWM1; // PWM输出模式 sConfig.Pulse = 0; // 初始占空比为0(灯全暗) sConfig.OCPolarity = TIM_OCPOLARITY_HIGH; // 输出高电平 sConfig.OCFastMode = ENABLE; // 快速PWM模式 HAL_TIM_PWM_Init(&htim1); // 初始化PWM通道 HAL_TIM_PWM_ConfigChannel(&htim1, &sConfig, LED_Pin); // 配置LED PWM通道 HAL_TIM_Base_Start(&htim1); // 开启定时器计时 // 设置PWM频率 HAL_TIM_Base_SetPrescaler(&htim1, freq - 1); // 频率减1,因为计数器最大值是频率-1 HAL_TIM_Base_SetAutoReload(&htim1, (TIM的优点周期 * freq) / 1000); // 设置自动重载周期 } void pwm_breath_light(int8_t duty_cycle_step, uint32_t period_ms) { // 更新PWM占空比 duty_cycle_step *= period_ms; // 将步长转换为毫秒内 if (duty_cycle_step > 0) { // 呼吸增加亮度 HAL_TIM_PWM_IgnoreDeadTime(&htim1, DISABLE); // 忽略死区时间 HAL_TIM_PWM_SetValue(&htim1, (TIM的优点周期 * period_ms) / 1000 + duty_cycle_step); // 提高亮度 } else if (duty_cycle_step < 0) { // 呼吸降低亮度 HAL_TIM_PWM_IgnoreDeadTime(&htim1, ENABLE); // 开启死区时间 HAL_TIM_PWM_SetValue(&htim1, (TIM的优点周期 * period_ms) / 1000 - duty_cycle_step); // 减低亮度 } } int main() { setup_pwm(1000); // 设置基本PWM频率 while (1) { for (int i = 0; i <= 100; i += 5) { // 呼吸循环 pwm_breath_light(i, 500); // 呼吸灯,每次变化5%占空比,周期500ms HAL_Delay(50); // 暂停50ms } for (int i = 100; i >= 0; i -= 5) { // 同样反向呼吸 pwm_breath_light(i, 500); HAL_Delay(50); } } return 0; } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

依点_DW

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值