目录:
一、引脚映像与寄存器
1、定时器引脚复用功能映像
2、定时器
1)定时器介绍 2)定时器时钟分割
二、定时器PWM产生原理
三、STM32产生PWM的配置
一、引脚映像与寄存器
1、定时器引脚复用功能映像
2、定时器
1)定时器介绍
STM32中一共有11个定时器,其中TIM6、TIM7是基本定时器;TIM2、TIM3、TIM4、TIM5是通用定时器;TIM1和TIM8是高级定时器,以及2个看门狗定时器和1个系统嘀嗒定时器SysTick。
其中TIM1和TIM8能够产生3对WM互补输出,常用于三相电机的驱动,时钟由APB2的输出产生;
TIM2~TIM5是普通定时器,TIM6和TIM7是基本定时器,其时钟由APB1输出产生。
--------------------------------
2)定时器时钟分割
这三种不同的采样频率基准是通过设置控制寄存器TIMx_CR1中的CKD(时钟分频因子)来实现的,手册上有详细的说明:
TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_tim
//等同于
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //设置时钟分割:TDTS = Tck_tim
STM32的定时器输入通道都有一个滤波单元,分别位于每个输入通路上和外部触发输入通路上,它们的作用是滤除输入信号上的高频干扰。
二、定时器PWM产生原理
通用定时器可以利用GPIO引脚进行脉冲输出,配置为比较输出、PWM输出功能时,捕获/比较寄存器TIMx_CCR被用作比较功能,下面把它简称为比较寄存器。
举例说明定时器的PWM输出工作过程:
若配置脉冲计数器TIMx_CNT为向上计数,而重载寄存器TIMx_ARR被配置为N,即TIMx_CNT的当前计数值数值X在TIMxCLK时钟源的驱动下不断累加,当TIMx_CNT的数值X大于N时,会重置TIMx_CNT数值为0重新计数。
而在TIMx_CNT计数的同时,TIMx_CNT计数值X会与比较寄存器TIMx_CCR预先存储的数值A进行比较,当脉冲计数器TIMx_CNT的数值X小于比较寄存器TIMx_CCR的值A时,输出高电平(低电平);反之,当脉冲计数器的数值X大于或等于比较寄存器的值A时,输出低电平(高电平)。
如此循环,得到的输出脉冲周期就为重载寄存器TIMx_ARR存储的数值(N+1)乘以触发脉冲的时钟周期,其脉冲宽度则为比较寄存器TIMx_CCR的值A乘以触发脉冲的时钟周期,输出PWM占空比:A/(N+1) 。
三、STM32产生PWM的配置
根据以上重映像表,我们使用定时器3的通道2作为PWM的输出引脚,所以需要对PB5引脚进行配置。
1、IO口操作代码
GPIO_InitTypeDef GPIO_InitStructure; //定义结构体
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO, ENABLE);
//使能GPIO外设和AFIO复用功能模块时钟
GPIO_PinRemapConfig(GPIO_PartialRemap_TIM3, ENABLE); //选择Timer3部分重映像
//选择定时器3的通道2作为PWM的输出引脚TIM3_CH2->PB5 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); //初始化引脚
2、初始化定时器
void TIM3_PWM_Init(u16 arr,u16 psc)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; //定义初始化结构体
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //使能定时器3时钟
//初始化TIM3
TIM_TimeBaseStructure.TIM_Period = arr; //自动重装载寄存器值
TIM_TimeBaseStructure.TIM_Prescaler =psc; //TIMx预分频值
TIM_TimeBaseStructure.TIM_ClockDivision = 0; //时钟分割
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //向上计数
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //根据以上功能对定时器进行初始化
}
3、设置TIM3_CH2的PWM模式,使能TIM3的CH2输出
TIM_OCInitTypeDef TIM_OCInitStructure; //定义结构体
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //选择定时器模式,TIM脉冲宽度调制模式2
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; //输出比较极性低
TIM_OC2Init(TIM3, &TIM_OCInitStructure); //根据结构体信息进行初始化
TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable); //使能定时器TIM2在CCR2上的预装载值
4、使能定时器3
TIM_Cmd(TIM3, ENABLE); //使能定时器TIM3
经过以上的操作,定时器3的第二通道已经可以正常工作并输出PWM波了,只是其占空比和频率固定,可以通过改变TIM3_CCR2控制占空比。修改占空比的函数:TIM_SetCompare2(TIM3,n); n不同,占空比不同。
5、修改pwm波形的占空比
编写一个函数:void TIM3_PWM_Init(u16 arr,u16 psc);将以上所有的代码都加进来这个函数中,只要在main函数中调用该函数进行初始化,然后使用TIM_SetCompare2()函数修改PWM的占空比就可以在PB5脚得到需要的PWM波形了。
int main(void)
{
TIM3_PWM_Init(9999,143); //频率=72*10^6/(9999+1)/(143+1)=50Hz
TIM_SetCompare2(TIM3,4999); //得到占空比为50%的PWM波形
while(1);
}
竹坞无尘水槛清,相思迢递隔重城。秋阴不散霜飞晚,留得残荷听雨声。觉得不错,动动发财的小手点个赞哦!