定时器
定时器的基本概述
STM32的常见的定时器资源: 系统嘀嗒定时器SysTick、看门狗定时器WatchDog、实时时钟RTC、基本定时器、通用定时器、高级定时器。
系统嘀嗒定时器SysTick :这是一个集成在Cortex M3内核当中的定时器,它并不属于芯片厂商的外设,也就是说使用ARM内核的不同厂商,都拥有基本结构相同的系统定时器。主要目的是给RTOS提供时钟节拍做时间基准。
基本定时器:TIM6、TIM7。
通用定时器:TIM2、TIM3、TIM4、TIM5。在基本定时器的基础上,实现输出比较、输入捕获、PWM生成、单脉冲模式输出等功能。这类定时器最具***代表性***,使用也***最广泛***。
高级定时器:TIM1、TIM8。
STM32通用定时器的重要知识点
通用定时器的基本结构组成:
STM32的通用定时器,是一个通过可编程预分频器(Prescaler)驱动的16位自动重装主计数器(Counter Period)构成。可以对内部时钟或触发源以及外部时钟或触发源进行计数。
TIMx主要功能:通用TIMx (TIM2、TIM3、TIM4和TIM5)定时器功能包括:
- 16位向上、向下、向上/向下自动装载计数器
- 16位可编程(可以实时修改)预分频器,计数器时钟频率的分频系数为1~65536之间的意
数值 - 4个独立通道:
- 输入捕获
- 输出比较
- PWM生成(边缘或中间对齐模式)
- 单脉冲模式输出
- 使用外部信号控制定时器和定时器互连的同步电路
- 如下事件发生时产生中断/DMA:
- 更新:计数器向上溢出/向下溢出,计数器初始化(通过软件或者内部/外部触发)
- 触发事件(计数器启动、停止、初始化或者由内部/外部触发计数)─
- 输入捕获
- 输出比较
- 支持针对定位的增量(正交)编码器和霍尔传感器电路
- 触发输入作为外部时钟或者按周期的电流管理
-
- 更新:计数器向上溢出/向下溢出,计数器初始化(通过软件或者内部/外部触发)
触发事件(计数器启动、停止、初始化或者由内部/外部触发计数)
输入捕获
输出比较
- 更新:计数器向上溢出/向下溢出,计数器初始化(通过软件或者内部/外部触发)
通用定时器的==基本工作原理==:
首先,定时器时钟信号送入16位***可编程预分配器***(Prescaler),该预分配器系数为0~65535之间的任意数值。预分配器溢出后,会向16位的主计数器(Counter Period)发出一个脉冲信号。
预分频器,本质上是一个加法计数器,预分频系数实际上就是加计数的溢出值。
定时器发生中断时间的计算方法:
定时时间 = (Prescaler+1 ) X (Counter Period+1) X 1/ 定时器时钟频率(信号的周期)
时钟信号1KHz,Prescaler为9,Counter Period为999,定时时间?
例子:时钟信号32MHz,每隔500ms翻转一次PB9的输出电平
【1】设置Clock Source时钟源
【2】设置Prescaler和Counter Period参数
【3】设置NVIC嵌套向量中断控制器
注:Prescaler和Counter Period参数的设置不是唯一的,一般设置方法:时钟信号为X,则Prescaler为X-1,需要的时间为Yms,则Counter Period设置为Y-1, 上题中,Prescaler和Counter Period参数为32000和500,32000 * 500/32000 = 0.5s = 500ms
CUBEMX设置
大部分设置和之前写的一样,LED脚作GPIO_OUTPUT,配置时钟源。
- 配置定时器TIM2,Prescaler和Counter Period参数设置
- 使能TIM2
- 配置时钟数
-
生成工程
MDK设置
-
编写回调函数
在
stm32l4xx_it.c
中生成的中断处理函数如下,定时器TIM2所有的中断都会调用该中断服务函数TIM2_IRQHandler
:
- 在中断处理函数中自动生成了HAL_TIM_IRQHandler(&htim2)代码,该代码会自动根据中断事件回调相应的函数,这里我们需要处理更新中断的事件,回调函数默认是__weak定义的,所以在tim.c中重新定义该回调函数,并且在该函数中添加功能的时候,因为该回调函数会被所有的==定时器共用==,所以需要先判断是哪个定时器在调用:
- 最后在
main
函数中开启TIM2并使能其中断(TIM2初始化代码之后,while之前):
HAL_TIM_Base_Start_IT(&htim2);
最后就可以看见LED以0.5S为周期闪烁了