STM32外设:定时器TIM
主要外设:
- TIM:Timer 定时器
TIM中的基本电路
定时器
计数器的基本功能
- 复位:
计数器值=初值、产生一个输出脉冲、产生更新事件(UEV)脉冲、更新中断标志UIF=1 - 计数:
计数器值递增或递减 - 设置方向:递增或递减
计数器的使用:输入脉冲(N个)→计数器→输出脉冲(1个)
- 输入脉冲的第一个边沿时刻:计数器进行
复位 - 输入脉冲的非首个边沿时刻:检查计数器是否等于
终值- 若相等(溢出),对计数器进行
复位 - 若不等(计数),对计数器进行
计数
- 若相等(溢出),对计数器进行
- 所以
N=|终值-初值|+1
计数器的数据:初值、计数器值、终值
- 计数器值:在
计数器中,位宽决定计数范围(16bit计数器为0~65535) - STM32以0为初值或终值
- 另一个值(终值或初值):所以计数器还需要一个额外的
寄存器
计数器的定时(分频)功能:
- 若输入为
频率fp的时钟信号 - 则输出为
频率f的时钟信号且f=fp*(1/N),N作为分频系数
时基单元
输入→预分频寄存器PSC及影子寄存器、预分频计数器→自动重载寄存器ARR及影子寄存器、核心计数器、计数器寄存器CNT→产生上溢、下溢
→产生UEV事件→[产生更新中断UIF、DMA中断]
- PSC和ARR都有一个影子寄存器:真正起作用的寄存器、不能直接用代码修改
- 代码修改PSC和ARR时
- 直接修改影子寄存器的值(无缓冲)
- 等到UEV事件时,统一修改影子寄存器的值(缓冲)
时钟源
输入信号→时钟源选择→时基单元
- 内部时钟
- 引脚TIM_CH(外部输入):外部时钟模式1
- 引脚TIM_ETR(外部输入):外部时钟模式2
- 内部触发信号ITR:内部其他定时器
外部时钟模式2:
引脚TIM_ETR→GPIO AFR→GPIO输入电路→边沿选择SMCR(ETP)→分频器SMCR(ETPS)→滤波器SMCR(ETF)→时钟源选择SMCR(ECE、SMS)→时基单元
引脚TIM_CH→输入捕获单元→捕获/比较寄存器→中断/DMA
捕获/比较寄存器→输出比较单元→引脚TIM_CH
定时器分类
- 内核定时器(CortexM):SysTick系统节拍定时器
- 外设定时器(STM32):TIM基本、通用、高级定时器、看门狗定时器、实时时钟RTC、低功耗定时器
TIM_Base时基单元:内部时钟模式
主要功能:用内部时钟,定时触发事件/中断
数据通路
内部时钟APB timer→时钟源选择SMCR(ECE、SMS)→时基单元→中断→NVIC→CPU
时基单元TIM_Base:输入脉冲(N1*N2个)→预分频模块→计数模块→输出脉冲(1个)
- 预分频模块:
预分频计数器+预分频寄存器 - 计数模块:
核心计数器+自动重载寄存器+计数器寄存器
预分频模块
- 预分频计数器:主要用于分频,计数值为0→PSC,分频系数为N1=PSC+1
- 预分频寄存器:预分频系数PSC(计数终值)
计数模块
- 核心计数器:可用于分频或计数
- 自动重载寄存器:设置自动重载系数ACC(计数初值或终值)
- 计数器寄存器:记录当前计数值CNT
计数模式:针对核心计数器
- 递增计数:0→ARR(上溢)
- 递减计数:ARR→0(下溢)
- 中心对齐计数:0→ARR-1(上溢)、ARR→0(下溢)
时基单元的定时功能
- 输入时钟信号:APB的定时器时钟TIM_CLK
- 输入时钟信号fp,经过预分频模块和计数模块的两次分频,最终产生特定周期T(频率为f)的时钟信号
f=1/T=fp*(1/N1)*(1/N2)→T*fp=N1*N2=(PSC+1)*(ACC+1)→PSC=N1-1,ACC=N2-1
硬件设计
- TIM10挂接在APB2总线上,定时器时钟TIM2_CLK为100MHz
- 若产生10ms定时中断:
10ms*100MHz=10000*1000 - 即PSC=10000-1、ARR=1000-1
CubeMX的配置
- 引脚分配:无
- 外设配置:
- Timers-TIM10 →模式→ 勾选Activated
- Timers-TIM10 →参数设置(时基单元设置)→ PSC预分频器=10000-1、ARR自动重载寄存器=100-1、计数器模式=递增up、内部时钟分频器=不分频、auto-reload preload=disable
- System Core-NVIC-NVIC中断表 →TIM1 update interrupt and TIM10 global interrupt→ 勾选使能、并设置抢占优先级和子优先级
用户代码
//USER CODE2:外设启动
__HAL_TIM_CLEAR_IT(&htim10, TIM_IT_UPDATE);//清除定时器初始化过程中的中断标志、避免定时器一启动就进入中断
HAL_TIM_Base_Start_IT(&htim10); // 启动定时器中断、启动定时器
//USER CODE4:定义中断回调函数
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim){
if(htim->Instance==TIM10){//判断更新中断来源
}
}
TIM_Base时基单元:ETR外部时钟模式2
主要功能:对外部输入脉冲进行计数
数据通路:
TIM_ETR引脚→GPIO输入电路→GPIO的AFR→预分频PSC=0(影子寄存器)→核心计数器CNT
时基单元的外部脉冲计数功能
- 输入脉冲信号:捕获/比较通道CH、外部触发引脚ETR
- PSC通常置0
- ACC通常置为特别大的值(防止计数结束前发生溢出)
- 读取CNT中的计数值
硬件设计
PA0复用为TIM2_ETR,用来接收外部的脉冲信号
CubeMX的配置
- 引脚分配:
- 在外设配置时,可自动将PA0复用为TIM2_ETR
- 外设配置:
- Timers-TIM2 → 模式 →时钟源=ETR2
- Timers-TIM2 → 参数设置(时基单元设置)→ PSC预分频器=0、ARR自动重载寄存器=0xFFFFFFFF、计数器模式=向上、内部时钟分频器=不分频、auto-reload preload=disable
- Timers-TIM2 → 参数设置(时钟源)→ 时钟滤波=0、时钟极性=不反向、时钟分频=不分频
用户代码
HAL_TIM_Base_Start(&htim2);//启动定时器
uint32_t Result = __HAL_TIM_GET_COUNTER(&htim2); // 读取外部脉冲计数值
TIM_OC输出比较单元
时基单元TIM_Base为内部时钟模式:CNT从初值→CCR→终值循环变化
捕获/比较寄存器CCR→输出控制→引脚TIM_CH(输出比较通道)
TIM_CH的输出比较模式分类:
- PWM1:
[初值→CCR)时输出有效电平、[CCR→终值]时输出无效电平(PWM2相反)(脉冲宽度调制波形) - ACTIVE:
CNT=CCR(匹配)时输出有效电平、不匹配时输出无效电平(INACTIVE相反)(单脉冲模式) - TOGGLE:
CNT=CCR(匹配)时输出电平翻转 - TIMING:
CNT=CCR(匹配)时无通道输出(冻结模式) - FORCED_ACTIVE:强制输出有效电平
- FORCED_INACTIV:强制输出无效电平
TIM_CH输出有效电平的极性:高电平有效、低电平有效
脉冲宽度调制Pulse Width Modulation:对模拟信号电平进行数字编码的方法,应用于灯光亮度调节、功率控制、电机控制等领域
- 周期Period:一个完整PWM波形所持续时间(时基单元提供)
- 占空比Duty:
(高电平持续时间Ton/PWM周期)x100%(输出比较单元提供)

硬件设计
PA5复用为TIM2_CH1,产生周期为1ms,占空比为47.5%的PWM信号
- TIM2挂接在APB2总线上,定时器时钟TIM2_CLK为100MHz
- PWM的周期为200ms:
1ms*100MHz=100*1000设PSC=100-1、ARR=1000-1、向上计数 - 占空比为47.5%,若使用PWM1、输出极性为高电平有效、则CCR为475
CubeMX的配置
- 引脚分配:
- Pinout View:搜索PA5 设置为TIM2_CH1
- 外设配置:
- Timers-TIM2 →模式→ 时钟源=内部时钟源、Channel1=PWM通用CH1
- Timers-TIM2 →参数设置(时基单元设置)→ PSC预分频器=100-1、ARR自动重载寄存器=1000-1、计数器模式=向上、内部时钟分频器=不分频、auto-reload preload=disable
- Timers-TIM2 →参数设置(PWM输出通道设置)→ 模式=PWM mode1、脉冲(CCR)=475、通道极性=高电平有效、输出比较预装载=使能(PWM波形循环)、快速模式:禁用
用户代码
//USER CODE2:外设启动
HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_1);
//USBR CODE3:后台程序(无限循环)
//呼吸灯:PWM的不同占空比时,在人眼的视觉暂留效果,导致LED看起来“不同亮度”
//扫描频率需大于50Hz(周期20ms),以避免闪烁
__HAL_TIM_SET_COMPARE(&htim2,TIM_CHANNEL_1,Duty);//步进20%的占空比
HAL_Delay(100);
TIM_IC输入捕获单元
主要功能:测量信号的参数,比如周期和频率
- 被测信号的周期 = 两次上升沿CNT的差值 x ( PSC + 1 ) / 时基单元周期
引脚TIM_CH(输入捕获通道)→输入滤波→边沿检测→当前通道直接输入方式、其他通道的间接输入方式→预分频器→捕获/比较寄存器CCR
- 当TIM_CH的上升沿或下降沿时,将CNT的值写入到CCR中


硬件设计
PA0复用为TIM2_CH1,输入捕获
PA6复用为TIM3_CH1,比较输出PWM,即被测信号源(100KHz占空比50%的方波)
CubeMX的配置
- 引脚分配:
- Pinout View:搜索PA0 设置为TIM2_CH1
- 外设配置:
- Timers-TIM2 →模式→ 时钟源=内部时钟源、Channel1=输入捕获 直接模式
- Timers-TIM2 →参数设置(时基单元设置)→ PSC预分频器=0、ARR自动重载寄存器=0xFFFFFFFF、计数器模式=向上、内部时钟分频器=不分频、auto-reload preload=disable
- Timers-TIM2 →参数设置(输入捕获通道1设置)→ 极性选择=上升沿、输入捕获通道IC选择=直接输入模式、预分频器分频比=不分频、输入滤波=0
用户代码
uint32_t Diff = 0 ; // 存放捕获差值
uint8_t MeasureFlag = 0 ; // 测量完成标志:0表示未完成,1表示完成
uint8_t CapIndex = 0 ; // 捕获指示:0表示没有开始捕获,1表示完成一次捕获
uint32_t CapVal1 = 0 ; // 存放第一次捕获值
uint32_t CapVal2 = 0 ; // 存放第二次捕获值
//USER CODE2:外设启动
HAL_TIM_IC_Start_IT(&htim2, TIM_CHANNEL_1); // 启动定时器2通道1的输入捕获功能
//USBR CODE3:后台程序(无限循环)
if( MeasureFlag == 1){ // 判断测量标志是否置位
Diff =CapVal2 >= CapVal1?(CapVal2 - CapVal1):(0xFFFFFFFF + 1 - CapVal1 + CapVal2); // 计算差值
printf ("Period is: %.4f ms\r\n",(double)Diff/100000); // 计算信号周期
MeasureFlag = 0; // 清除测量完成标志
HAL_Delay(1000);
HAL_TIM_IC_Start_IT(&htim2, TIM_CHANNEL_1); // 启动下一次捕获
}
//USER CODE4:定义中断回调函数
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim){
if(htim->Instance==TIM2){//判断发生捕获中断的定时器
if(htim->Channel==HAL_TIM_ACTIVE_CHANNEL_1){//判断发生捕获中断的通道
if(CapIndex == 0){ //存放第一次捕获时CCR的值
CapVal1=HAL_TIM_ReadCapturedValue(&htim2, TIM_CHANNEL_1);
CapIndex=1;
}else if(CapIndex == 1){//存放第二次捕获时CCR的值
CapVal2=HAL_TIM_ReadCapturedValue(&htim2, TIM_CHANNEL_1);
HAL_TIM_IC_Stop_IT(&htim2, TIM_CHANNEL_1); // 停止捕获
CapIndex=0; //重置捕获标志
MeasureFlag=1;//测量完成的结束标志
}
}
}
}
STM32外设:定时器TIM的更多相关文章
- STM32通用定时器(转载)
STM32的定时器功能很强大,学习起来也很费劲儿. 其实手册讲的还是挺全面的,只是无奈TIMER的功能太复杂,所以显得手册很难懂,我就是通过这样看手册:while(!SUCCESS){看手册-}才搞明 ...
- STM32 基于定时器的PWM发生器
脉冲宽度调制(PWM),是英文"Pulse Width Modulation" 的缩写,简称脉宽调制,是利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术.简单一点,就 ...
- Stm32高级定时器(三)
Stm32高级定时器(三) 1 互补输出和死区插入 1.1 死区:某个处于相对无效状态的时间或空间 本来OCX信号与OCXREF时序同相同步,OCXN信号与OCXREF时序反相同步.但为了安全考虑,以 ...
- STM32通用定时器原理
/************************************************************************************************ 转载 ...
- STM32 通用定时器的几种配置方式
STM32 通用定时器的几种配置方式 //------------------------------------------------------------------------------ ...
- STM32通用定时器配置
一.STM32通用定时器原理 STM32 系列的CPU,有多达8个定时器,其中TIM1和TIM8是能够产生三对PWM互补输出的高级定时器,常用于三相电机的驱动,它们的时钟由APB2的输出产生.其它6个 ...
- stm32基本定时器timer6的原理与使用
/********************基本定时器 TIM 参数定义,只限 TIM6.7************/ /* 一.定时器分类 STM32F1 系列中,除了互联型的产品,共有 8 个定时器 ...
- STM32——通用定时器基本定时功能
STM32——————通用定时器基本定时功能 1. ...
- Stm32高级定时器(四)
Stm32高级定时器(四) 1 编码器接口模式 1.1 编码器原理 什么是正交?如果两个信号相位相差90度,则这两个信号称为正交.由于两个信号相差90度,因此可以根据两个信号哪个先哪个后来判断方向.根 ...
- Stm32高级定时器(二)
Stm32高级定时器(二) 1 主从模式:主?从? 谈论主从,可知至少有两个以上的触发或者驱动信号,stm32内部有多个定时器,可以相互之间驱动或者控制. 主模式:定时器使能只受驱动时钟控制或者输出控 ...
随机推荐
- ubuntu20.4操作指令合集
每个指令前面尽量加上sudo,避免麻烦的权限问题 下载软件:sudo apt install 包名 开启/关闭防火墙(开启/关闭所有端口):sudo ufw enable/disable 防火墙状态: ...
- Flutter系列文章-Flutter应用优化
当涉及到优化 Flutter 应用时,考虑性能.UI 渲染和内存管理是至关重要的.在本篇文章中,我们将通过实例深入讨论这些主题,展示如何通过优化技巧改进你的 Flutter 应用. 代码性能优化 1. ...
- P4327题解
思路 分组计算 以下图为例: ..#.. .#.. .*.. .#.. .#.#. #.#. *.*. #.#. #.X.# .X.* .X.* .X.# .#.#. #.#. *.*. #.#. . ...
- langchain中的LLM模型使用介绍
简介 构建在大语言模型基础上的应用通常有两种,第一种叫做text completion,也就是一问一答的模式,输入是text,输出也是text.这种模型下应用并不会记忆之前的问题内容,每一个问题都是最 ...
- SQL - 5
Smiling & Weeping ----我本不想和风讨论你,可风说可以替我去见你 第五章:SQL高级处理 5.1 窗口函数 5.1.1 窗口函数概念及基本的使用方法 窗口函数也称为OLAP ...
- 浅谈TCP协议的发生过程
1. TCP协议 1.1 TCP协议的性质 面向连接的.可靠的.基于字节流 至于为什么面向连接,又为什么可靠,基于字节流的,等后面便可知道. 1.2 TCP协议栈收发数据的四个阶段 创建套接字 连接服 ...
- Quantitative Relationship Induction
数量关系是指事物之间的数值或数量之间的相互关系(+.-.*./). 数量关系描述各种量的变化和相互关系.数量关系可以包括数值的比较.增减.比例.百分比.平均值等方面. 在数学中,数量关系可以通过代数方 ...
- 给网站添加xml地图索引写法和应用
使用php给网站添加xml地图索引写法 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 ...
- 在 Rust 中实现 Repository 仓储模式
前言 单位上有个 Rust 项目,orm 选型很长时间都没定下来,故先设计了抽象的仓储层方便写业务逻辑. 设计抽象接口 抽象只读接口,仅读取使用,目前需求仅用查询 id.查询全部和按名称搜索,当然理应 ...
- vscode提取扩展时出错XHR failed
问题分析 使用cmd的ping工具尝试ping域名 marketplace.visualstudio.com 无法ping通 解决方案 1. 打开本地配置文件 C:\Windows\System32 ...