1****定时器基础知识
a:上来说就是用来定时的机器,是存在于STM32单片机中的一个外设。STM32总共有8个定时器,分别是2个高级定时器(TIM1、TIM8),4个通用定时器 (TIM2、TIM3、TIM4、TIM5) 和2个基本定时器 (TIM6、TIM7),如下图所示:|
STM32F10X****系列总共最多有八个定时器:
STM32F103C8T6核心定时器 (5个)
-
TIM1 (高级控制定时器 - Advanced-control timer)
-
16位向上/向下计数器
-
4个独立通道(可用于输入捕获、输出比较、PWM生成)
-
支持互补输出带死区插入(非常适合电机控制、电源转换)
-
支持编码器接口
-
支持刹车信号输入
-
最高可达72MHz计数时钟。
-
-
TIM2 (通用定时器 - General-purpose timer)
-
16位向上/向下计数器
-
4个独立通道(输入捕获、输出比较、PWM)
-
支持编码器接口
-
具有32位可编程预分频器(提供非常精细的时钟分频)。
-
最高可达72MHz计数时钟。
-
-
TIM3 (通用定时器 - General-purpose timer)
-
16位向上/向下计数器
-
4个独立通道(输入捕获、输出比较、PWM)
-
支持编码器接口
-
最高可达72MHz计数时钟。
-
-
TIM4 (通用定时器 - General-purpose timer)
-
16位向上/向下计数器
-
4个独立通道(输入捕获、输出比较、PWM)
-
支持编码器接口
-
最高可达72MHz计数时钟。
-
-
TIM5 (通用定时器 - General-purpose timer)
-
16位向上/向下计数器
-
4个独立通道(输入捕获、输出比较、PWM)
-
支持编码器接口
-
最高可达72MHz计数时钟。
-
2.三种STM32****定时器的区别:
即:高级定时器具有捕获/比较通道和互补输出,通用定时器只有捕获/比较通道,基本定时器没有以上两者
**.**计数器模式
通用定时器可以向上计数、向下计数、向上向下双向计数模式
1:向上计数模式:计数器从0计数到自动加载值(TIMx_ARR),然后重新从0开始计数并且
产生一个计数器溢出事件
2:向下计数模式:计数器从自动装入的值(TIMx_ARR)开始向下计数到0,然后从自动装
入的值重新开始,并产生一个计数器向下溢出事件
3:中央对齐模式(向上/向下计数):计数器从0开始计数到自动装入的值-1,产生一个
计数器溢出事件,然后向下计数到1并且产生一个计数器溢出事件;然后再从0开始重新计数

二:基本定时器
**1.**基本定时器的结构框图

- 时钟源
- 控制器
- 时基单元
1. 时钟源 (Clock Sources)
-
来源: 图中最上方明确标注了
来自RCC的TIMxCLK
。 -
含义:
-
RCC
(Reset and Clock Control):STM32的时钟控制器模块,负责产生和分配系统所有时钟信号。 -
TIMxCLK
:这是分配给特定定时器(TIM1, TIM2, TIM3等)的时钟源。这个时钟的频率决定了定时器运行的最快速度。
-
-
常见TIMxCLK来源 (STM32F1为例):
-
内部时钟 (CK_INT): 这是最常用的模式。通常TIMxCLK直接来源于
APB1
(低速外设总线,TIM2-4挂在上面)或APB2
(高速外设总线,TIM1挂在上面)的时钟。在标准库/HAL库中,调用HAL_TIM_Base_Init()
或类似初始化函数后,默认选择的就是内部时钟。 -
外部时钟模式1 (External Clock Mode 1): 时钟信号来自定时器的特定输入通道(如TI1, TI2)。通常用于外部脉冲计数或测量外部信号频率。
-
外部时钟模式2 (External Clock Mode 2): 时钟信号来自
ETR
引脚(外部触发输入)。 -
内部触发输入 (ITRx): 一个定时器可以被另一个定时器触发,此时触发信号就成为被触发定时器的时钟源。
-
-
图中体现:
来自RCC的TIMxCLK
就是进入定时器的最初时钟信号。它首先被送入 触发控制器 (Trigger Controller) 和 时基单元。 -
关键点: 时钟源的选择和频率是决定定时器计数速度和精度的最根本因素。

因为APB1的预分频系数是2,所以是36MHz*2=72MHz;
2:控制器
控制器用于控制定时器:复位、使能、计数、触发ADC
涉及到的寄存器:CR1/2,DIER,EGR,SR
核心功能 :
通过寄存器控制定时器的启停、计数模式、中断/DMA触发及事件生成。
关键寄存器及作用:
寄存器 | 核心功能 | 关键位说明 |
---|---|---|
CR1 | 控制计数方向、使能、预装载设置 | CEN :定时器使能位(1=启动计数) DIR :计数方向(0=向上,1=向下) ARPE :ARR预装载使能(影子寄存器开关) |
CR2 | 主模式配置、触发输出选择 | MMS[2:0] :选择TRGO触发源(如更新事件UEV、捕获比较事件等) |
DIER | 使能中断/DMA请求 | UIE :更新事件中断使能 UDE :更新事件DMA请求使能 |
EGR | 软件强制生成事件 | UG :置1时立即生成更新事件(强制重载影子寄存器) |
SR | 状态标志监测 | UIF :更新事件标志位(需软件清零) |
3:时基(定时器的心脏)
定时器最重要的就是时基部分:包括预分频器、计数器、自动重装载寄存器
预分频器:1-16位预分频器PSC对内部时钟CK_PSC进行分频之后,得到计数器时
钟CK_INT=CK_PSC/(PSC+1)
CNT在计数器时钟的驱动下开始计数,计数一次的时间为1/CK_INT
计数器、重装在寄存器:定时器使能(CEN置1)后,计数器CNT在CK_CNT驱动
下计数,当TNT值与ARR的设定值相等时就自动生成事件并CNT自动清零,然后
自动重新开始计数,如此重复以上过程。
最终定时周期计算 (以向上计数为例):
-
定时器时钟频率 (CK_CNT) = TIMxCLK / (PSC + 1)
-
计数器溢出频率 (更新事件频率) = CK_CNT / (ARR + 1)
-
定时周期 (每次更新事件的时间间隔) = (ARR + 1) / CK_CNT = (ARR + 1) * (PSC + 1) / TIMxCLK
例子 (STM32F103C8T6 @72MHz, TIM2 定时1ms):
-
TIMxCLK
(APB1 Timer Clk) = 72 MHz -
目标周期 T = 0.001s (1ms)
-
选择
PSC = 7199
(分频系数 7200)CK_CNT
= 72,000,000 Hz / 7200 = 10,000 Hz (周期 0.0001s)
-
需要计数次数 N = T / (1 / CK_CNT) = 0.001s / 0.0001s = 10
-
设置
ARR = 9
(因为计数从0到9是10次)- 验证:周期 = (9 + 1) * (7199 + 1) / 72,000,000 = 10 * 7200 / 72,000,000 = 72,000 / 72,000,000 = 0.001s = 1ms ✅
这张框图完美地诠释了STM32定时器如何利用时钟源、控制器和时基单元(PSC, CNT, ARR)协同工作来产生精确的定时基础。理解这三个部分及其相互关系是掌握STM32定时器的关键。
**.**定时时间的计算
定时器时间= (PSC+1)*(ARR+1)/72M
三、影子寄存器:关键缓冲机制
存在意义 :解决运行时修改参数导致的周期撕裂问题
两种模式对比:
特性 | 启用影子寄存器 (ARPE=1) | 禁用影子寄存器 (ARPE=0) |
---|---|---|
修改生效时机 | 下次更新事件(UEV)时 | 立即生效 |
安全性 | ⭐⭐⭐⭐ 无周期撕裂风险 | ⚠️ 可能中断当前计数周期 |
典型场景 | 实时调整PWM周期/频率 | 单次触发或无需平滑切换的场景 |
寄存器操作 | 修改后需等待UEV或手动触发EGR.UG=1 |
直接写入即生效 |
关键场景演示(ARPE=1时修改ARR):
CNT正在计数至旧ARR值(如200)
用户写入新ARR=300 → 存入预装载寄存器
CNT到达200 → 触发UEV →
影子寄存器加载300
CNT清零并按新值300 重新计数
完美避免计数中途切换导致的周期异常
通用定时器(TIM2/3/4/5) 和 高级定时器(TIM1/8) 、
一、定时器核心功能对比
功能 | 通用定时器 (TIM2/3/4/5) | 高级定时器 (TIM1/8) |
---|---|---|
基础定时 | ✅ 支持 | ✅ 支持 |
输出比较 | ✅ 4通道独立PWM输出 | ✅ 4通道PWM + 3路互补输出 |
输入捕获 | ✅ 测量脉冲宽度/频率 | ✅ 增强型捕获(支持正交编码器) |
断路输入 | ❌ 不支持 | ✅ 紧急关断引脚(Break Input) |
重复计数器 | ❌ 无 | ✅ RCR(实现事件分频) |
时钟源 | PCLK1 (36/72MHz) | PCLK2 (72MHz) |
📌 注:
F103的通用定时器挂载在APB1总线(最大72MHz),高级定时器挂载在APB2总线(72MHz)。
互补输出和断路输入是高级定时器用于电机控制/逆变器的关键安全特性。
二、高级定时器独有功能详解
1. 重复计数器 (RCR)
- 作用 :实现事件分频,避免频繁中断。
2. 互补输出与死区控制
-
通道结构:
TIM1_CH1 --> PWM主输出 (e.g., PA8) TIM1_CH1N --> 互补输出 (e.g., PB13) // 低有效,带死区
-
死区发生器 (DBG) :
防止上下管(如MOSFET)同时导通造成短路,插入纳秒级延迟。
3. 断路输入 (Break Input)
-
紧急关断场景 :过流/过压时,外部信号拉低→ 立即关闭所有PWM输出。
-
寄存器控制 :
BDTR
寄存器配置断路极性、锁定模式、OSSR/OSSI状态。
三、通用定时器核心特性
1. 时基单元(与高级定时器相同)
-
16位PSC(预分频器) + 16位ARR(自动重装) → 灵活定时间隔
-
计算公式 :
<code>T<sub>out</sub> = (ARR + 1) × (PSC + 1) / TIM<sub>CLK</sub></code>
(例:72MHz下,PSC=7199, ARR=9 → 1ms定时)
3 定时器控制LED
软件流程设计
初始化系统
初始化定时器和LED的IO时钟
初始化LED的引脚IO
定时器中断中驱动LED灯
Tim.c
cs
#include "stm32f10x.h"
#include "Tim.h"
void Base_Tim_Init(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitstruct;
NVIC_InitTypeDef NVIC_Initstruct;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
TIM_TimeBaseInitstruct.TIM_ClockDivision=TIM_CKD_DIV1;//看心得1
TIM_TimeBaseInitstruct.TIM_CounterMode=TIM_CounterMode_Up;
TIM_TimeBaseInitstruct.TIM_Period=7200;
TIM_TimeBaseInitstruct.TIM_Prescaler=10000;
TIM_TimeBaseInitstruct.TIM_RepetitionCounter=0;
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitstruct);
TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE );
TIM_Cmd( TIM2, ENABLE);
NVIC_Initstruct.NVIC_IRQChannel=TIM2_IRQn ;
NVIC_Initstruct.NVIC_IRQChannelPreemptionPriority=0;
NVIC_Initstruct.NVIC_IRQChannelSubPriority=0;
NVIC_Initstruct.NVIC_IRQChannelCmd=ENABLE;
NVIC_Init(&NVIC_Initstruct);
}
Tim.h
cs
#ifndef _TIM_H_
#define _TIM_H_
void Base_Tim_Init(void);
#endif
main.c
cs
#include "stm32f10x.h"
#include "main.h"
#include "led.h"
#include "Bear.h"
#include "key.h"
#include "relay.h"
#include "shake.h"
#include "wireless.h"
#include "exti_key.h"
#include "usart.h"
#include "stdio.h"
#include "Tim.h"
void delay(uint16_t time)//延时1ms 软件延时粗延时
{
uint16_t i=0;
while(time --)
{
i=12000;
while(i --);
}
}
int main()
{
LED_Init();
Base_Tim_Init();
while(1)
{
}
}
void TIM2_IRQHandler (void)
{
if(TIM_GetITStatus(TIM2, TIM_IT_Update)!=RESET)
{
GPIO_ResetBits(GPIOA,GPIO_Pin_1);
delay(1000);
GPIO_SetBits(GPIOA,GPIO_Pin_1);
delay(1000);
TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
}
}
今日心得:
1:定时器时钟分频(TIM_Clock_Division_CKD)详解
在STM32定时器(TIM)中,CKD
(Clock Division)用于配置输入时钟源的分频系数,从而调整定时器的内部时钟频率。以下是核心概念的解释:
1. 分频宏定义的含义
宏定义 | 值(十六进制) | 二进制值 | 分频系数 | 作用描述 |
---|---|---|---|---|
TIM_CKD_DIV1 |
0x0000 |
00 |
1 | 不分频(时钟源直接使用) |
TIM_CKD_DIV2 |
0x0100 |
01 |
2 | 时钟源2分频(频率减半) |
TIM_CKD_DIV4 |
0x0200 |
10 |
4 | 时钟源4分频(频率降为1/4) |
关键点:
这些值通过位操作写入定时器控制寄存器(
TIMx_CR1
)的 CKD[1:0] 位(第8-9位)。例如:
0x0100
(即0000 0001 0000 0000
)会将第8位置1,第9位保持
总结
-
TIM_CKD_DIVx 是配置定时器时钟源分频的选项,直接影响定时器的基础频率。
-
分频系数1/2/4 分别对应不分频、2分频、4分频,通过寄存器位
CKD[1:0]
控制。 -
与预分频器(PSC)协同工作,可实现更灵活的时钟频率调整。
通过合理配置 CKD
,开发者可以优化定时器的功耗和性能,适配不同应用场景的需求。
2:TIM_ITConfig(TIM_TypeDef* TIMx, uint16_t TIM_IT, FunctionalState NewState);作用是啥
核心作用
配置定时器(TIM)的中断使能状态
通过设置/清除定时器的 DIER(DMA/Interrupt Enable Register)寄存器 的特定位,控制特定定时器事件是否触发中断。
参数解析
参数 | 类型 | 说明 |
---|---|---|
TIMx |
TIM_TypeDef* | 定时器实例指针(如 TIM1, TIM2 等) |
TIM_IT |
uint16_t | 中断源选择(使用位掩码指定要配置的中断事件) |
NewState |
FunctionalState | 中断状态:ENABLE (使能)或 DISABLE (禁用) |
中断源(TIM_IT)详解
TIM_IT
是以下宏的位掩码组合(可多选):
中断源宏 | 值(十六进制) | 触发事件说明 |
---|---|---|
TIM_IT_Update | 0x0001 |
计数器溢出/更新事件(如计数器达到自动重载值) |
TIM_IT_CC1 | 0x0002 |
通道 1 捕获/比较事件(如输入捕获触发或比较匹配) |
TIM_IT_CC2 | 0x0004 |
通道 2 捕获/比较事件 |
TIM_IT_CC3 | 0x0008 |
通道 3 捕获/比较事件 |
TIM_IT_CC4 | 0x0010 |
通道 4 捕获/比较事件 |
TIM_IT_Trigger | 0x0040 |
触发事件(由从模式控制器触发,如外部信号同步) |
TIM_IT_Break | 0x0080 |
断路输入事件(高级定时器特有,用于紧急关闭输出) |