STM32中使用PWM实现呼吸灯

个人理解:如果能实现电压的变化就能实现呼吸灯了,如果能得到一个类似正弦电压的电压,那么就能实现这个呼吸灯。那么问题就来了,该怎么得到这个类似正弦电压的电压?STM32中的PWM能做到这个。接下来我说下我是怎么通过这个PWM来实现呼吸灯的。

硬件的准备就不说了,想实现呼吸灯的你这个硬件配置肯定是莫得问题。我重点说下这个PWM的配置,即怎么用代码来实现这个PWM。

STM32中有8个定时器,其中两个高级定时器,两个基本定时器和4个通用定时器。我们通过使用通用定时器TIM3来配置PWM,其中TIM3有四个通道,我们选择使用通道2。

我们接下来配置的PWM的相关函数设置在库函数文件stm32f10x_tim.h和stm32f10x_tim.c文件中。

Step1

要使用TIM3,我们必须先开启TIM3的时钟。库函数使能TIM3时钟的方法是:

RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);

还有一个,开启AFIO时钟:

RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); 

Step2

TIM3_CH2是默认接在PA7上的,在这里我不想它在PA7上,那我们就要重映射了。我重映射到PB5上,配置如下:

GPIO_InitTypeDef GPIO_InitStructure; 
GPIO_PinRemapConfig(GPIO_PartialRemap_TIM3, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure); 

Step3

初始化TIM3的arr和psc:

TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_TimeBaseStructure.TIM_Period = arr; //设置自动重装载值
TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置预分频值
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); 

Step4

设置TIM3_CH2的PWM模式,使TIM3的CH2输出。

TIM_OCInitTypeDef TIM_OCInitStructure;
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //选择 PWM 模式 2
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //输出极性高
TIM_OC2Init(TIM3, &TIM_OCInitStructure); //初始化 TIM3 OC2 

Step5

使能TIM3:

TIM_Cmd(TIM3, ENABLE); 

Step6

修改TIM3_CCR2来控制占空比,下面给出函数形式。这个使关键之处,就是靠这个来实现电压的变化。

void TIM_SetCompare2(TIM_TypeDef* TIMx, uint16_t Compare2)

好了,讲配置到这基本也结束了。上面都是一些主要的配置,到这这个PWM基本完成,但上面是分步讲解,接下面我给出完整的配置过程的代码。
文件名:timer.c

#include "timer.h"
void TIM3_PWM_Init(uint16_t arr,uint16_t psc)
{
 GPIO_InitTypeDef GPIO_InitStructure;
 TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
 TIM_OCInitTypeDef TIM_OCInitStructure;
 
 RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|
 RCC_APB2Periph_AFIO, ENABLE);
 GPIO_PinRemapConfig(GPIO_PartialRemap_TIM3, ENABLE);

 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
 GPIO_Init(GPIOB, &GPIO_InitStructure);
 
 TIM_TimeBaseStructure.TIM_Period = arr;
 TIM_TimeBaseStructure.TIM_Prescaler =psc;
 TIM_TimeBaseStructure.TIM_ClockDivision = 0;
 TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
 TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);

 TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;
 TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
 TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
 
 TIM_OC2Init(TIM3, &TIM_OCInitStructure);
 TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable);
 
 TIM_Cmd(TIM3, ENABLE); 
}

上面就是完整的配置了。还有个timer.h文件。这个就是一些声明,这个简单,你应该会,但保险起见,我还是一起给出来吧。
文件timer.h

#ifndef __TIMER_H__
#define __TIMER_H__
#include <stdint.h>
#include <stm32f10x_tim.h>
#include <stm32f10x_gpio.h>
void TIM3_PWM_Init(uint16_t arr,uint16_t psc);
#endif

好了!完成。全部的配置结束。接下来的使用就靠那个函数了。在第六步。使用我就不多说了,按照它函数的格式就ok了。
我还是给出一个例子吧。。。。

TIM_SetCompare2(TIM3,temp);

另外有个要注意的点,temp的取值范围0-899。根据你的灯去设置你的最大值。然后这个temp应该是个变值。你来个循环,ok!

看到这,属于你的呼吸灯已经完成!!享受这个完成之后的快乐吧!一种非常美妙的感觉。

猜你喜欢

转载自blog.csdn.net/qq_44323019/article/details/101936138