STM32的定时器分为基本定时器、通用定时器和高级定时器。以STM32VET6指南者为例,
TIM6、TIM7是基本定时器,TIM2、TIM3、TIM4、TIM5是通用定时器,TIM1和TIM8是高级定时器。
定时器的基本功能就是计数,并在适当的时间生成一个时间/更新。
时钟源(TIMxCLK):基本定时器和通用定时器的时钟源都是经过APB1总线时钟的2倍频提供的,
为72MHz。高级定时器的时钟源来自于APB2总线时钟,也是72MHz。
计数器时钟(CK_CNT):定时器时钟经过PSC预分频器分频后,为计数器时钟CK_CNT。
计数器时钟用来驱动计数器计数。PSC是一个16位的寄存器,可以对定时器时钟TIMxCLK进行
1~65536之间的任何一个数进行分频。计算方式为:
CK_CLK = TIMxCLK / (PSC+1)
计数器(CNT):计数器CNT是一个16位的计数器,最大计数值为65535。计数模式为:
向上计数,向下计数,中央对齐。其中,基本定时器只支持向上计数模式,其它模式不支持。
通用和高级定时器支持所有的计数模式。
自动重装在寄存器(ARR):自动重载寄存器 ARR 用来存放与计数器 CNT 比较的值,
是一个16位的寄存器,这里面装载着计数器能计数的最大值。
向上计数模式:计数器从 0 开始计数,每来一个 CK_CNT 脉冲计数器就增加 1,直 到
计数器的值与自动重载寄存器 ARR 值相等,然后计数器又从 0 开始计数并生成计数 器上溢事件,
计数器总是如此循环计数
向下计数模式:,计数器从自动重载寄存器 ARR 值开始计数,每来一个 CK_CNT 脉 冲计数器就减 1,
直到计数器值为 0,然后计数器又从自动重载寄存器 ARR 值开始递 减计数并生成计数器下溢事件,
计数器总是如此循环计数。
中央对齐模式: 计数器从 0 开始递增计数,直到计数值等于(ARR-1)值生成计数器上 溢事件,
然后从 ARR 值开始递减计数直到 1 生成计数器下溢事件。然后又从 0 开始计 数,如此循环。
每次发生计数器上溢和下溢事件都会生成更新事件。
重复计数器:为高级定时器独有,是一个8位的寄存器。在基本/通用定时器发生上/下溢事件时
直接就生成更新事件,但对于高级控制定时器 却不是这样,高级控制定时器在硬件结构上多出了
重复计数器,在定时器发生上溢或下溢 事件是递减重复计数器的值,只有当重复计数器为 0 时才
会生成更新事件。在发生 N+1 个 上溢或下溢事件(N 为 RCR 的值)时产生更新事件。
基本定时器就是一个计数器,没有连接到I/O口;
通用定时器和高级定时器不仅仅是一个计数器(最重要的功能还是计数),它们每一个定时器
还有4路通道,每个通道连接在一个GPIO引脚上,可以实现输入捕获、输出比较功能。每个通道需要单独配置。
在STM32的标准库对定时器外设建立了四个结构体类型,分别为:
时基初始化结构体TIM_TimeBaseInitTypeDef;
输出比较初始化结构体TIM_OCInitTypeDef;
输入捕获初始化结构体TIM_ICInitTypeDef;
断路和死区初始化结构体TIM_BDTRInitTypeDef;
高级定时器可以用到所有的初始化结构体;
通用定时器只能使用前三个结构体,不能使用最后一个结构体;
基本定时器只能使用第一个结构体。
1. TIM_TimeBaseInitTypeDef 时基结构体
TIM_TimeBaseInitTypeDef用于定时器基础参数设置,与TIM_TimeBaseInit 函数
配合使用完成配置。
typedef struct {
uint16_t TIM_Prescaler; // 预分频器
uint16_t TIM_CounterMode; // 计数模式
uint32_t TIM_Period; // 定时器周期
uint16_t TIM_ClockDivision; // 时钟分频
uint8_t TIM_RepetitionCounter; // 重复计数器
} TIM_TimeBaseInitTypeDef;
基本定时器需配置:TIM_Prescaler、TIM_Period
通用定时器需配置:TIM_Prescaler、TIM_CounterMode、TIM_Period
时钟分频和重复计数器只有高级定时器才有。
2. TIM_OCInitTypeDef 输出比较结构体
TIM_OCInitTypeDef 用于输出比较模式,与 TIM_OCxInit 函数配合使 用完成指定定时器
输出通道初始化配置。通用定时器和高级定时器都有四个定时器通道,使用时都必 须单独设置。
typedef struct {
uint16_t TIM_OCMode; // 比较输出模式
uint16_t TIM_OutputState; // 比较输出使能
uint16_t TIM_OutputNState; // 比较互补输出使能
uint32_t TIM_Pulse; // 脉冲宽度
uint16_t TIM_OCPolarity; // 输出极性
uint16_t TIM_OCNPolarity; // 互补输出极性
uint16_t TIM_OCIdleState; // 空闲状态下比较输出状态
uint16_t TIM_OCNIdleState; // 空闲状态下比较互补输出状态
} TIM_OCInitTypeDef;
其中,如果产生PWM波驱动LED灯和简单的步进电机,只选用配置TIM_OCMode、TIM_OutputState、
TIM_Pulse、TIM_OCPolarity即可。
TIM_OCMode:比较输出模式选择,可选择为 PWM1/PWM2模式,这两种模式基本相同,选哪个都可以。
TIM_OutputState:比较输出使能,肯定选ENABLE;
TIM_Pulse:比较输出脉冲宽度,实际设定比较寄存器 CCR 的值,决定脉冲宽度。这个设置定时器的
比较寄存器,用来设置PWM波的占空比(高低电平时间)。
TIM_OCPolarity:比较输出极性,可选 OCx 为高电平有效或低电平有效。它决定着定 时器通道有效电平。
它设定 CCER 寄存器的 CCxP 位的值。
关于TIM_OCPolarity输出比较极性:
如果你设置计数器计数模式为向上计数模式,ARR寄存器的值为M,比较寄存器的值为N,计数器的值x,
TIM_OCPolarity输出比较极性设置为TIM_OCPolarity_High,那么:当 0<=x <=N时,输出高电平(PWM为高电平),
当N<=x<=M时,输出低电平(PWM为低电平)。