自认为在STM32的学习中,通用定时器这一块是一个难点,因为配置的过程繁杂,难以记忆。而且因为STM32 功能的强大与丰富,涉及的相关寄存器与时钟源也有许多种。下面做一个简单的总结。
查看STM32F4系列芯片手册通用定时器框图,F3的也一样,框图大同小异。
从框图上可以看到,STM32通用定时器,用不同颜色的笔给划分了区域,分成了4个部分
- 时钟源
- 基本定时器
- 输入捕获
- 输出比较
分成了以上这四个部分:
1.时钟源
计数器时钟可由下列时钟源提供:
● 内部时钟 (CK_INT)
● 外部时钟模式 1:外部输入引脚 (TIx)
● 外部时钟模式 2:外部触发输入 (ETR),仅适用于 TIM2、TIM3 和 TIM4。
● 内部触发输入 (ITRx):使用一个定时器作为另一个定时器的预分频器,例如可以将定时器配置为定时器 2 的预分频器。(定时器的级联)
时钟源框图:
内部时钟框图(CK_INT)
如何选择内部时钟作为时钟源?
将TIMx_SMCR 寄存器中 SMS=000,ECE=0,当对 CEN 位写入 1 时,预分频器的时钟就由内部时钟 CK_INT 提供。内部时钟的频率为该定时器所在时钟线频率x2。
**一般常用内部时钟作为时钟源
外部时钟源模式1框图
如何选择外部时钟模式1作为时钟源?
当 TIMx_SMCR 寄存器中的 SMS=111 ,ECE=0时,可选择此模式。
选择作为时钟源后,可以通过配置SMCR的TS位来进一步选择时钟来源。
内部触发(其他定时器与之级联,这种级联方式的组合是ST规定的)
外部时钟源模式2框图
如何选择外部时钟模式2作为时钟源?
TIMx_SMCR 寄存器中的ECE位写入 1 可选择此模式。
选择之后,可以使用外部输入的脉冲信号作为定时器的时钟源,通过操作TIMx->SMCR的ETP、ETPS、ETF功能位,可以选择输入信号的极性、分频系数、滤波系数。
** 通用定时器的输出比较(PWM的输出)**
每个通用定时器至少有1个通道,每个通道对应一个IO引脚(若需要使用定时器的输入/输出功能,需要将该引脚复用成定时器通道)。每个通道可以用于输入 或 输出功能。
输出比较:根据计数器和比较寄存器值的大小关系,决定在对应的通道(引脚)上输出特定的电平。
输出比较的框图
对于输出比较的配置从这张框图上就能看出,首先
- 把通道配置成输出通道。 TIMx->CCMR1 中的 CC1S[0:1] 填00
- 关闭CCR1的缓冲功能 ,也就是关闭影子功能。OCIE 清零
- 设置输出比较模式为PWM1还是PWM2,TIMx->CCRM1的OC1M[0:2]位
- 设置有效电平 是高电平有效还是低电平有效,手册上说的有点绕,这里我的理解,PWM1,有效电平为高电平。PWM2,有效电平为低电平。TIMx->CCER的CC1P位。
- 别忘了使能通道和给设置比较值。
讲完原理,贴代码:
比如:需要使用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);//计数器使能
}