STM32定时器与PWM(HAL库)
实验任务:
一、设置一个5秒的定时器,每隔5秒从串口发送“hello windows!”;同时设置一个2秒的定时器,让LED等周期性地闪烁,实现一个多任务并发运行的功能。
思考,如果不采用定时器,如何同时完成上面两个周期性任务?
二、使用TIM3和TIM4,分别输出一个PWM波形,PWM的占空比随时间变化,驱动外接的一个LED以及最小开发板上已焊接的LED(固定接在 PC13 GPIO端口),实现2个 LED呼吸灯的效果。
(一)定时器介绍
1.STM32定时器
stm32中有8个定时器,其中4个通用定时器、2个基本定时器和2个高级定时器
其中三种定时器的区别如下所示:
定时器种类 | 位数 | 计数器模式 | 产生DMA请求 | 捕获/比较通道 | 互补输出 | 特殊应用场景 |
---|---|---|---|---|---|---|
高级定时器 (TIM1, TIM8) | 16 | 向上, 向下, 向上/下 | 可以 | 4 | 有 | 带死区控制盒紧急刹车, 可应用于PWM电机控制 |
通用定时器 (TIM2~TIM5) | 16 | 向上, 向下, 向上/下 | 可以 | 4 | 无 | 通用。定时计数, PWM输出, 输入捕获, 输出比较 |
基本定时器 (TIM6, TIM7) | 16 | 向上, 向下, 向上/下 | 可以 | 0 | 无 | 主要应用于驱动DAC |
其中TIM1和TIM8为高级定时器,它比起通用定时器和基本定时器多了互补输出的功能。通用定时器为TIM2到TIM5,它比起高级定时器少了互补输出,但其它功能比较完善。TIM6和TIM7为基本定时器,它没有捕获/比较的通道,也没有互补输出。
2.通用定时器功能和特点
STM32的众多定时器中我们使用最多的是高级定时器和通用定时器,而高级定时器一般也是用作通用定时器的功能,下面我们就以通用定时器为例进行讲解,其功能和特点包括:
(1) 定时器特性
- 总线位置: 位于低速的APB1总线上 (APB1)
- 计数模式: 16位向上、向下、向上/向下(中心对齐)计数模式,自动装载计数器(TIMx_CNT)。
- 预分频器: 16位可编程(可以实时修改)预分频器(TIMx_PSC),计数器时钟频率的分频系数为1~65535之间的任意数值。
(2) 通道功能
- 通道数量: 4个独立通道(TIMx_CH1~4)
① 输入捕获
② 输出比较
③ PWM生成: 边缘或中间对齐模式
④ 单脉冲模式输出
(3) 同步与控制
- 可使用外部信号(TIMx_ETR)控制定时器和定时器互连(可以用1个定时器控制另外一个定时器)的同步电路。
(4) 中断/DMA请求
- 产生中断/DMA的事件:
① 更新: 计数器向上溢出/向下溢出,计数器初始化(通过软件或者内部/外部触发)
② 触发事件: 计数器启动、停止、初始化或者由内部/外部触发计数
③ 输入捕获
④ 输出比较
⑤ 支持针对定位的增量(正交)编码器和霍尔传感器电路
⑥ 触发输入作为外部时钟或者按周期的电流管理
(5) 应用场景
-
STM32的通用定时器可以被用于:
- 测量输入信号的脉冲长度(输入捕获)
- 产生输出波形(输出比较和PWM)
-
使用定时器预分频器和RCC时钟控制器预分频器,脉冲长度和波形周期可以在几个微秒到几个毫秒间调整。
-
STM32的每个通用定时器都是完全独立的,没有互相共享的任何资源。
3.计数器模式
通用定时器可以向上计数、向下计数、向上向下双向计数模式。
CH340芯片模块的工作原理如下:
- 向上计数模式:计数器从0计数到自动加载值(TIMx_ARR),然后重新从0开始计数并且产生一个计数器溢出事件。
- 向下计数模式:计数器从自动装入的值(TIMx_ARR)开始向下计数到0,然后从自动装入的值重新开始,并产生一个计数器向下溢出事件。
- 中央对齐模式(向上/向下计数):计数器从0开始计数到自动装入的值-1,产生一个计数器溢出事件,然后向下计数到1并且产生一个计数器溢出事件;然后再从0开始重新计数。
4通用定时器输出引脚
定时器 | 通道1 | 通道2 | 通道3 | 通道4 |
---|---|---|---|---|
TIM2 | PA0 | PA1 | PA2 | PA3 |
TIM3 | PA6 | PA7 | PB0 | PB1 |
TIM4 | PB6 | PB7 | PB8 | PB9 |
TIM5 | PA0 | PA1 | PA2 | PA3 |
这里需要注意的是,如果对引脚进行了重映射
,则通道对应引脚会发生变化。以TIM3为例
复用功能 | 没有重映射 | 部分重映射 | 完全重映射 |
---|---|---|---|
TIM3_CH1 | PA6 | PB4 | PC6 |
TIM3_CH2 | PA7 | PB5 | PC7 |
TIM3_CH3 | PB0 | PB0 | PC8 |
TIM3_CH4 | PB1 | PB1 | PC9 |
其他几个定时器如下:
- TIM2
复用功能 | TIM2_REMAP[1:0] =00 (没有重映像) | TIM2_REMAP[1:0] =01 (部分重映像) | TIM2_REMAP[1:0] =10 (部分重映像) | TIM2_REMAP[1:0] =11 (完全重映像) |
---|---|---|---|---|
TIM2_CH1_ETR | PA0 | PA15 | PA0 | PA15 |
TIM2_CH2 | PA1 | PB3 | PA1 | PB3 |
TIM2_CH3 | PA2 | PA2 | PB10 | PB10 |
TIM2_CH4 | PA3 | PA3 | PB11 | PB11 |
- TIM4
复用功能 | TIM4_REMAP=0 | TIM4_REMAP=1 |
---|---|---|
TIM4_CH1 | PB6 | PD12 |
TIM4_CH2 | PB7 | PD13 |
TIM4_CH3 | PB8 | PD14 |
TIM4_CH4 | PB9 | PD15 |
- TIM5
复用功能 | TIM5CH4_IREMAP = 0 | TIM5CH4_IREMAP = 1 |
---|---|---|
TIM5_CH4 | TIM5的通道4连至PA3 | LSI内部时钟连至TIM5_CH4的输入作为校准使用 |
5.定时器计时计算
(1)定时器计算详解
定时器的溢出时间 Tout 可以通过以下公式计算:
T o u t = ( arr + 1 ) × ( psc + 1 ) T c l k T_{out} = \frac{(\text{arr}+1) \times (\text{psc}+1)}{T_{clk}} Tout=Tclk(arr+1)×(psc+1)
其中:
-
Tclk:定时器的输入时钟频率(单位MHz)
-
Tout:定时器溢出时间(单位为us)
-
arr:定时器的自动重装载寄存器(TIM_Period),例如:4999
-
psc:定时器的预分频值(TIM_Prescaler),例如:7199
-
举例
T o u t = ( 4999 + 1 ) × ( 7199 + 1 ) 72 = 500000 us = 500 ms T_{out} = \frac{(4999+1) \times (7199+1)}{72} = 500000 \text{us} = 500 \text{ms} Tout=