当前位置: 首页 > news >正文

STM32第二十一天定时器TIM

1 定时器基础知识
a:上来说就是用来定时的机器,是存在于STM32单片机中的一个外设。STM32总共有8个定时器,分别是2个高级定时器(TIM1、TIM8),4个通用定时器 (TIM2、TIM3、TIM4、TIM5) 和2个基本定时器 (TIM6、TIM7),如下图所示:|
STM32F10X系列总共最多有八个定时器:

 STM32F103C8T6核心定时器 (5个)

  1. TIM1 (高级控制定时器 - Advanced-control timer)

    • 16位向上/向下计数器

    • 4个独立通道(可用于输入捕获、输出比较、PWM生成)

    • 支持互补输出带死区插入(非常适合电机控制、电源转换)

    • 支持编码器接口

    • 支持刹车信号输入

    • 最高可达72MHz计数时钟。

  2. TIM2 (通用定时器 - General-purpose timer)

    • 16位向上/向下计数器

    • 4个独立通道(输入捕获、输出比较、PWM)

    • 支持编码器接口

    • 具有32位可编程预分频器(提供非常精细的时钟分频)。

    • 最高可达72MHz计数时钟。

  3. TIM3 (通用定时器 - General-purpose timer)

    • 16位向上/向下计数器

    • 4个独立通道(输入捕获、输出比较、PWM)

    • 支持编码器接口

    • 最高可达72MHz计数时钟。

  4. TIM4 (通用定时器 - General-purpose timer)

    • 16位向上/向下计数器

    • 4个独立通道(输入捕获、输出比较、PWM)

    • 支持编码器接口

    • 最高可达72MHz计数时钟。

  5. 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. 时钟源
2. 控制器
3. 时基单元

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
计数器、重装在寄存器:定时器使能(CEN1)后,计数器CNTCK_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):

  1. CNT正在计数至旧ARR值(如200)

  2. 用户写入新ARR=300 → 存入预装载寄存器

  3. 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 

软件流程设计
初始化系统
初始化定时器和LEDIO时钟
初始化LED的引脚IO
定时器中断中驱动LED
Tim.c
#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;//看心得1TIM_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

#ifndef _TIM_H_
#define _TIM_H_void Base_Tim_Init(void);#endif

main.c

#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_DIV10x0000001不分频(时钟源直接使用)
TIM_CKD_DIV20x0100012时钟源2分频(频率减半)
TIM_CKD_DIV40x0200104时钟源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)寄存器 的特定位,控制特定定时器事件是否触发中断。

参数解析

参数类型说明
TIMxTIM_TypeDef*定时器实例指针(如 TIM1, TIM2 等)
TIM_ITuint16_t中断源选择(使用位掩码指定要配置的中断事件)
NewStateFunctionalState中断状态:ENABLE(使能)或 DISABLE(禁用)

中断源(TIM_IT)详解

TIM_IT 是以下宏的位掩码组合(可多选):

中断源宏值(十六进制)触发事件说明
TIM_IT_Update0x0001计数器溢出/更新事件(如计数器达到自动重载值)
TIM_IT_CC10x0002通道 1 捕获/比较事件(如输入捕获触发或比较匹配)
TIM_IT_CC20x0004通道 2 捕获/比较事件
TIM_IT_CC30x0008通道 3 捕获/比较事件
TIM_IT_CC40x0010通道 4 捕获/比较事件
TIM_IT_Trigger0x0040触发事件(由从模式控制器触发,如外部信号同步)
TIM_IT_Break0x0080断路输入事件(高级定时器特有,用于紧急关闭输出)

 

http://www.dtcms.com/a/276263.html

相关文章:

  • docker搭建 与镜像加速器
  • LeetCode经典题解:3、无重复字符的最长子串
  • 【Elasticsearch】post_filter
  • 【MATLAB代码】Chan方法解算TOA,用于三维目标的定位,锚点数量可自适应。订阅专栏后可查看完整代码
  • Windows环境下解决Matplotlib中文字体显示问题的详细指南
  • PyTorch神经网络实战:从零构建图像分类模型
  • linux----------------------线程同步与互斥(上)
  • 搭建MySQL读写分离
  • LiteFlow源码
  • Mamba架构的模型 (内容由deepseek辅助汇总)
  • 手把手教你 Aancond 的下载与 YOLOV13 部署(环境的创建及配置下载)以及使用方法,连草履虫都能学会的目标检测实验!
  • net.createServer详解
  • Python后端项目之:我为什么使用pdm+uv
  • 模拟注意力:少量参数放大 Attention 表征能力
  • hiredis: 一个轻量级、高性能的 C 语言 Redis 客户端库
  • 深入解析C#接口实现的两种核心技术:派生继承 vs 显式实现
  • Java 21 虚拟线程
  • 浏览器宏任务的最小延时:揭开setTimeout 4ms的神话
  • java中的main方法
  • window7,windows10,windows11种系统之间实现打印机共享
  • 创客匠人:从定位逻辑看创始人 IP 如何驱动 IP 变现
  • CompareFace使用
  • Kimi K2万亿参数开源模型原理介绍
  • 【读书笔记】《C++ Software Design》第二章:The Art of Building Abstractions
  • Ruby如何采集直播数据源地址
  • OpenEuler操作系统中检测插入的USB设备并自动挂载
  • 【数据结构】反射、枚举 和 lambda表达式
  • Golang 面向对象(封装、继承、多态)
  • 【C语言】指针进阶:指针和数组
  • 手把手教你用YOLOv10打造智能垃圾检测系统