通用定时器产生PWM

一、STM32F103 PWM介绍
STM32F1除了基本定时器TIM6和TIM7,其他定时器都可以产生PWM输出:其中高级定时器 TIM1 和 TIM8 可以同时产生多达 7 路的 PWM 输出,而通用定时器也能同时产生多达 4路的 PWM 输出。
PWM的输出其实就是对外输出脉宽可调(即占空比调节)的方波信号,信号频率是由自动重装寄存器ARR的值决定,占空比由比较寄存器CCR的值决定。
PWM输出比较模式总共有8种,具体由寄存器 CCMRx 的位 OCxM[2:0]配置。这里只讲解最常用的两种PWM输出模式:PWM1和PWM2。PWM1和PWM2这两种模式用法差不多,区别之处就是输出电平的极性不同。
在这里插入图片描述
二、PWM输出配置步骤
(1)使能定时器及端口时钟,并设置引脚复用器映射

RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);	//使能定时器时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);	//使能引脚复用时钟
GPIO_PinRemapConfig(GPIO_FullRemap_TIM3,ENABLE);	//TIM3完全重映射

在这里插入图片描述
(2)初始化相应的GPIO,模式选复用推挽输出
(3)初始化定时器参数,包含自动重装值,分频系数,计数方式等

void TIM_TimeBaseInit(TIM_TypeDef*  TIMx, TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct);  //TIMx为对应的定时器,TIM_TimeBaseInitStruct为配置结构体

(4)初始化PWM输出参数,包含PWM模式、输出极性,使能等

void TIM_OCxInit(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct);	//TIM_OCInitStruct为配置结构体
//TIM_OCInitTypeDef的部分成员
typedef struct{
	uint16_t TIM_OCMode;        //比较输出模式
	uint16_t TIM_OutputState;   //比较输出使能
	uint16_t TIM_OCPolarity;    //输出极性
}TIM_OCInitTypeDef; 	
TIM_OCMode 描述
TIM_OCMode_PWM1 TIM脉宽宽度调制模式1
TIM_OCMode_PWM2 TIM脉宽宽度调制模式2
TIM_OutputState 比较输出使能/失能
TIM_OutputState_Enable 使能
TIM_OutputState_Disable 失能
TIM_OCCPolarity 输出极性
TIM_OCPlarity_High 高电平有效
TIM_OCPlarity_Low 低电平有效

(5)开启定时器

TIM_Cmd(TIM3,ENABLE); //开启定时器

(6)使能TIMx在CCRx上的预装载寄存器

//第一个参数用于选择定时器,第二个参数用于选择使能还是失能输出比较预装载寄存器,可选择为TIM_OCPreload_Enable、TIM_OCPreload_Disable。
void TIM_OCxPreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload);

(7)使能 TIMx 在 ARR 上的预装载寄存器允许位

//第一个参数用于选择定时器,第二个参数用于选择使能还是失能。
void TIM_ARRPreloadConfig(TIM_TypeDef* TIMx, FunctionalState NewState);

(8)修改TIMx_CCRx的值控制占空比

//第一个参数用于选择定时器,第二个参数用于控制占空比
void TIM_SetCompare1(TIM_TypeDef* TIMx, uint32_t Compare1); 

三、总结写法如下

/******************************
函数名:void TIM3_PWM_Init(u16 pre,u16 psc);
参数:pre为周期,psc为预分频
功能:使用通用定时器TIM3产生四路pwm,因使用完全重映射,故输出引脚分别为PC6、PC7、PC8、PC9
*******************************/
void TIM3_PWM_Init(u16 pre,u16 psc){
	GPIO_InitTypeDef GPIO_initStructure;			//GPIO配置结构体
	TIM_TimeBaseInitTypeDef TIM_InitStructure;		//定时器配置结构体
	TIM_OCInitTypeDef TIM_OCInitTypeDefStructure;		//PWM输出参数配置结构体
	
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);	//使能定时器时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);	//使能GPIOC时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);	//使能复用功能时钟
	
	GPIO_initStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7|GPIO_Pin_8|GPIO_Pin_9;
	GPIO_initStructure.GPIO_Mode = GPIO_Mode_AF_PP;		//复用推挽输出
	GPIO_initStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOC,&GPIO_initStructure);			//初始化GPIO
	
	GPIO_PinRemapConfig(GPIO_FullRemap_TIM3,ENABLE);	//复用使能,完全重映射
	
	TIM_InitStructure.TIM_Period = pre;			//定时器周期
	TIM_InitStructure.TIM_Prescaler = psc;			//定时器预分频器
	TIM_InitStructure.TIM_ClockDivision = TIM_CKD_DIV1;	//时钟分频
	TIM_InitStructure.TIM_CounterMode = TIM_CounterMode_Up;	//计数模式
	TIM_TimeBaseInit(TIM3,&TIM_InitStructure);		//初始化TIM3
	
	TIM_OCInitTypeDefStructure.TIM_OCMode = TIM_OCMode_PWM1;		//PWM输出模式
	TIM_OCInitTypeDefStructure.TIM_OCPolarity = TIM_OCPolarity_High;		//输出极性,根据实际需要更改
	TIM_OCInitTypeDefStructure.TIM_OutputState = TIM_OutputState_Enable;	//使能比较输出
	
	TIM_OC1Init(TIM3,&TIM_OCInitTypeDefStructure);		//初始化通道1PWM输出
	TIM_OC2Init(TIM3,&TIM_OCInitTypeDefStructure);  	//初始化通道2PWM输出
	TIM_OC3Init(TIM3,&TIM_OCInitTypeDefStructure);  	//初始化通道3PWM输出
	TIM_OC4Init(TIM3,&TIM_OCInitTypeDefStructure);  	//初始化通道4PWM输出
	
	TIM_OC1PreloadConfig(TIM3,TIM_OCPreload_Enable);	//使能TIM3在CCR1上的预装载寄存器
	TIM_OC2PreloadConfig(TIM3,TIM_OCPreload_Enable);	//使能TIM3在CCR2上的预装载寄存器
	TIM_OC3PreloadConfig(TIM3,TIM_OCPreload_Enable); 	//使能TIM3在CCR3上的预装载寄存器
	TIM_OC4PreloadConfig(TIM3,TIM_OCPreload_Enable); 	//使能TIM3在CCR4上的预装载寄存器
	TIM_ARRPreloadConfig(TIM3,ENABLE); 			//使能 TIMx 在 ARR 上的预装载寄存器允许位
	
	TIM_Cmd(TIM3,ENABLE);					//开启定时器
}	
//在main中调用函数修改占空比
void TIM_SetCompare1(TIM_TypeDef* TIMx, uint32_t Compare1);	//修改通道1占空比
void TIM_SetCompare2(TIM_TypeDef* TIMx, uint32_t Compare2); 	//修改通道2占空比
void TIM_SetCompare3(TIM_TypeDef* TIMx, uint32_t Compare3); 	//修改通道3占空比
void TIM_SetCompare4(TIM_TypeDef* TIMx, uint32_t Compare4); 	//修改通道4占空比

占空比计算: 占空比 = Compare1 / pre * 100%

发布了8 篇原创文章 · 获赞 6 · 访问量 1167

猜你喜欢

转载自blog.csdn.net/weixin_44762713/article/details/103882803