至于STM32的PWM的基本知识,博客 STM32——PWM基本知识及配置过程已经说的非常清楚了,这里再说明一下PWM的频率和占空比计算
- 首先要搞清楚单片机的时钟树,搞清楚TIM的时钟来源以及具体时钟频率,这里以TIM2CH4为例,假设时钟来源为内部时钟HSI,最终到APB1的时钟为8M,TIM2的时钟也为8M
- 其次,搞明白PWM的计算公式,PWM的周期由ARR决定,定时器的计数器跑完一个(ARR+1)即为一个PWM周期,而计数器的计数单位时间为(PSC+1)/8M

- 计算,假设PWM周期设置为20ms即50Hz,
,假设PSC=7,则计数器计数单位为1us,再将ARR+1设置为20 000,20ms = (ARR+1)*[(PSC+1)/8M]
即设置PWM周期20ms1us*20 000=20ms
- PWM的占空比与CCRx和ARR寄存器有关,ARR决定CCRx的最大值,CCRx使用
设置TIM_SetComparex
-
备注
在实际操作中,因为单片机焊接了外部晶振8M,以为定时器的APB1时钟频率为72M,再怎么计算修改寄存器值,输出的PWM都不对,后来才发现单片机默认使用的是内部时钟源!
- 代码实例
void TIM2_PWM_Init() { GPIO_InitTypeDef GPIO_InitStructure; TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_OCInitTypeDef TIM_OCInitStructure; RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA , ENABLE); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); TIM_TimeBaseStructure.TIM_Period = 20000-1; //arr 20000*1us=20ms TIM_TimeBaseStructure.TIM_Prescaler = 8-1;//psc 8/8M =1us TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1; TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;//PWM模式1:CNT<CCR时输出有效 TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = 0;//TIM_SetCompare TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;//设置极性-有效为高电平 TIM_OC4Init(TIM2, &TIM_OCInitStructure); TIM_CtrlPWMOutputs(TIM2,ENABLE); TIM_OC4PreloadConfig(TIM2, TIM_OCPreload_Enable); TIM_ARRPreloadConfig(TIM2, ENABLE); TIM_Cmd(TIM2, ENABLE); } TIM_SetCompare4(TIM2,10000);//20ms 50%占空比