STM32F1开发指南笔记15----定时器产生PWM输出——呼吸灯2

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

main函数

#include "led.h"
#include "delay.h"
#include "key.h"
#include "sys.h"
#include "usart.h"
#include "timer.h"
 	
int main(void)
 {		
 	u16 led0pwmval=0;
	u8 dir=1;	
	delay_init();	    	 //延时函数初始化	  
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置NVIC中断分组2:2位抢占优先级,2位响应优先级
 	LED_Init();			     //LED端口初始化
 	TIM3_PWM_Init(899,0);	 //不分频。PWM频率=72000000/900=80Khz
   	
	 while(1)
	{
 		delay_ms(10);	 
		if(dir)led0pwmval++;
		else led0pwmval--;

 		if(led0pwmval>300)dir=0;
		if(led0pwmval==0)dir=1;										 
		TIM_SetCompare2(TIM3,led0pwmval);		   
	}	 
 }

timer.c函数

#include "timer.h"
#include "led.h"
#include "usart.h"

//TIM3 PWM部分初始化 
//PWM输出初始化
//arr:自动重装值
//psc:时钟预分频数
void TIM3_PWM_Init(u16 arr,u16 psc)
{  
	//定义结构体变量
	GPIO_InitTypeDef GPIO_InitStructure;
	TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
	TIM_OCInitTypeDef  TIM_OCInitStructure;
	
	//使能定时器3时钟,使能GPIO外设和AFIO复用功能模块时钟
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);	
 	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB  | RCC_APB2Periph_AFIO, ENABLE);  
	
	//Timer3部分重映射  TIM3_CH2->PB5
	GPIO_PinRemapConfig(GPIO_PartialRemap_TIM3, ENABLE);     
 
   //设置该引脚为复用输出功能,输出TIM3 CH2的PWM脉冲波形	GPIOB.5
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; //TIM_CH2
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  //复用推挽输出
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化GPIO
 
   //初始化TIM3
	TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值
	TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值 
	TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_tim
	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数模式
	TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位
	
	//初始化TIM3 Channel2 PWM模式	 
	TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //选择定时器模式:TIM脉冲宽度调制模式2
 	TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
	TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //输出极性:TIM输出比较极性高
	TIM_OC2Init(TIM3, &TIM_OCInitStructure);  //根据T指定的参数初始化外设TIM3 OC2

	//使能TIM3在CCR2上的预装载寄存器
	TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable);  
 
	//使能TIM3
	TIM_Cmd(TIM3, ENABLE);  
}

代码解析

从死循环函数可以看出,我们将 led0pwmval 这个值设置为 PWM 比较值(低于这个值输出低电平,高于这个值输出高电平),也就是通过 led0pwmval 来控制 PWM 的占空比,然后控制 led0pwmval 的值从 0 变到 300,然后又从 300 变到 0,如此循环,因此 DS0 的亮度也会跟着从暗变到亮,然后又从亮变到暗。至于这里的值,我们为什么取 300,是因为 PWM 的输出占空比达到这个值的时候,我们的 LED 亮度变化就不大了(虽然最大值可以设置到 899),因此设计过大的值在这里是没必要的。至此,我们的软件设计就完成了。

对比延时函数实现的呼吸灯

前面写过一份关于呼吸灯的实现代码,那个是根据延时函数来实现的效果,利用灯的亮/灭时间的不同来控制显示灯的亮度。方法简单,但是实际项目过程中不可取,因为延时函数实现的呼吸灯会一直浪费CPU资源。而利用定时器产生PWM输出则可以节约CPU资源。

补充定时器PWM初始化时的模式设置和极性设置

TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; 模式设置
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; 极性设置
在这里插入图片描述
在这里插入图片描述

由此可知,(PWM2和High)以上代码设置含义为:当计数值CNT小于CCR比较值时为低电平0,当CNT大于CCR时为高电平。
通过改变PWM模式和极性即可改变PWM波形。

发布了34 篇原创文章 · 获赞 1 · 访问量 1418

猜你喜欢

转载自blog.csdn.net/qq_38958704/article/details/105475516