1_STM32定时器输出5路PWM

一、STM32定时器简介

STM32共有8个定时器,TIM1~TIM8。包括两个高级控制定时器,TIM1和TIM8;四个通用计时器,TIM2、TIM3、TIM4、TIM5;两个基本定时器,TIM6、TIM7。
其中除了TIM6和TIM7以外的其他定时器都可用来产生PWM输出。而每个高级控制定时器有7个通道,每个通用计时器也有4个通道,因此最多可以同时产生 30 路 PWM 输出。

二、此例简介

完成的功能:简单地使用多个定时器输出5路pwm
芯片:STM32F103RCT6
硬件:5个小灯,正点原子mini开发板

三、代码

1.main函数

 int main(void)
 {
	  delay_init();            //延时函数初始化    	 
   
	  TIM2_PWM_Init(899,1);     //定时器2初始化
	  TIM3_PWM_Init(899,1);     //定时器3初始化
	  TIM4_PWM_Init(899,1);     //定时器4初始化
	  TIM5_PWM_Init(899,1);     //定时器5初始化

	 TIM_SetCompare3(TIM2,90);  //PA2,90%的亮度 
	 TIM_SetCompare4(TIM2,180);//PA3,80%的亮度
	 TIM_SetCompare2(TIM3,360); //PA7,60%的亮度
	 TIM_SetCompare1(TIM4,540);//PB6,40%的亮度
	 TIM_SetCompare2(TIM5,720);//PA1,20%的亮度
	 
	 delay_ms(100);

}

2.定时器初始化函数(以定时器二为例)

void TIM2_PWM_Init(u16 arr,u16 psc)
{  
	GPIO_InitTypeDef GPIO_InitStructure;
	TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
	TIM_OCInitTypeDef  TIM_OCInitStructure;

	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);  //使能定时器时钟2 
 	RCC_APB1PeriphClockCmd(RCC_APB2Periph_GPIOA , ENABLE);  //使能GPIOA

	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3|GPIO_Pin_2; //使能TIM2的CH3和CH4
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  //复用推挽输出
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);

	TIM_TimeBaseStructure.TIM_Period = arr; //
	TIM_TimeBaseStructure.TIM_Prescaler =psc; //
	TIM_TimeBaseStructure.TIM_ClockDivision = 0; //一般设置为0
	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //向上计数模式
	TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); 

	TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //脉冲宽度调制模式2
	TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
	TIM_OCInitStructure.TIM_Pulse = 0; //CCR初始值
	TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //有效电平为高电平
	TIM_OC4Init(TIM2, &TIM_OCInitStructure);  //根据参数初始化TIM2的通道4
	TIM_OC3Init(TIM2, &TIM_OCInitStructure); //根据参数初始化TIM2的通道3

    TIM_CtrlPWMOutputs(TIM2,ENABLE);	//定时器2输出使能	

	TIM_OC3PreloadConfig(TIM2, TIM_OCPreload_Enable);  //CH3预转载使能	
	TIM_OC4PreloadConfig(TIM2, TIM_OCPreload_Enable);//CH4预转载使能
	
	TIM_ARRPreloadConfig(TIM2, ENABLE); //使能TIM2的ARR预装载寄存器

	TIM_Cmd(TIM2, ENABLE);  //使能TIM2
}

3.比较输出函数

void TIM_SetCompare3(TIM_TypeDef* TIMx, uint16_t Compare3)
{
	assert_param(IS_TIM_LIST3_PERIPH(TIMx));//assert_param这个函数是用于检测传递给函数的参数是否是有效的参数
  	TIMx->CCR3 = Compare3; //将参数Compare3写入TIMx结构体中的成员CCR3
}

###########################################
注释:
1️⃣为什么执行TIM_SetCompare3(TIM2,90);输出的就是90%的亮度?
先解释一下PWM输出的频率,执行语句TIM2_PWM_Init(899,1);即把arr的值设置为899,psc设置为1(2分频),那么定时器输出PWM的频率为72MHz÷[(psc+1)×(arr+1)]=72MHz÷[(899+1)×(1+1)]=40000Hz,这个频率只要大于50Hz即可。因为大于50Hz时,人眼就感觉不到灯在闪烁。频率与亮度无关。
跟亮度有关的是脉冲宽度,在程序中,我们设置:
高电平为有效电平(TIM_OCInitStructure.TIM_OCPolarity=TIM_OCPolarity_High;),
PWM模式为模式二(TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;),
向上计数模式(TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;),
CCR的值为90(TIM_SetCompare3(TIM2,90);),
CNT在0~899(ARR值)之间计数,当CNT>90(CCR值)时,输出高电平,此时高电平有效,故开始点亮LED。也就是说,只在0到90之间,LED灭,在90到900,LED亮,有效电平的脉冲宽度就为:(900-90)/900=90%,那么在高频率的闪烁中LED的亮度就为90% .
2️⃣PWM输出模式不只有上面的这种,可以很灵活
在这里插入图片描述
这时候如果设置有效电平为高电平,那么输出的就是高电平;设置的电平是低电平,那么输出的就是低电平。
3️⃣几个小细节
我在使用多个定时器时,其初始化函数都是复制粘贴,但就犯了几个错误,找了几天😭
(1)TIM_SetCompareX(TIM_TypeDef* TIMx, uint16_t Compare3)中的X是表示通道X,如果用的是通道3,那么就要写成TIM_SetCompare3.
(2)TIM_OCXInit(TIM2, &TIM_OCInitStructure);
TIM_OCXPreloadConfig(TIM2, TIM_OCPreload_Enable);
这两处也是,如果用的是通道3,那么就要写成TIM_OC3Init(TIM2, &TIM_OCInitStructure); 以及TIM_OC3PreloadConfig(TIM2, TIM_OCPreload_Enable);.

四、调光效果

从左往右亮度分别为20%,40%,60%,80%,90%。
他

五、附录

程序1、STM32定时器简单输出5路PWM,控制5个小灯呈现5种亮度

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值