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内部有多个定时器,可以相互之间驱动或者控制. 主模式:定时器使能只受驱动时钟控制或者输出控 ...
随机推荐
- 程序后台运行方法:使用守护进程 或 screen软件
我们常需要SSH远程登录到Linux 服务器,经常运行一些需要很长时间才能完成的任务,在此期间不能关掉窗口或者断开连接,否则这个任务会被杀掉,一切就半途而废了. 可以使用以下两个方法: 方法一:noh ...
- Windows平台的JDK安装及IDEA配置JDK的过程
1.下载安装包 jdk-8u201-windows-x64.exe,即jdk1.8.0_201 链接:https://pan.baidu.com/s/1WYaTlProtHkC_KyMHIUBxQ?p ...
- Prism报错
Rules.Default..WithoutFastExpressionCompiler()报错 说没有找到容器 1.查看Prism.Wpf源码 获取DryIoc容器规则 2.证明项目中出现了另外一个 ...
- 【JMeter】使用BeanShell写入内容到文件
使用BeanShell写入内容到文件 目录 使用BeanShell写入内容到文件 一.前言 二.提取 三.写入 一.前言 在我们日常工作中,可能会遇到需要将请求返回的数据写入到文件中.在我们使用J ...
- uni-app+h5puls 编写相机拍照
<template> <view class="camera-page"> <image :src="imgSrc" v-if=& ...
- CodeForces 1343D Constant Palindrome Sum
题意 多组样例 给一个长度为\(n\)(\(n\)一定为偶数)的数组\(a[]\),给一个正整数\(k\),保证数组内元素为小于等于\(k\)的正整数,你可以每次将数组的一个元素变为小于等于\(k\) ...
- 云原生 | 企业内使用 CoreDNS 构建高性能、插件化的DNS服务器
[点击 关注「 全栈工程师修炼指南」公众号 ] 设为「️ 星标」带你从基础入门 到 全栈实践 再到 放弃学习! 涉及 网络安全运维.应用开发.物联网IOT.学习路径 .个人感悟 等知识分享. 希望各位 ...
- 杰哥教你面试之一百问系列:java集合
目录 1. 什么是Java集合?请简要介绍一下集合框架. 2. Java集合框架主要分为哪几种类型? 3. 什么是迭代器(Iterator)?它的作用是什么? 4. ArrayList和LinkedL ...
- 4399 Flash游戏专用浏览器, 无需安装Flash插件
目前所有的主流浏览器都已经不再支持Flash了,即使有一些国内浏览器还支持flash,但只能安装国内特供版Flash Player. 但问题的关键在于,这个国内特供版跟 Adobe 海外发行的版本是两 ...
- 在 Net7.0环境下通过反射创建泛型实例和调用泛型方法
一.介绍 最近没事干,就用闲暇时间写点东西,也记录一下温习历程.老人说的好,好记性,不如烂笔头.时间一长,当时记忆的再清楚,都会变得模糊,索性就写博客记录下来,如果下次需要,直接打开博客就找到了,不用 ...