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内部有多个定时器,可以相互之间驱动或者控制. 主模式:定时器使能只受驱动时钟控制或者输出控 ...
随机推荐
- python实现创建一个银行类,这个类实现了两个方法,第一个方法可以将用户信息写入到文件中,第二个方法可以读取文件中的用户信息出来
class bank: def user_info(self): a=input('请输入用户信息:') # 不写encoding = 'utf-8'中文会乱码 with open('info.txt ...
- PhotoShop Beta(爱国版)安装教程-内置AI绘画功能
PS beta版安装教程 Window和Mac版都有,里面内置AI绘画功能 ps Beta版真的太爽了,今天来和大家分享下安装教程. 很多人拿这资料卖5块 9.9 19.9,球友们直接用,建议赶紧装, ...
- Python从0到1丨详解图像锐化的Sobel、Laplacian算子
本文分享自华为云社区<[Python从零到壹] 五十八.图像增强及运算篇之图像锐化Sobel.Laplacian算子实现边缘检测>,作者: eastmount . 一.Sobel算子 So ...
- RK3568开发笔记(十):开发板buildroot固件移植开发的应用Demo,启动全屏显示
前言 上一篇,移植应用前的通讯接口工作和全屏工作都已经完成了.本篇移植开发的商业应用. 交叉编译好应用 (略),参照<RK3568开发笔记(八):开发板烧写buildroot固件(支 ...
- strimzi实战之一:简介和准备
欢迎访问我的GitHub 这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos 关于strimzi strimzi是一个开源项目,已加 ...
- MySQL数据库操作 Lab1
实验一 MySQL数据库操作 实验目的: 掌握MySQL安装.配置与登录方法,使用MySQL客户创建数据库及对数据库表完成各种操作 实验内容: 1. 安装MySQL数据库管理系统, ...
- HCTF 2023 wp
HCTF 2023 wp 一.Misc 1.玩原神玩的 分析:附件为一张图片 观察最后一行,明显有flag的格式 搜索得知是 对照得flag为:hctf{yuanlainiyewanyuanshenh ...
- Go包介绍与初始化:搞清Go程序的执行次序
Go包介绍与初始化:搞清Go程序的执行次序 目录 Go包介绍与初始化:搞清Go程序的执行次序 一.main.main 函数:Go 应用的入口函数 1.1 main.main 函数 1.2 main.m ...
- 浅析 C# Console 控制台为什么也会卡死
一:背景 1. 讲故事 在分析旅程中,总会有几例控制台的意外卡死导致的生产事故,有经验的朋友都知道,控制台卡死一般是动了 快速编辑窗口 的缘故,截图如下: 虽然知道缘由,但一直没有时间探究底层原理,市 ...
- 19. 从零开始编写一个类nginx工具, 配置数据的热更新原理及实现
wmproxy wmproxy是由Rust编写,已实现http/https代理,socks5代理, 反向代理,静态文件服务器,内网穿透,配置热更新等, 后续将实现websocket代理等,同时会将实现 ...