一、定时器
定时器,顾名思义,就是用于定时或计数,它其实就是一个加1计数器。
1.1 定时器类型
STM32f103
有三类定时器:
类型 | 编号 | 总线 | 功能 |
---|---|---|---|
高级定时器 | TIM1、TIME8 | APB2 | 拥有通用定时器全部功能,并额外具有重复计数器、死区生成、互补输出、刹车输入等功能 |
通用定时器 | TIM2、TIM3、TIM4、TIM5 | APB1 | 拥有基本定时器全部功能,并额外具有内外时钟源选择、输入捕获、输出比较、编码器接口、主从触发模式等功能 |
基本定时器 | TIM6、TIM7 | APB1 | 拥有定时中断、主模式触发DAC的功能 |
每个通用定时器TIMx
功能:
- 位于低速的
APB1
总线上; 16
位向上、向下、向上/向下自动装载计数器(TIMx_CNT
);- 16位可编程预分频器(
TIMx_PSC
),计数器的时钟频率的分频系数为1~65535
之间的任意数值; - 4个独立通道(
TIMx_CH1~4
),这些通道可以用来作为:- 输入捕获;
- 输出比较;
PWM
生成;- 单脉冲模式输出;
- 可使用外部信号(
TIMx_ETR
)控制定时器和定时器互联的同步电路; - 如下事件发生时产生中断/
DMA
(6个独立的IRQ/DMA
请求生成器):- 更新:计数器向上溢出/向下溢出,计数器初始化(通过软件或内部外部触发);
- 触发事件(计数器启动、停止、初始化或者由内部/外部触发计数);
- 输入捕获;
- 输出比较;
- 支持针对定位的增量(正交)编码器和霍尔传感器电路;
- 触发输入作为外部时钟或者按周期的电流管理;
STM32
的通用定时器可以被用于:测量输入信号的脉冲长度(输入捕获)或者产生输出波形(输出比较和PWM
)等。
使用定时器预分频器和RCC
时钟控制器预分频器,脉冲长度和波形周期可以在几个微秒到几个毫秒间调整。STM32
的每个通用定时器都是完全独立的,没有互相共享的任何资源。
1.1.1 高级定时器框图

1.1.2 通用定时器框图

1.1.3 基本定时器框图

1.2 计数器模式
通用定时器可以向上计数、向下计数、向上向下双向计数模式。
- 向上计数模式:计数器从
0
计数到自动加载值(TIMx_ARR
),然后重新从0
开始计数并且产生一个计数器溢出事件; - 向下计数模式:计数器从自动装入的值(
TIMx_ARR
)开始向下计数到0
,然后从自动装入的值重新开始,并产生一个计数器向下溢出事件; - 中央对齐模式(向上/向下计数):计数器从
0
开始计数到自动装入的值-1
,产生一个计数器溢出事件,然后向下计数到1
并且产生一个计数器溢出事件;然后再从0
开始重新计数。
具体如下图所示:

1.3 功能介绍
1.3.1 定时器中断

1.3.2输出比较
输出比较可以通过比较CNT
与CCRx
寄存器值的关系,来对输出电平进行置1
、置0
或翻转的操作,用于输出一定频率和占空比的PWM
波形。
输出比较模式:
模式 | 描述 |
---|---|
冻结 | CNT=CCR时,REF保持为原状态 |
匹配时置有效电平 | CNT=CCR时,REF置有效电平 |
匹配时置无效电平 | CNT=CCR时,REF置无效电平 |
匹配时置电平翻转 | CNT=CCR时,REF电平翻转 |
强制为无效电平 | CNT与CCR无效,REF强制为无效电平 |
强制为有效电平 | CNT与CCR无效,REF强制为有效电平 |
PWM模式1 | 向上计数:CNT<CCR时,REF置有效电平,CNT≥CCR时,REF置无效电平 向下计数:CNT>CCR时,REF置无效电平,CNT≤CRR时,REF置有效电平 |
PWM模式2 | 向上计数:CNT<CCR时,REF置无效电平,CNT≥CCR时,REF置有效电平 向下计数:CNT>CCR时,REF置有效电平,CNT≤CRR时,REF置无效电平 |
1.3.3 PWM
基本结构

PWM
频率 :\(F_{req} = CK\_PSC / (PSC + 1) / (ARR + 1)\);
PWM
占空比:\(Duty = CCR / (ARR + 1)\);
PWM
分辨率:\(Peso = 1 / (ARR + 1)\)。
二、定时器相关寄存器
2.1 控制寄存器(TIMx_CR1
)
想要使用定时器功能,首先要使能定时器。使能定时器主要用到控制寄存器1
(TIMx_CR1
),此处重点关注第一位,这一位是计数器使能位,给此位设1,使能计数器;


2.2 DMA
/中断使能寄存器(TIMx_DIER
)
定时器的使用,很多情况下都伴随着中断,因此下面要重点关注的是DMA
/中断使能寄存器(TIMx_DIER
)。同样的,只用关注第一位。该位为更新中断允许位,当该位设置为1时,将允许由于更新事件所产生的中断;


2.3 预分频寄存器(TIMx_PSC
)
接下来就要确定定时器的时间,定时器的定时是通过频率计算出来的。这里要用到预分频寄存器(TIMx_PSC
)。该寄存器用于设置对时钟进行分频,然后提供给计数器,作为计数器的时钟;

计数器计数频率:\(CK\_CNT = 时钟源频率 / 预分频系数 = \frac{CK\_PSC}{PSC + 1}\)
计数器溢出频率 :$CK_CNT_OV = 时钟源频率 / 预分频系数 /自动重装载寄存器 = CK_CNT / (ARR + 1)
= CK_PSC / (PSC + 1) / (ARR + 1) $
2.4 从模式控制寄存器(TIMx_SMCR
)
从框图中可以看到统通用定时器时钟来源有以下几个:
- 内部时钟(
CK_INT
)默认; - 外部时钟模式
1
:外部输入脚(TIx
); - 外部时钟模式
2
:外部触发输入(ETR
); - 内部触发输入(
ITRx
):使用一个定时器作为另一个定时器的预分频器,如可以配置一个定时器Timer1
而作为另一个定时器Timer2
的预分频器。
时钟源的选择,可以通过从模式寄存器(TIMx_SMCR
)的第3位来选择;


2.5 自动重装载寄存器(TIMx_ARR
)
下面是自动重载寄存器。自动装载寄存器(TIMx_ARR
)是预先装载的,写或读自动重装载寄存器将访问预装载寄存器;

2.6 状态寄存器(TIMx_SR
)


三 定时中断源码
3.1 定时中断初始化步骤
定时中断配置流程如下(这里以TIM3
为例):
(1) TIM3
时钟使能:通过配置RCC_APB1ENR
寄存器使能TIM3
时钟;
(2) 配置TIM3
时基单元;
-
配置
TIM3_ARR
寄存器自动重装载的值; -
配置
TIM3_PSC
频寄存器预分频系数;
(3) 配置TIM3_DIER
寄存器允许更新中断(UIE=1
),清SR
寄存器状态标志位(UIF=0
);
(4) 设置NVIC
;
- 参考《
STM32F103
嵌套向量中断控制器》:设置中断优先级分组、设置响应优先级和抢断优先级、使能相应中断位;
(4) 中断处理函数;
- 设置中断服务函数(包括清除中断标志)。
(5) 允许TIM3
工作:配置TIM3_CR1
位0。
3.2 源码实现
3.3 实现功能
参考文章
[1] STM32F103
定时器配置