stm32 PWM驱动呼吸灯

本文详细介绍了STM32的输出比较(OC)功能,用于生成PWM波形,阐述了CCR寄存器在PWM中的作用,以及PWM的频率、占空比和分辨率计算。此外,还展示了如何利用PWM驱动呼吸灯,包括开启时钟、初始化时基单元、配置GPIO和输出比较模块,以及通过调整CCR值改变占空比实现亮度变化。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、输出比较简介

OC(Output Compare)输出比较
输出比较可以通过比较CNT与CCR寄存器值的关系,来对输出电平进行置1、置0或翻转的操作,用于输出一定频率和占空比的PWM波形。

这里插入图片描述CCR(捕获/比较寄存器)这里输入捕获和输出比较是共用的,当使用输入捕获时,就是捕获寄存器;当使用输出比较时,就是比较寄存器。在输出比较这里,这部分电路会比较CNT和CCR的值,CNT计数器值自增,CCR是我们给定的一个值,当CNT的值大于,小于或者等于CCR时,输出会被置1,置0,反复下去,就形成了一个电平不断跳变的PWM波形了。这就是输出比较的基本功能了。
每个高级定时器和通用定时器都拥有4个输出比较通道
高级定时器的前3个通道额外拥有死区生成和互补输出的功能

在这里插入图片描述
在这里插入图片描述死区生成和互补输出主要用来驱动三相无刷电机。

二、PWM简介

PWM(Pulse Width Modulation)脉冲宽度调制
在具有惯性的系统中,可以通过对一系列脉冲的宽度进行调制,来等效地获得所需要的模拟参量,常应用于电机控速等领域
PWM参数:
频率 = 1 / TS
占空比 = TON / TS(高电平时间/整个周期时间)
分辨率 = 占空比变化步距

在这里插入图片描述

三、输出比较通道

在这里插入图片描述当CNT>CCR1或者CNT=CCR1时,就会传给输出模式控制器一个信号,输出模式控制器就会改变它输出的oc1ref的高低电平。通过极性选择电路,写0电平不翻转,写1电平翻转,最后通过输出使能电路oc1通道输出。
输出模式控制器的具体工作方式:
在这里插入图片描述我们主要使用PWM模式1和PWM模式2,频率和占空比都可调。一般我们使用向上计数,PWM模式1向上计数模式产生一个PWM波形的过程:
在这里插入图片描述
配置好时基单元后,CNT计时器就开始不断自增运行了,然后我们给定一个CCR的值。如上图右上角部分,黄线是ARR(自动重装器)的值,红线是CCR的值,蓝线是CNT,下面的绿线是预设输出。
当CNT<CCR时,置高电平;当CNT>=CCR时,置低电平。当CNT=ARR时,清0继续自增。由上图可以知道,占空比的值是根据CCR的值来调控的,CCR越大,高电平时间越长,占空比越大。这样持续下去就形成了电平不断跳变的PWM信号,再通过极性选择和输出使能,最终通过GPIO输出。
PWM参数计算:
在这里插入图片描述PWM频率: Freq = CK_PSC / (PSC + 1) / (ARR + 1)
PWM频率等于CNT计数更新频率,因为PWM的周期等于CNT计数周期。
PWM占空比: Duty = CCR / (ARR + 1)
PWM分辨率: Reso = 1 / (ARR + 1)

四、pwm驱动呼吸灯

步骤:
1.开启时钟,开启定时器时钟和GPIO时钟。
2.初始化时基单元。初始化ARR和PSC的值。
3.初始化GPIO,PWM要通过GPIO输出,配置GPIO。
4.初始化输出比较模块。选择通道,初始化输出比较结构体。
5.启动定时器。启动后就开始输出PWM波形了。
驱动呼吸灯demo:
pwm.c

#include "stm32f10x.h"                  // Device header
 void PWM_Init(void)
 {
    
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
	TIM_OCInitTypeDef TIM_OCInitStructure;   //输出比较结构体
	GPIO_InitTypeDef GPIO_InitStructure;
	//1.开启时钟,选择内部时钟,TIM2是APB1总线的外设
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	//配置GPIO
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  //选择复用推挽输出,将引脚控制权交给片上外设,控制PWM输出。
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitStructure);
	
	//2.初始化时基单元
	TIM_InternalClockConfig(TIM2);   //选择内部时钟驱动TIM2的时基单元
	TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1 ;  //选择时钟分频
	TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;  //计数器模式选择
	//定时时间的公式:CK_CNT_OV = CK_PSC / (PSC + 1) / (ARR + 1),定时1s,也就是1HZ;
	//预分频器和计数器有一个数的偏差,因此要减1,PSC和ARR的取值0~65535;
	TIM_TimeBaseInitStructure.TIM_Period = 100-1;  //自动重装器的值  ARR
	TIM_TimeBaseInitStructure.TIM_Prescaler = 720-1;  //预分频器的值  PSC
	TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;  //重复计数器的值,基本定时器用不到
	TIM_TimeBaseInit(TIM2,&TIM_TimeBaseInitStructure);
	
	TIM_OCStructInit(&TIM_OCInitStructure);  //给结构体赋初值函数
	TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;  //配置输出比较模式
	TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;  //输出比较极性,高电平
	TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;  //输出状态使能
	TIM_OCInitStructure.TIM_Pulse = 50;  //配置CCR寄存器的值  CCR
	TIM_OC1Init(TIM2,&TIM_OCInitStructure);
	//5.启动定时器
	TIM_Cmd(TIM2,ENABLE); 
 }
 
 void PWM_SetCompare1(uint16_t compare)
 {
    TIM_SetCompare1(TIM2,compare);
 }

main.c

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "Buzzer.h"
#include "Key.h"
#include "Light_Seror.h"
#include "OLED.h"
#include "PWM.h"


int main(void)
{
	uint16_t i;
	OLED_Init();
	PWM_Init();
	
	while(1)
	{
		for(i = 0;i<=100;i++){
		    PWM_SetCompare1(i);
			Delay_ms(10);
		}	
        for(i = 0;i<=100;i++){
		    PWM_SetCompare1(100-i);
			Delay_ms(10);
		}			
	}
}

注:内容来自博主 【江科大自化协】。本文做学习笔记用。

<think>好的,用户现在问的是关于STM32PWM呼吸实现。之前他们问过有源蜂鸣器是否能播放音频,现在转到另一个主题,可能是在做某种嵌入式项目,需要控制光效果。我需要先确定呼吸的基本原理,然后结合STM32的具体实现方法。 首先,呼吸是通过调节LED的亮度变化来实现的,通常使用PWM(脉宽调制)来控制。PWM通过改变占空比来调整平均电压,从而改变LED的亮度。用户可能已经知道PWM的基本概念,但需要具体的步骤来在STM32上实现。 接下来,我需要考虑用户可能的背景。他们可能有一定的嵌入式开发基础,但可能对STM32PWM配置不太熟悉。需要详细步骤,包括使用的开发环境(比如Keil、STM32CubeIDE)、配置PWM的流程,以及代码示例。 用户的问题中提到的是STM32,所以需要具体到该系列MCU的配置方法。STM32有多种系列,比如F1、F4等,但PWM配置的大体流程是类似的,可能使用定时器的PWM模式。需要提到如何通过CubeMX配置定时器和GPIO,或者直接通过寄存器配置。 另外,呼吸的效果需要一个渐变的过程,即改变占空比的值,可能使用线性递增递减或者正弦波等方式。需要给出一个循环调整占空比的示例代码,比如使用for循环逐渐增加和减少比较寄存器的值,并添加适当的延时。 可能还需要提到中断或者DMA的方式来实现更平滑的效果,但考虑到用户可能是初学者,保持简单的方法可能更好,使用基本的延时函数即可。 还要注意检查可能的错误点,比如定时器时钟配置是否正确,PWM频率是否足够高以避免闪烁,占空比调整的步进是否合适。例如,PWM频率一般要高于100Hz,否则人眼会察觉到闪烁。占空比的分辨率(比如使用8位即0-255)会影响亮度变化的平滑度。 另外,用户可能没有说出他们使用的具体STM32型号,所以在回答时需要保持一定的通用性,同时指出不同型号之间的可能差异,比如定时器的数量或通道的不同。 最后,总结实现步骤,强调配置定时器、生成PWM信号、以及循环调整占空比的关键点,确保用户能够按照步骤操作并实现呼吸效果。</think>以下是关于 **STM32 PWM呼吸** 的详细介绍与实现方法: --- ### 一、PWM呼吸原理 呼吸的核心是通过 **PWM(脉宽调制)** 动态调节LED亮度,实现「渐亮→渐暗」的循环效果: - **亮度控制**:PWM占空比(高电平时间占比)决定LED平均电压 - **呼吸周期**:通过算法平滑改变占空比(如线性/正弦变化) --- ### 二、STM32硬件配置(以通用定时器为例) #### 1. 定时器选择 - **推荐定时器**:TIM2/TIM3/TIM4(通用定时器) - **PWM模式**:PWM Mode 1 或 2 - **频率公式**: $$ PWM频率 = \frac{定时器时钟源}{预分频系数(PSC) \times 自动重载值(ARR)} $$ 建议频率范围:1kHz~10kHz(避免肉眼可见闪烁) #### 2. GPIO配置 - 选择支持PWM输出的引脚(如PA6对应TIM3_CH1) - 设置为 **复用推挽输出** 模式 --- ### 三、代码实现步骤(以HAL库为例) #### 1. 初始化PWM ```c // 启动定时器PWM通道 HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_1); ``` #### 2. 呼吸核心算法 ```c uint16_t duty = 0; int8_t step = 1; // 亮度变化步长 while(1) { // 更新占空比(范围:0 ~ ARR值) __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_1, duty); // 渐变方向控制 duty += step; if(duty >= htim3.Instance->ARR || duty == 0) { step = -step; } // 调节呼吸速度(单位:ms) HAL_Delay(10); } ``` --- ### 四、进阶优化技巧 | **优化方向** | **实现方法** | |------------------|-----------------------------------------------------------------------------| | **平滑过渡** | 使用正弦函数计算占空比:`duty = ARR/2 * (1 + sin(angle))` | | **无阻塞延时** | 结合定时器中断更新占空比,避免`HAL_Delay`卡住主循环 | | **多通道同步** | 配置多个PWM通道,实现彩虹呼吸效果 | | **自动重载预装** | 启用TIMx_CR1寄存器的`ARPE`位,确保ARR值更新无抖动 | --- ### 五、CubeMX配置示例(TIM3) 1. **时钟树配置**:确保定时器时钟源正确(如APB1总线) 2. **定时器参数**: - Prescaler (PSC):79(假设主频84MHz → 84MHz/(79+1)=1.05MHz) - Counter Period (ARR):1000 → PWM频率=1.05MHz/1000≈1.05kHz 3. **PWM通道**: - Mode: PWM Mode 1 - Pulse: 初始占空比(如500) --- ### 六、关键调试要点 1. **示波器验证**:检查PWM波形是否符合预期频率和占空比 2. **电流保护**:串联220Ω电阻防止LED过流 3. **频率选择**:若低频导致LED闪烁,尝试提高ARR值或降低PSC值 4. **DMA传输**:大批量占空比数据更新时可使用DMA减轻CPU负担 --- 通过上述方法,即可在STM32上实现平滑的呼吸效果。实际效果可通过调节**渐变步长**(step)和**延时时间**(HAL_Delay)优化动态表现。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值