欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 汽车 > 新车 > stm32:PWM原理 及 呼吸灯实现

stm32:PWM原理 及 呼吸灯实现

2025/3/25 21:07:21 来源:https://blog.csdn.net/sikimayi/article/details/146440750  浏览:    关键词:stm32:PWM原理 及 呼吸灯实现

早上好啊,大伙。上一期说完了定时器的原理和模板。这一期就来运用一下定时器来实现一些模块的功能。
对于定时器的一大应用就是PWM波调速,通过PWM调速能够实现很多模块的使用。所以今天这一期我们就来讲讲什么是PWM,讲完之后给大伙用PWM做一个呼吸灯。

请添加图片描述

文章目录

  • 什么是PWM
    • PWM的频率
        • 单位时间内(通常为1秒)脉冲信号重复的次数,单位为赫兹(Hz)。
    • PWM的周期
        • 一个完整脉冲循环(从高电平开始到下一个高电平开始)的时间长度,单位为秒(s)。
    • 举个栗子
    • PWM的占空比
  • PWM原理
    • OC(Output Compare)输出比较
    • PWM(Pulse Width Modulation)脉冲宽度调制
      • PWM参数:
    • 输出比较通道(通用)框图
  • PWM代码实现
    • 第一步、添加上期的 TIM 时钟的代码
    • 第二步、确定输出比较通道
    • 第三步、OC 通道初始化
    • 第四步、PWM配置CCR的值
  • 使用PWM实现呼吸灯
  • 总结
  • 感谢大伙观看,别忘了三连支持一下
  • 大家也可以关注一下我的其它专栏,同样精彩喔~
  • 下期见咯~

什么是PWM

PWM 也就是脉冲宽度调制,是一种通过调节数字信号的脉冲宽度来控制模拟设备的技术。其核心思想是快速切换电源的通断,通过改变高电平(导通)与低电平(关断)的时间比例(即占空比),来模拟不同的平均电压或功率输出。

不知道大家前面有没有学过数码管,用一个寄存器控制多个数码管就是通过快速变换,来实现多个数码管的显示。
再比如说,我们看的动漫也是这样实现的。

PWM的频率

单位时间内(通常为1秒)脉冲信号重复的次数,单位为赫兹(Hz)。

频率 = 1 周期 频率 = \frac{1}{周期} 频率=周期1

PWM的周期

一个完整脉冲循环(从高电平开始到下一个高电平开始)的时间长度,单位为秒(s)。

周期 = 1 频率 周期 = \frac{1}{频率} 周期=频率1

举个栗子

请添加图片描述频率 ——
若频率为 1 kHz(1000 Hz),则周期为:
周期 = 1 1000 = 0.001 秒 周期 = \frac{1}{1000} = 0.001秒 周期=10001=0.001

周期 ——
若周期为 20 μs(微秒),则频率为:
频率 = 1 T = 1 20 × 1 0 − 6 = 50 kHz \text{频率} = \frac{1}{T} = \frac{1}{20 \times 10^{-6}} = 50\,\text{kHz} 频率=T1=20×1061=50kHz

PWM的占空比

是一个脉冲周期内,高电平的时间与整个周期时间的比例
单位: % (0%-100%)
表示方式:20%
在这里插入图片描述

周期: 一个脉冲信号的时间 , 1s内测周期次数等于频率
脉宽时间: 高电平时间

上图中,脉宽时间占总周期时间的比例,就是占空比。

PWM原理

利用快速开关电源的通断,通过改变高电平持续时间占整个周期的比例(占空比),控制输出到负载的平均电压或功率。

OC(Output Compare)输出比较

输出比较可以通过比较CNT与CCR寄存器值的关系,来对输出电平进行置1、置0或翻转的操作,用于输出一定频率和占空比的PWM波形
每个高级定时器和通用定时器都拥有4个输出比较通道
高级定时器的前3个通道额外拥有死区生成和互补输出的功能

PWM(Pulse Width Modulation)脉冲宽度调制

在具有惯性的系统中,可以通过对一系列脉冲的宽度进行调制,来等效地获得所需要的模拟参量,常应用于电机控速等领域

PWM参数:

频率 = 1 / TS
占空比 = TON / TS
分辨率 = 占空比变化步距

在这里插入图片描述

输出比较通道(通用)框图

在这里插入图片描述
在这里插入图片描述

PWM代码实现

第一步、添加上期的 TIM 时钟的代码

这一步就不放代码。
就需要把ARR和PSC调一下,改成我们所想要的就行了。

	TIM_TimeBaseInitStructure.TIM_Period = 100 - 1;					//计数周期,即ARR的值TIM_TimeBaseInitStructure.TIM_Prescaler = 720 - 1;				//预分频器,即PSC的值

第二步、确定输出比较通道

每一个输出比较通道都有它对应的引脚口,可以看一下下面的引脚图 ——
在这里插入图片描述

例如说,下面 TIM2 的几个 OC 通道。
在这里插入图片描述

这里我们就用 TIM2 的 OC1 通道为例。

void PWM_Init(void)
{Timer_Init();													//导入之前写的TIM时钟定义RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);			//开启GPIOB的时钟GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);							//将PA0引脚初始化为复用推挽输出	//受外设控制的引脚,均需要配置为复用模式
}

第三步、OC 通道初始化

在OC的初始化里面有很多的参数都是高级定时器里面才会用的,所以我们就挑出其中通用定时器里的参数来进行配置 ——

  1. TIM_OCMode,输出比较模式。

TIM_OCMode_Timing 定时模式
TIM_OCMode_Active 激活模式
TIM_OCMode_Inactive 非激活模式
TIM_OCMode_Toggle 翻转模式
TIM_OCMode_PWM1 PWM模式1
TIM_OCMode_PWM2 PWM模式2

  1. TIM_OCPolarity,输出极性。

TIM_OCPolarity_High 高极性
TIM_OCPolarity_Low 低极性

  1. TIM_OutputState,输出使能。

TIM_OutputState_Disable 失能
TIM_OutputState_Enable 使能

  1. TIM_Pulse,初始CCR值。

下面看看代码吧 ——

void PWM_Init(void)
{Timer_Init();RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);			//开启GPIOB的时钟GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);							//将PA0引脚初始化为复用推挽输出	//受外设控制的引脚,均需要配置为复用模式TIM_OCInitTypeDef TIM_OCInitStructure;							//定义结构体变量TIM_OCStructInit(&TIM_OCInitStructure);                         //结构体初始化,若结构体没有完整赋值//则最好执行此函数,给结构体所有成员都赋一个默认值//避免结构体初值不确定的问题TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;               //输出比较模式,选择PWM模式1TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;       //输出极性,选择为高,若选择极性为低,则输出高低电平取反TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;   //输出使能TIM_OCInitStructure.TIM_Pulse = 0;								//初始的CCR值TIM_OC1Init(TIM2, &TIM_OCInitStructure);
}

第四步、PWM配置CCR的值

需要注意的是 ——

CCR和ARR共同决定占空比,此函数仅设置CCR的值,并不直接是占空比。
占空比 ( D u t y ) = C C R / ( A R R + 1 ) 占空比(Duty) = CCR / (ARR + 1) 占空比(Duty)=CCR/(ARR+1)

void PWM_SetCompare1(uint16_t Compare)
{TIM_SetCompare1(TIM2, Compare);		//设置CCR2的值
}

OK,到这里我们PWM的配置就完成了。

使用PWM实现呼吸灯

下面我们来看看怎么用刚才实现的PWM来做呼吸灯。
TIM的代码可以看上一期的内容 ——
stm32教程:TIM定时器详解 & TIM时钟计时代码模板
里面的Timer.c就按照上面说的改,这里就不放了。其它代码的完整版在下面。

PWM.c

#include "stm32f10x.h"                  // Device header
#include "Timer.h"
#include "PWM.h"void PWM_Init(void)
{Timer_Init();RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);			//开启GPIOB的时钟GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);							//将PA0引脚初始化为复用推挽输出//受外设控制的引脚,均需要配置为复用模式TIM_OCInitTypeDef TIM_OCInitStructure;							//定义结构体变量TIM_OCStructInit(&TIM_OCInitStructure);                         //结构体初始化,若结构体没有完整赋值//则最好执行此函数,给结构体所有成员都赋一个默认值//避免结构体初值不确定的问题TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;               //输出比较模式,选择PWM模式1TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;       //输出极性,选择为高,若选择极性为低,则输出高低电平取反TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;   //输出使能TIM_OCInitStructure.TIM_Pulse = 0;								//初始的CCR值TIM_OC1Init(TIM2, &TIM_OCInitStructure);
}void PWM_SetCompare1(uint16_t Compare)
{TIM_SetCompare1(TIM2, Compare);		//设置CCR2的值
}

PWM.h

#ifndef __PWM_H
#define __PWM_Hvoid PWM_Init(void);
void PWM_SetCompare1(uint16_t Compare);#endif

main.c

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"
#include "PWM.h"uint16_t i = 0;int main()
{OLED_Init();//函数定义初始化PWM_Init();while(1){for (i = 0; i <= 100; i++){PWM_SetCompare1(i);			//依次将定时器的CCR寄存器设置为0~100,PWM占空比逐渐增大,LED逐渐变亮Delay_ms(10);				//延时10ms}for (i = 0; i <= 100; i++){PWM_SetCompare1(100 - i);	//依次将定时器的CCR寄存器设置为100~0,PWM占空比逐渐减小,LED逐渐变暗Delay_ms(10);				//延时10ms}}}

总结

OKK,这一期的内容就这么多,其实还是容易的对吧。
如果需要工程的文件的可以私信我,或者在评论区里留言,我都会提供。

感谢大伙观看,别忘了三连支持一下

大家也可以关注一下我的其它专栏,同样精彩喔~

下期见咯~

在这里插入图片描述

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词