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内部有多个定时器,可以相互之间驱动或者控制. 主模式:定时器使能只受驱动时钟控制或者输出控 ...
随机推荐
- 基于 ASP.NET 的投票系统
OnlineVoting 基于 ASP.NET 的投票系统 功能页面 登录 注册 首页 投票广场 查看别人发布的投票. 个人中心 个人资料 换头像.修改密码和其他信息. 发布投票 项目地址:https ...
- Redis系列18:过期数据的删除策略
Redis系列1:深刻理解高性能Redis的本质 Redis系列2:数据持久化提高可用性 Redis系列3:高可用之主从架构 Redis系列4:高可用之Sentinel(哨兵模式) Redis系列5: ...
- centos7.X安装nginx – 东凭渭水流
1.安装nginx需要使用root用户 2.配置nginx源 rpm -ivh http://nginx.org/packages/centos/7/noarch/RPMS/nginx-release ...
- 三维模型OSGB格式轻量化压缩点云处理技术探讨
三维模型OSGB格式轻量化压缩点云处理技术探讨 点云是一种常用的三维模型表示方法,由于其具有高精度.高保真度.易处理等优点,因此在很多领域都得到了广泛应用.但是,点云数据的存储量通常比较大,为了使点云 ...
- 在Jupyter中使用AI写代码,如有神助,太惊艳了
昨晚看到一个可以在JupyterLab中使用的AI代码辅助工具jupyter-ai,它的交互确实非常棒,可以直接聊天,也可以就笔记中的代码提问,最出彩的是生成笔记功能,还是蛮惊艳的. 这里就极简介绍一 ...
- GIT提交修改的项目到远程仓库
1.在项目目录下右键选择Git Bash. 2.执行提交命令三部曲 git add . //文件-暂存区,即将所有新增的文件添加到提交索引中,,add后面是"空格 点"就表示当前目 ...
- MySQL实战实战系列 06 全局锁和表锁 :给表加个字段怎么有这么多阻碍?
今天我要跟你聊聊 MySQL 的锁.数据库锁设计的初衷是处理并发问题.作为多用户共享的资源,当出现并发访问的时候,数据库需要合理地控制资源的访问规则.而锁就是用来实现这些访问规则的重要数据结构. 根据 ...
- 《流畅的Python》 读书笔记 230926
写在最前面的话 缘由 关于Python的资料市面上非常多,好的其实并不太多. 个人认为,基础的,下面的都还算可以 B站小甲鱼 黑马的视频 刘江的博客 廖雪峰的Python课程 进阶的更少,<流畅 ...
- 爬虫系列——Scrapy
文章目录 一 介绍 二 安装 三 命令行工具 四 项目结构以及爬虫应用简介 五 Spiders 六 Selectors 七 Items 八 Item Pipeline 九 Dowloader Midd ...
- Aoba's GitLab Doki Theme - 一个简单的 GitLab 主题工具
前言 平常工作在用 GitLab 但总觉得缺点什么颜色好单调,于是随手摸了一个主题工具 界面预览 GitLab 主页效果 个人偏好配置页面 安装方法 安装 Tampermonkey 之类的用户脚本工具 ...