STM32 PWM配置及呼吸灯

        PWM的英文全称是"Pulse Width Modulation"中文翻译为"脉冲宽度调制"

        在PWM中可以调节的其实只有两个东西一个叫做可调周期(调频率)另一个叫做占空比(高电平/周期)。

        而呼吸灯其实就是改变流经二极管的平均电流也就是说当周期一定的情况下流经二极管的高电平发生改变。

STM32 PWM配置及呼吸灯_第1张图片

        反之,倒回去,灯就会由暗变亮。 

        由此可以看出其周期不需要改变,只需要改变其占空比。

        我们假设LED灯在PA1上,那么我们需要配置两个东西,一个是GPIO_PA1一个是TIM2_PWM。所以我们要注意PA口的时钟,和TIM2挂在哪个总线上,需要先把这两个外设时钟打开。

        查看STM32F103xx performance line block diagram(性能线路框图)

STM32 PWM配置及呼吸灯_第2张图片STM32 PWM配置及呼吸灯_第3张图片

         可以看到GPIOA挂到了APB2上,TIM2挂到了APB1上。所以我们做的第一件事就是开启GPIOA和TIM2的时钟。

        打开库函数手册

STM32 PWM配置及呼吸灯_第4张图片

 STM32 PWM配置及呼吸灯_第5张图片

 //1.打开外设时钟

void TIM2_PWM_Configarution(void)
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
}

        从STM32F103xx pin definitions可以看到PA1有个复用功能TIM2_CH2。我们要把GPIOA_Pin_1配置成复用功能。

STM32 PWM配置及呼吸灯_第6张图片

 //2.配置GPIO口

void TIM2_PWM_Configarution(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);

	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_1;
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;
	GPIO_Init(GPIOA,&GPIO_InitStructure);

}

//3.设置周期

void TIM2_PWM_Configarution(void)
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
	
	GPIO_InitTypeDef GPIO_InitStructure;
	TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
	
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_1;
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;
	GPIO_Init(GPIOA,&GPIO_InitStructure);
	
	TIM_TimeBaseStructure.TIM_Period = 19999;
	TIM_TimeBaseStructure.TIM_Prescaler = 71;  
	//TIM_TimeBaseStructure.TIM_ClockDivision = 0x0;
	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
	TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);

}

        PWM工作的时候,有一个中间的比较值,例如PWM的计数是从0~100,设置中间比较值为50。假设现在值是1,它就会和50比较,因为它是向上计数,所以1++变为2,当增加到比较值的时候,电平会发生改变。而模式1和模式2就是决定初始的电平。

如果是PWM1模式

a)如果设置TIM_OCPolarity_High:

TIMx_CNT

TIMx_CNT>TIMx_CCR输出为低电平

b)如果设置TIM_OCPolarity_Low:

TIMx_CNT

TIMx_CNT>TIMx_CCR输出为高电平

如果是PWM2模式

a)如果设置TIM_OCPolarity_High:

TIMx_CNT

TIMx_CNT>TIMx_CCR输出为高电平

b)如果设置TIM_OCPolarity_Low:

TIMx_CNT

TIMx_CNT>TIMx_CCR输出为低电平

//4.输出比较功能 

void TIM2_PWM_Configarution(void)
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
	
	GPIO_InitTypeDef GPIO_InitStructure;
	TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
	TIM_OCInitTypeDef TIM_OCInitStructure; 
	
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_1;
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;
	GPIO_Init(GPIOA,&GPIO_InitStructure);
	
	TIM_TimeBaseStructure.TIM_Period = 19999;
	TIM_TimeBaseStructure.TIM_Prescaler = 71;  //71+1= 72·ÖƵ
	//TIM_TimeBaseStructure.TIM_ClockDivision = 0x0;
	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
	TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
	

	TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; 
	TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; 
	TIM_OCInitStructure.TIM_OutputState = TIM_OutputNState_Enable;
	TIM_OC2Init(TIM2, & TIM_OCInitStructure);
	
	TIM_Cmd(TIM2, ENABLE);
}

 main.c

#include "bsp_SysTick.h"
#include "bsp_tim2.h"

int main(void)
{
	int i;
	
	SysTick_Configuration();
	
	TIM2_PWM_Configuration();	
	
	while(1)
	{
		for(i = 0; i < 20000; i++)
		{
			TIM_SetCompare2(TIM2, i);
			Delay_us(50);
		}
		for(i = 20000; i>0; i--)
		{
			TIM_SetCompare2(TIM2, i);
			Delay_us(50);
		}
	}
}

你可能感兴趣的:(1024程序员节,stm32,嵌入式硬件,单片机,c语言,c++,学习)