上文学习了PWM的基本概述,和PWM的各种参数,本文 学习使用PWM信号去驱动LED实现呼吸灯的效果。
1、PWM驱动LED呼吸灯
1.1介绍
目标:单片机输出一个PWM信号,驱动LED呼吸亮灭。PWM占空比高,则LED更亮;PWM占空比低,则LED更暗;
如下图为实物连接图,在PA0引脚输出PWM信号。
1.2程序运行思路分析:
1)打开时钟(TIM和GPIO的时钟)
2)初始化GPIO(指定某个引脚输出PWM信号)
3)初始化定时器时基单元,(为了设置定时器参数,如频率,计数模式,ARR自动重装值,PSC预分频器等)
4)初始化定时器输出比较,(配置某个定时器的某个通道,模式,极性,使能,和CCR捕获比较寄存器)
5)开启定时器
6)函数调用
1.3程序
下图的程序为输出50%占空比PWM 信号。使用时,直接在主函数,调用PWM_Init ();
void PWM_Init (void)
{
RCC_APB1PeriphClockCmd (RCC_APB1Periph_TIM2,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
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);
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV1;//
TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up; //向上计数模式
TIM_TimeBaseInitStruct.TIM_Period = 100-1; //ARR
TIM_TimeBaseInitStruct.TIM_Prescaler = 720-1; //PSC
TIM_TimeBaseInitStruct.TIM_RepetitionCounter = 0;
TIM_TimeBaseInit(TIM2,&TIM_TimeBaseInitStruct);
TIM_OCInitTypeDef TIM_OCInitStructure;
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 ,ARR,PSC,CCR,共同设置PWM的占空比
TIM_OC1Init(TIM2,&TIM_OCInitStructure);
TIM_Cmd(TIM1,ENABLE);
}
若要设置不断更改PWM占空比,则需要调用更改CCR的函数TIM_SetCompare1,
然后再在主函数中调用函数,写入自己想要的值,
如:在主函数中调用,功能为,更改CCR 的值从小变大,再从大变小,不断循环。
运行LED效果:变亮变暗不断循环,实现呼吸灯效果
void PWM_SetCompare(uint16_t Compare1)
{
TIM_SetCompare1(TIM2,Compare1);
}
//以上是调用的函数
//下面可以在主函数中调用,功能为,更改CCR 的值从小变大,再从大变小,不断循环
while(1)
{
for (i=0;i <= 100;i++)
{
PWM_SetCompare(i);
Delay_ms(10);
}
for (i=0;i <= 100;i++)
{
PWM_SetCompare(100-i);
Delay_ms(10);
}
}
2、程序功能解释
2.1、PWM输出流程图
系统时钟频率出来,经过预分频器和自动重装器,可输出固定频率的信号,
设计计数模式,如图中的向上计数模式,从0计数到ARR,再自动重装为0,不断循环。
当经过比较器的时候,比较计数值CNT与CCR的值,选择比较的模式(PWM1和PWM2),如PWM1模式:CNT<CCR,则输出高电平。
如此经过比较器后,就输出高低电平不同宽度的PWM波形了。
2.2、PWM占空比计算
计算PWM占空比的计算方式为:如图为输出50%PWM信号,1KHZ。
2.3、时基单元初始化函数
TIM_TimeBaseInit函数,TIM_TimeBaseInitTypeDef结构体参数有:
TIM_Prescaler,预分频器值,也就是PSC值。
TIM_CounterMode,计数模式,一般为向上计数模式,
TIM_Period,自动重装值,ARR.
TIM_ClockDivision,预分频,多少分频,对72MHZ的频率进行除法,一分频则不变。
TIM_RepetitionCounter,不太理解,给的是0
2.4输出比较初始化函数
以上函数是用来配置输出比较模块的,每个函数对应一个定时器的通道,配合结构体使用。
TIM_OCInitTypeDef,结构体参数有:
TIM_OCMode:输出比较模式,PWM应用中就PWM1和PWM2两种模式,其他有冻结/有效/无效/反转等用不到的模式。
TIM_OutputState:输出使能
TIM_OutputNState:输出失能
TIM_Pulse:比较器值CCR, 0x0000 and 0xFFFF之间的值。
TIM_OCPolarity:极性,TIM_OCNPolarity_High,TIM_OCNPolarity_Low
TIM_OCNPolarity:同上
TIM_OCIdleState:未理解,没用到
TIM_OCNIdleState:未理解,没用到
如上面几个在程序中未用到的参数,就可以调用函数TIM_OCStructInit(&TIM_OCInitStructure);,给他们统一赋初始值。
下图为输出比较模式的详解图:
2.5设置CCR值
以上函数是用来更改占空比的,调整CCR的值来改变占空比,
参考:
PWM原理 PWM频率与占空比详解
PWM详解(嵌入式学习)
STM32入门教程-2023版 细致讲解 中文字幕