自认为在STM32的学习中,通用定时器这一块是一个难点,因为配置的过程繁杂,难以记忆。而且因为STM32 功能的强大与丰富,涉及的相关寄存器与时钟源也有许多种。下面做一个简单的总结。
查看STM32F4系列芯片手册通用定时器框图,F3的也一样,框图大同小异。
STM32-通用定时器-PWM输出-总结
从框图上可以看到,STM32通用定时器,用不同颜色的笔给划分了区域,分成了4个部分

  1. 时钟源
  2. 基本定时器
  3. 输入捕获
  4. 输出比较

分成了以上这四个部分:

1.时钟源

计数器时钟可由下列时钟源提供:
● 内部时钟 (CK_INT)
● 外部时钟模式 1:外部输入引脚 (TIx)
● 外部时钟模式 2:外部触发输入 (ETR),仅适用于 TIM2、TIM3 和 TIM4。
● 内部触发输入 (ITRx):使用一个定时器作为另一个定时器的预分频器,例如可以将定时器配置为定时器 2 的预分频器。(定时器的级联)
时钟源框图:
STM32-通用定时器-PWM输出-总结
内部时钟框图(CK_INT)
STM32-通用定时器-PWM输出-总结
如何选择内部时钟作为时钟源?
将TIMx_SMCR 寄存器中 SMS=000,ECE=0,当对 CEN 位写入 1 时,预分频器的时钟就由内部时钟 CK_INT 提供。内部时钟的频率为该定时器所在时钟线频率x2。
**一般常用内部时钟作为时钟源STM32-通用定时器-PWM输出-总结
STM32-通用定时器-PWM输出-总结
外部时钟源模式1框图
STM32-通用定时器-PWM输出-总结
如何选择外部时钟模式1作为时钟源?
当 TIMx_SMCR 寄存器中的 SMS=111 ,ECE=0时,可选择此模式。
选择作为时钟源后,可以通过配置SMCR的TS位来进一步选择时钟来源。
内部触发(其他定时器与之级联,这种级联方式的组合是ST规定的)
STM32-通用定时器-PWM输出-总结
外部时钟源模式2框图
STM32-通用定时器-PWM输出-总结
STM32-通用定时器-PWM输出-总结
如何选择外部时钟模式2作为时钟源?
TIMx_SMCR 寄存器中的ECE位写入 1 可选择此模式。
选择之后,可以使用外部输入的脉冲信号作为定时器的时钟源,通过操作TIMx->SMCR的ETP、ETPS、ETF功能位,可以选择输入信号的极性、分频系数、滤波系数。

** 通用定时器的输出比较(PWM的输出)**
每个通用定时器至少有1个通道,每个通道对应一个IO引脚(若需要使用定时器的输入/输出功能,需要将该引脚复用成定时器通道)。每个通道可以用于输入 或 输出功能。
输出比较:根据计数器和比较寄存器值的大小关系,决定在对应的通道(引脚)上输出特定的电平。

输出比较的框图
STM32-通用定时器-PWM输出-总结
STM32-通用定时器-PWM输出-总结
对于输出比较的配置从这张框图上就能看出,首先

  1. 把通道配置成输出通道。 TIMx->CCMR1 中的 CC1S[0:1] 填00STM32-通用定时器-PWM输出-总结
  2. 关闭CCR1的缓冲功能 ,也就是关闭影子功能。OCIE 清零STM32-通用定时器-PWM输出-总结
  3. 设置输出比较模式为PWM1还是PWM2,TIMx->CCRM1的OC1M[0:2]位STM32-通用定时器-PWM输出-总结
  4. 设置有效电平 是高电平有效还是低电平有效,手册上说的有点绕,这里我的理解,PWM1,有效电平为高电平。PWM2,有效电平为低电平。TIMx->CCER的CC1P位。 STM32-通用定时器-PWM输出-总结
  5. 别忘了使能通道和给设置比较值。STM32-通用定时器-PWM输出-总结STM32-通用定时器-PWM输出-总结

讲完原理,贴代码:
比如:需要使用PWM控制LED亮度,LED1–PF6

明确操作对象,确定需要操作的引脚是TIMxCHn (定时器X的通道n)之后将该引脚复用成此功能 PF6(AF3)–> TIM10CH1

完成TIMx的(基本定时器功能)初始化打开外设时钟、选择时钟源、设定预分频值、重装载值

完成TIMxCHn通道 输出功能配置将该通道配置为输出,关闭CCRn的缓冲功能,对CCRn(捕获/比较寄存器)赋值,设置输出比较模式、设置有效电平,使能该通道

使能计数器

void TIM10_PWM_CH1_Init(u32 psc,u32 arr)
{
	/*********GPIO配置*****************/
	//PF6
	RCC->AHB1ENR |= (1<<5); //打开GPIOF时钟
	
	GPIOF->MODER &=~ (3<<12);//配置成复用模式
	GPIOF->MODER |=  (2<<12);
	
	GPIOF->AFR[0] &=~ (0XF<<24);
	GPIOF->AFR[0] |=  (3<<24);
	
	/*********时基单元配置配置*********/
	RCC->APB2ENR |= (1<<17);//打开TIM10外设时钟
	
	TIM10->SMCR &=~ (7<<0); //选择内部时钟源
	TIM10->SMCR &=~ (1<<14);//禁用外部时钟源
	TIM10->PSC = psc-1;     //预分频 
	TIM10->ARR = arr-1;     //预装载值
	TIM10->CNT = 0;         //计数器清零
	
	/*********PWM输出通道1配置*********/
	TIM10->CCMR1 &=~ (3<<0);//CC1S = 00 通道配置成输出
	TIM10->CCMR1 &=~ (1<<3);//CCIPE  关闭影子功能
	
	TIM10->CCMR1 &=~ (7<<4);//设置该通道的输出模式:PWM模式1 OC1M = 110
	TIM10->CCMR1 |=  (6<<4);
	
	TIM10->CCR1 = arr/2; //设定比较值 CCR1
	
	TIM10->CCER  &=~ (1<<1);//设置该通道输出的有效电平:高电平有效 CC1P = 0
	TIM10->CCER  |=  (1<<0);//使能该通道 CC1E = 1
		
	TIM10->CR1 |= (1<<0);//计数器使能
}

相关文章: