【STM32】HAL库-通用定时器

2023-05-16

简介

通用定时器是一个通过可编程预分频器驱动的16位自动装载计数器构成。
它适用于多种场合,包括测量输入信号的脉冲长度(输入捕获)或者产生输出波形(输出比较和PWM)。
使用定时器预分频器和RCC时钟控制器预分频器,脉冲长度和波形周期可以在几个微秒到几个毫秒间调整。
每个定时器都是完全独立的,没有互相共享任何资源。

在这里插入图片描述

在这里插入图片描述

时基单元

软件可以读写计数器CNT、自动重装载寄存器ARR和预分频寄存器PSC,即使计数器运行时也可以操作。

  • 当前计数值寄存器CNT
    向上计数可随时修改

  • 自动重装载寄存器ARR
    可随时修改,具有影子寄存器,根据TIMx_CR1寄存器中的自动重装载预加载使能位(ARPE),写入ARR寄存器的内容能够立即或在每次更新事件(UEV)时,传送到它的影子寄存器。真正起作用的是其影子寄存器
    在这里插入图片描述

  • 预分频寄存器PSC
    可随时修改,具有影子寄存器,具有缓冲,新的预分频数值将在下一个更新事件时起作用(发生更新事件(UEV)时才将值传送到其影子寄存器中)。

更新事件UEV的使能与来源

  • 更新事件UEV的使能位
    TIMx_CR1寄存器的UDIS位
    在这里插入图片描述
    UDIS位为0则将不再产生更新事件,但计数器和预分频器的计数器依然会在应产生更新事件时重新从0开始计数
    UDIS位为1,当发生一次更新事件时所有影子寄存器会被更新
  • 更新事件UEV的来源
    更新中断和DMA请求的来源
    TIMx_CR1寄存器的URS位
    在这里插入图片描述

软件触发更新事件

写入事件产生寄存器TIM_EGR寄存器的UG位
置位UG位则产生更新事件
如果设置了TIMx_CR1寄存器中的URS位(选择更新请求) ,设置UG位可以产生一次更新事件UEV,但不设置UIF标志(即没有中断或
DMA请求)。
这是为了避免在捕获模式下清除计数器时,同时产
生更新和捕获中断。
在这里插入图片描述

计数模式

设置TIMx_CR1中的DIR方向位来选择计数方向

  • 向上计数模式
    在向上计数模式中,计数器从0计数到自动加载值(TIMx_ARR计数器的内容),然后重新从0开始计数并且产生一个计数器溢出事件。

  • 向下计数模式
    在向下模式中,计数器从自动装入的值(TIMx_ARR计数器的值)开始向下计数到0,然后从自动装入的值重新开始并且产生一个计数器向下溢出事件。

  • 中央对齐计数模式(向上/向下计数)
    在中央对齐模式,计数器从0开始计数到自动加载的值(TIMx_ARR寄存器)−1,产生一个计数器溢出事件,然后向下计数到1并且产生一个计数器下溢事件;然后再从0开始重新计数。在每次计数上溢和每次计数下溢时产生更新事件
    在这个模式,不能写入TIMx_CR1中的DIR方向位。它由硬件更新并指示当前的计数方向。
    可以通过(软件或者使用从模式控制器)设置TIMx_EGR寄存器中的UG位产生更新事件。然后,计数器重新从0开始计数,预分频器也重新从0开始计数。

时钟源

定时器时钟来源CK_PSC

  • 内部时钟(CK_INT)
  • 外部时钟模式1:外部输入脚(TIx)
  • 外部时钟模式2:外部触发输入(ETR)
  • 内部触发输入(ITRx):使用一个定时器作为另一个定时器的预分频器,如可以配置一个定时器Timer1而作为另一个定时器Timer2的预分频器。

CNT计数器的时钟由CK_CNT提供,CK_CNT的时钟频率等于fCK_PSC/(PSC[15:0]+1)

  • 内部时钟(CK_INT)
    如果禁止了从模式控制器(TIMx_SMCR寄存器的SMS=000),则CEN、DIR(TIMx_CR1寄存器)和UG位(TIMx_EGR寄存器)是事实上的控制位,并且只能被软件修改(UG位仍被自动清除)。只要CEN位被写成’1’,预分频器的时钟就由内部时钟CK_INT提供。

外部时钟模式1

当TIMx_SMCR寄存器的SMS=111时,此模式被选中。计数器可以在选定输入端的每个上升沿或下降沿计数。
在这里插入图片描述
配置过程
在这里插入图片描述

定时器-外部时钟模式1-上升沿计数demo

采用STM32F103C8T6单片机,KeilMDK5.32版本

定时器时钟源为外部时钟1,由TI2FP2(PA1)提供,在TI2FP2的上升沿计数
当发生更新事件触发中断后,串口发送数据updata到上位机

STM32CubeMX配置

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
定时器更新中断回调函数
在这里插入图片描述

工程文件下载链接

外部时钟模式2

选定此模式的方法为:令TIMx_SMCR寄存器中的ECE=1
计数器能够在外部触发ETR的每一个上升沿或下降沿计数。

在这里插入图片描述
配置过程
在这里插入图片描述

定时器-外部时钟模式2-上升沿计数demo

采用STM32F103C8T6单片机,KeilMDK5.32版本

定时器时钟源为外部时钟2,由ETP(PA0)提供,在ETP的上升沿计数
当发生更新事件触发中断后,串口发送数据(Updata)到上位机

STM32CubeMX配置
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
定时器更新中断回调函数
在这里插入图片描述
工程文件下载链接

输入捕获

输入部分对相应的TIx(引脚上的电平)输入信号采样,并产生一个滤波后的信号TIxF(逻辑信号0/1)。然后,一个带极性(上升沿/下降沿)选择的边缘检测器产生一个信号(TIxFPx),它可以作为从模式控制器的输入触发或者作为捕获控制。该信号(TIxFPx)通过预分频(预分频器内部含有一个预分频计数器,用来计TIxFPx的数目)进入捕获寄存器(ICxPS)。

通道1为例的输入捕获通道框图
通过CC1S来选择IC1的信号来源
通过ICPS来选择几个IC1信号等效于IC1PS信号。
在这里插入图片描述
在这里插入图片描述

在捕获模式下,捕获发生在影子寄存器上,然后再复制到预装载寄存器中。
在发生捕获时候,计数器CNT的值会被复制到捕获/比较影子寄存器中,然后从影子寄存器中再复制到捕获/比较预装载寄存器中。

在输入捕获模式下,当检测到ICx信号上相应的边沿后,计数器的当前值被锁存到捕获/比较寄存器(TIMx_CCRx)中当捕获事件发生时,相应的CCxIF标志(TIMx_SR寄存器)被置’1’,如果使能了中断或者DMA操作,则将产生中断或者DMA操作。如果捕获事件发生时CCxIF标志已经为高,那么重复捕获标志CCxOF(TIMx_SR寄存器)被置’1’。写CCxIF=0可清除CCxIF,或读取存储在TIMx_CCRx寄存器中的捕获数据也可清除CCxIF。写CCxOF=0可清除CCxOF。

配置过程

在这里插入图片描述

在这里插入图片描述
fDTS的时钟频率通过控制寄存器 1(TIMx_CR1) 的CKD位控制在这里插入图片描述

输入捕获-下降沿捕获-软件触发更新事件CNT

采用STM32F103C8T6单片机,KeilMDK5.32版本

定时器的使用内部时钟源
CK_PSC = CK_INT = 72MHz
CK_CNT = 10KHz 计数器每计数一个数耗时0.0001s = 100us = 0.1ms
预分频器为72MHz / 10KHz = 7200 - 1 = 7199
计数器重装载值为65535 故最长计数为6.5535秒
PA0为定时器输入捕获通道1(CH1),下降沿捕获,CH1连接IC1
根据实际需求PA0配置PA0的模式 输入模式 上/下拉电阻
PC13控制LED灯,用杜邦线连接PA0与PC13,捕获LED的亮灭时间
开启更新中断,输入捕获通道1中断。在输入捕获回调函数中将计数CNT寄存器的值清零(在向上计数模式下)。也可以软件触发更新事件,但是需要将URS位置位(仅只有计数器溢出/下溢才产生更新中断或DMA请求)

发生捕获将flag |= 0x02,主函数中检查并复位flag,并输出信息到串口
延时1000ms,LED亮灭时间各持续一秒,下降沿捕获,故串口输出的值为2000ms左右。

在这里插入图片描述
回调函数
如果高电平/低电平的持续时间,需要写定时器溢出的逻辑代码
在这里插入图片描述
定时器初始化函数中,添加用户代码
置位USR位,在开启中断前西安清零相应标志位
在这里插入图片描述
定时器初始化注意点:
因为预分频PSC寄存器和重装载ARR寄存器有影子寄存器,真正起作用的是影子寄存器,在发生更新事件时,才将其值更新到其影子寄存器中,故在配置定时器后,需要软件触发更新时间(置位TIMx_EGR寄存器的UG位,此时URS位需为0)。重装载ARR寄存器也可以根据(TIMx_CR1寄存器的ARPE位来确定有没有缓冲,没有缓冲则立刻将其值更新到其影子寄存器中。
HAL库中TIM_Base_SetConfig()的代码也是这样写的,如下
在这里插入图片描述
STM32CubeMX配置
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
工程文件下载链接

串口使用了DMA,必须先初始化DMA再初始化串口,其他外设类似。 STM32CubeMX的BUG
在这里插入图片描述

PWM输入捕获

在这里插入图片描述

PWM输入捕获,用来测量PWM信号的周期与占空比,如下图:
在这里插入图片描述

复位模式 – 选中的触发输入(TRGI)的上升沿重新初始化计数器,并且产生一个更新寄存器的信号。

  1. IC1上升沿捕获发生时,会产生一个TRGI信号,但是TRGI信号有一定延时,CCR1捕获寄存器复制CNT寄存器的值的时候,CNT寄存器还未复位。

  2. IC2下降沿捕获,不会产生TRGI信号,CCR2捕获寄存器复制CNT寄存器的值

  3. 同1

通过URS位来确定是否需要使用复位模式产生的中断
不需要则置位URS位
在这里插入图片描述

由于只有TI1FP1和TI2FP2连到了从模式控制器,所以PWM输入模式只能使用TIMx_CH1 /TIMx_CH2信号。

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

配置过程

在这里插入图片描述

PWM输入捕获-复位模式demo

采用STM32F103C8T6单片机,KeilMDK5.32版本

定时器的使用内部时钟源
CK_PSC = CK_INT = 72MHz
CK_CNT = 10KHz 计数器每计数一个数耗时0.0001s = 100us = 0.1ms
预分频器为72MHz / 10KHz = 7200 - 1 = 7199
计数器重装载值为65535 故最长计数为6.5535秒
PA0为定时器输入捕获通道1(CH1),上升沿捕获,CH1连接IC1
根据实际需求PA0配置PA0的模式 输入模式 上/下拉电阻
IC2连接CH1,下降沿捕获
复位模式,选择TRGI触发源选择TI1PF1
PC13控制LED灯,用杜邦线连接PA0与PC13,捕获LED的亮灭时间

复位模式会产生更新事件,根据URS位来确定是否要使用这个更新事件

定时器初始化函数用户添加的代码
在这里插入图片描述
回调函数
在这里插入图片描述

主函数
在这里插入图片描述

STM32CubeMX配置
在这里插入图片描述
在这里插入图片描述
也可以使能触发中断

__HAL_TIM_ENABLE_IT(&htim2, TIM_IT_TRIGGER);

回调函数如下
在这里插入图片描述
工程文件下载链接

输出比较

此项功能是用来控制一个输出波形,或者指示一段给定的的时间已经到时。

在这里插入图片描述
在这里插入图片描述
输出模式如下图:

在这里插入图片描述
OCxM位的值:

  1. 000:CCR与CNT寄存器的值进行比较不能影响OC引脚的电平状态,被冻结,对OCxREF也没影响。
  2. 001:仅当CCR与CNT寄存器的值相等的这一时刻起作用(其他时刻不进行比较),将OC引脚的电平状态设置位有效电平,OCxREF为高电平。OC有效电平由捕获/比较使能寄存器(TIMx_CCER) 的CCxP位进行设置。
    在这里插入图片描述
  3. 010:仅当CCR与CNT寄存器的值相等的这一时刻起作用(其他时刻不进行比较) ,将OC引脚的电平状态设置位无效电平,OCxREF为低电平。
  4. 011:仅当CCR与CNT寄存器的值相等的这一时刻起作用(其他时刻不进行比较),OC引脚电平状态进行翻转,OCxREF也翻转。
  5. 100:不介绍
  6. 101:不介绍
  7. 110:PWM1,
    在向上计数模式下,TIMx_CNT<TIMx_CCR1,将OC引脚设置为有效电平,OCxREF设置为高电平;TIMx_CNT>TIMx_CCR1,OC引脚设置为无效电平,OCxREF设置为低电平
    在向下计数模式,TIMx_CNT<TIMx_CCR1,将OC引脚设置为有效电平,OCxREF设置为高电平;TIMx_CNT>TIMx_CCR1,OC引脚设置为无效电平,OCxREF设置为低电平。
  8. 111:PWM2与PWM相反

配置过程

在这里插入图片描述

PWM输出

脉冲宽度调制模式可以产生一个由TIMx_ARR寄存器确定频率、由TIMx_CCRx寄存器确定占空比的信号。

配置过程

  1. 选择计数器时钟(内部,外部,预分频器)
  2. 将相应的数据写入TIMx_ARR和TIMx_CCRx寄存器中
  3. 如果要产生一个中断请求和/或一个DMA请求,设置CCxIE位和/或CCxDE位。
  4. 选择输出模式(PWM1/PWM2),设置TIMx_CCMRx寄存器OCxPE位以使能相应的预装载寄存器(捕获/比较寄存器CCRx也有影子寄存器,置位OCxPE位来使能缓冲),设置TIMx_CR1寄存器的ARPE位(使能重装载寄存器的缓冲),OCx的有效极性在TIMx_CCER寄存器中的CCxP位设置
  5. 设置TIMx_CCER寄存器中的CCxE位控制OCx输出使能,设置TIMx_CR1寄存器的CEN位启动计数器
    在这里插入图片描述
    在PWM模式(模式1或模式2)下,TIMx_CNT和TIMx_CCRx始终在进行比较。
    当发生一个更新事件的时候,预装载寄存器才能被传送到影子寄存器,因此在计数器开始计数之前,必须通过设置TIMx_EGR寄存器中的UG位来初始化所有的寄存器。

计数模式

  • 向上计数
    在这里插入图片描述

  • 向下计数
    在这里插入图片描述

  • 中央对齐计数
    在这里插入图片描述

PWM输出-呼吸灯demo

采用STM32F103C8T6单片机,KeilMDK5.32版本

定时器的使用内部时钟源
CK_PSC = CK_INT = 72MHz
CK_CNT = 10KHz 计数器每计数一个数耗时0.0001s = 100us = 0.1ms
预分频器为72MHz / 10KHz = 7200 - 1 = 7199
计数器重装载值为100 故计数周期为10ms
PWM周期为10ms,计数器计一个数为0.1ms ,每25ms调整一次占空比(5~95%)
PA6为定时器PWM捕获通道1(CH1),捕获/比较寄存器的值初始化为5
PC13控制LED灯,用杜邦线连接PA6与PC13

在HAL库的定时器初始化函数中添加用户代码
在这里插入图片描述

主函数中每25ms调整一次占空比
在这里插入图片描述

STM32CubeMX配置
在这里插入图片描述
在这里插入图片描述
工程文件下载链接

单脉冲模式

单脉冲模式(OPM)是前述众多模式的一个特例。这种模式允许计数器响应一个激励,并在一个程序可控的延时之后,产生一个脉宽可程序控制的脉冲。
定时器仅运行一次,产生一次更新事件后,失能定时器。

可以在PWM输出模式下,设置定时器的分频,重装载值,捕获/比较寄存器的值,来输出PWM波。如下图,设置PWM的周期与占空比,输出一个长度可设置的脉冲信号。
在这里插入图片描述

单脉冲模式-PWM输出demo

采用STM32F103C8T6单片机,KeilMDK5.32版本

采用2个定时器
定时器2 为PWM输入捕获,复位从模式(触发则复位CNT寄存器),通道1(PA0)上升沿触发,IC1上升沿捕获,IC2下降沿捕获,开启IC1捕获中断。IC1和IC2连接到通道1(PA0),PA设置为下拉输入。分频为7200 计一个数为0.1ms,重装载值为65535。
定时器3为PWM输出模式,触发从模式(触发则使能定时器),通道2(PA7)下降沿触发,OC1(PA6)为PWM输出模式。分频为7200 计一个数为0.1ms,重装载值为100,CCR1寄存器为50,故OC1(PA6)PWM波周期为10ms,占空比为50%。
定时器3在单脉冲模式(发生更新事件则失能定时器,也就10ms后失能定时器)。
单脉冲模式负责失能定时器,触发从模式(通道2 PA7检测到上升沿信号)负责使能定时器。
PC13控制LED灯,每50ms亮灭一次。
用杜邦线连接PA0和PA6,连接PA7和PC13。
则输出的PWM波高电平持续时间为95ms,低电平为5ms,可以自己画一下波形图分析。

STM32CubeMX配置
定时器2设置
在这里插入图片描述
在这里插入图片描述
定时器3设置
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
HAL库的TIM2初始化函数添加用户代码
在这里插入图片描述
捕获回调函数
在这里插入图片描述
HAL库的TIM3初始化添加用户代码
在这里插入图片描述
主函数
在这里插入图片描述
工程文件下载链接

定时器的从模式

通用定时器有以下几种从模式,通过寄存器TIMx_SMCR寄存器中SMS位来选择从模式。
在这里插入图片描述

从模式的触发信号TRGI的来源,寄存器TIMx_SMCR寄存器中TS位
在这里插入图片描述
在这里插入图片描述

复位模式

计数器和它的预分频器能够重新被初始化;同时,如果TIMx_CR1
寄存器的URS位为低,还会产生一个更新事件UEV;然后所有的预装载寄存器(TIMx_ARR,TIMx_CCRx,TIMx_PSC)都会被更新。

典型例子 PWM输入捕获
定时器的通道1(IC1)配置为上升沿捕获,通道2(IC2)配置为下降沿捕获,通道1和通道2都连接CH1引脚,使能IC1的中断,定时器从模式选择为复位模式,从模式触发源为TI1FP1。

开始计数,CNT寄存器开始向上计数(假设定时器是在向上计数模式下工作)

如果TRGI信号被激活,即复位模式被激活,产生更新事件,则ARR、CCRx、PSC寄存器被更新(这些寄存器都有影子寄存器,起作用也是影子寄存器),CNT寄存器被清零(向上计数模式)。

当发送上升沿捕获的时候,

  1. CCR1影子寄存器复制当前CNT寄存器的值(此时CNT寄存器还没有被清零,因为有延时)
  2. TI1FP1信号被激活

步骤1和2是几乎同时进行的,
TI1FP1信号被激活,即TRGI信号被激活,即复位模式被激活,当复位模式激活时,CCR1影子寄存器已经完成了复制CNT寄存器的任务,复位模式将CNT寄存器清零,产生一个更新事件(如果使能更新中断,则会产生一个更新中断,更新事件会更新影子寄存器与其对应的寄存器),产生一个通道1(IC1)捕获中断,进入中断服务函数中。

当发送下降沿捕获的时候,不会触发复位模式的效果,仅CCR2寄存器捕获到CNT寄存器当前的值。

具体的PWM输入捕获配置请看PWM输入捕获章节,
工程文件下载链接

门控模式

当触发输入(TRGI)为高时,计数器的时钟开启。一旦触发输入变为低,则计数器停止(但不复位)。计数器的启动和停止都是受控的。

触发输入(TRGI)配置为上升沿,则高电平的时候计数器是正常计数,低电平的时候计数器暂停计数;配置为下降沿则相反。

定时器-门控模式-下降沿捕获demo

采用STM32F103C8T6单片机,KeilMDK5.32版本

定时器的使用内部时钟源
每计一个数0.1ms,最大计数值65535也就是6.5535秒。
开启定时器2通道1(PA0),配置为下降沿捕获,滤波值为3,定时器为门控模式,触发源TRGI为TI1FP1。开启定时器2全局中断,开启比较/捕获1中断
PC13控制LED,每200msLED亮灭状态翻转,用杜邦线连接PC13与PA0

在输入捕获回调函数中,利用串口发送捕获寄存器的值,按照LED200ms亮灭分析,得到在PC13亮灭状态各持续200ms,故串口应得到200ms的差距。亮则计数,灭则暂停计数。

STM32CubeMX配置
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
建议:设计电路的时候可根据需要添加上拉/下拉电阻。

主函数程序
在这里插入图片描述
定时器2初始化函数添加用户代码
在这里插入图片描述

注意:这里开启了输入捕获通道1中断,如果不添加上图红方框中的代码不会进入下图的输入捕获回调函数中。
原因:仅配置定时器为门控模式,并不会配置IC1为输入捕获模式。如果没有配置为输入捕获模式,则不会捕获CNT寄存器的值
HAL_TIM_IRQHandler()函数中
在这里插入图片描述

输入捕获回调函数

在回调函数中,利用串口发送捕获通道1寄存器的值。

在这里插入图片描述
串口助手显示的结果
在这里插入图片描述

工程文件下载链接

触发模式

计数器在触发输入TRGI的上升沿启动(但不复位),只有计数器的启动是受控的。

典型示例:单脉冲模式-PWM输出demo
工程文件下载链接

外部时钟模式1

选中的触发输入(TRGI)的上升沿驱动计数器。该时钟提供给CK_PSC

典型示例:定时器-外部时钟模式1-上升沿计数demo
工程文件下载链接

外部时钟模式2 + 从模式(门控/复位/触发)

外部时钟模式2可以与另一种从模式(外部时钟模式1和编码器模式除外)一起使用。
ETR信号被用作外部时钟的输入,在复位模式、门控模式或触发模式时可以选择另一个输入作为触发输入。

在这里插入图片描述
配置过程
在这里插入图片描述

定时器-外部时钟模式2-触发模式demo

采用STM32F103C8T6单片机,KeilMDK5.32版本

采用外部时钟模式2 作为时钟源
计数器在每个ETR(PA0)的上升沿计数一次;
从模式为触发模式,CH2(PA1)为上升沿捕获,开启IC2输入捕获中断。
PC13控制LED,用杜邦线连接PA0于PC13,LED每500ms亮灭一次(则计数周期为1000ms,每一秒计一个数)。
在输入捕获中断回调函数中,发送触发激活信息,即定时器开始计数。

STM32CubeMX配置
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
主函数代码
每500ms LED亮灭翻转
在这里插入图片描述
定时器初始化添加用户代码
在这里插入图片描述
输入捕获回调函数
在这里插入图片描述
工程文件下载链接

编码器模式

编码器接口模式基本上相当于使用了一个带有方向选择的外部时钟。
在这里插入图片描述
表:计数方向与编码器信号的关系
在这里插入图片描述

一个信号负责控制计时器的计数方向,一个信号负责提供计数脉冲,也就是时钟源。

例如编码器模式1 SMS = 001;
TI1负责控制计时器计数方向,TI2提供计数脉冲。

假设TI2每500ms翻转一次,也就是每500ms会出现一次边沿(上升沿/下降沿)
根据表:计数方向与编码器信号的关系,如果我们要维持计时器一直在向上模式下计数的话。
TI2在上升沿出现前,TI1必须为高电平,
TI2在下降沿出现前,TI1必须为低电平。

定时器-编码器模式1demo

采用STM32F103C8T6单片机,KeilMDK5.32版本

TI1(PA0)负责控制计时器计数方向,TI2(PA1)提供计数脉冲。
PC13控制LED的亮灭,PB0设置为推挽输出模式,PC13和PB0初始化电平都为低电平。每500ms,PC13和PB0电平状态翻转。
在编码器模式1下,保持计数器在向上计数模式下计数。
如果TI1/TI2需要捕获相应边沿,可自行设置,不影响编码器模式1的工作。

根据表:计数方向与编码器信号的关系,如果我们要维持计时器一直在向上模式下计数的话。
TI2在上升沿出现前,TI1必须为高电平,
TI2在下降沿出现前,TI1必须为低电平。

用杜邦线连接PC13与PA1(TI2)
PB0与PA0(TI1)

STM32CubeMX配置
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
定时器初始化函数添加用户代码
在这里插入图片描述
如果需要使用捕获功能,请开启定时器全局中断,并调用void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)输入捕获中断回调函数

主函数代码
保持定时器在向上计数模式,请对照表:计数方向与编码器信号的关系 分析代码。
在这里插入图片描述
工程文件下载链接

定时器同步

所有TIMx定时器在内部相连,用于定时器同步或链接。当一个定时器处于主模式时,它可以对另一个处于从模式的定时器的计数器进行复位、启动、停止或提供时钟等操作。

主模式下定时器输出TRGO信号,从模式下定时器接收到TRGO信号即TRGI信号,作出相应的动作(外部时钟模式1/复位/门控/触发)

主模式下的定时器触发信号TRGO的来源
在这里插入图片描述

这里给出一些应用:

使用一个定时器作为另一个定时器的预分频器

定时器周期性更新,更新事件到则触发TRGO到定时器2的TRGI中,即定时器的TRGO是定时器的TRGI(当然定时器2的TRGI来源要选择为定时器1,通过设置寄存器TIM2_SMCR寄存器的TS位),定时器在外部时钟模式1下,根据TRGI来计数。
在这里插入图片描述

配置过程
在这里插入图片描述

使用一个定时器作为另一个定时器的预分频器demo

采用STM32F103C8T6单片机,KeilMDK5.32版本

定时器2用内部时钟源72MHz,分频为7199,即计一个数耗时0.1ms,计数周期为10000,也就是一秒;定时器2更新信号会输出TRGO信号
定时器3外部时钟模式1,触发源为定时器输出的TRGO信号,分频为0,计数周期为2。

STM32CubeMX配置

定时器2的配置

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
定时器3配置
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

通过此表来设置定时器3的TRGI的来源,由表知,TIM3从模式TRGI信号应来于TIM2的输出TRGO信号,故应为ITR1(TS=001)

在这里插入图片描述
主函数代码
在这里插入图片描述
定时器2和定时器3全部初始化完成后,开启定时器2和定时器3的更新中断并使能定时器

定时器2的初始化函数添加用户代码
在这里插入图片描述
定时器更新中断回调函数
在这里插入图片描述
串口助手
每输出2次TIM2 Update后输出TIM3 Update,与一开始配置相同
在这里插入图片描述

工程文件下载链接

使用一个定时器使能另一个定时器

定时器发送输出TRGO信号(当然不仅仅更新事件能产生TRGO信号,还有使能信号、捕获/比较等等),另一个的定时器工作在门控/触发模式下。

使用一个定时器使能另一个定时器-主定时器触发模式demo

采用STM32F103C8T6单片机,KeilMDK5.32版本

定时器2的使能信号被用于作为触发输出(TRGO),定时器2工作在触发模式下,TRGI来源输入捕获的上升沿信号。
定时器3工作在触发模式下,TRGI来源定时器的TRGO。

定时器2 计数周期1000ms
定时器3 计数周期500ms

开启定时器2和3的更新中断,在更新中断回调函数发送相应的数据。

STM32CubeMX配置

TIM2配置
在这里插入图片描述

在这里插入图片描述
定时器3配置
在这里插入图片描述

在这里插入图片描述
主函数代码

先初始化主模式下的定时器,因为在定时器初始化函数中会手动置位UG(为了保证装载ARR,PSC的影子寄存器),而主模式下TRGO信号来源一开始默认是UG位(TIMx_CR2寄存器中的MSM位)。

如果先初始化从模式定时器3,定时器3工作在触发模式下,TRGI信号来源为定时器2的TRGO,而定时器2还未初始化,故TRGO信号来源默认是UG位,故在定时器2初始化过程中会置位UG位,从而触发定时器3的从模式触发模式,导致定时器3开始计数,而在本例中,定时器2和定时器3应该在定时器2的输入捕获通道1的上升沿出现的时候才开始计数,故需要先初始化定时器2
在这里插入图片描述
定时器更新中断回调函数
在这里插入图片描述

串口助手
在这里插入图片描述
工程文件下载链接

输入异或功能

TIMx_CR2寄存器中的TI1S位,允许通道1的输入滤波器连接到一个异或门的输出端,异或门的3个输入端为TIMx_CH1、TIMx_CH2和TIMx_CH3。
在这里插入图片描述

输入异或典型应用在与霍尔传感器的接口

用霍尔传感器进行电机马达的测速

定时器的三个输入端(有几个霍尔传感器就接几路输入端)通过一个异或门连接到TI1输入通道道(通过设置TIMx_CR2寄存器中的TI1S位来选择),“接口定时器”捕获这个信号。

定时器的从模式工作在复位模式下,触发TRGI的来源于TI1F_ED(上升沿和下降沿都会捕获/触发)

在这里插入图片描述

定时器由内部时钟源提供时钟,设置重装载值寄存器ARR和预分频器寄存器SPC保证计数周期长于霍尔传感器上的两次变化的时间间隔(如果霍尔传感器上的两次变化的时间间隔过长,超过定时器最大计数周期,则根据实际情况自行编写定时器更新事件超时逻辑代码)

复位模式下,每当3个输入之一变化时,TRGI被触发,则计数器从新从0开始计数。这样产生一个由霍尔输入端的任何变化而触发的时间基准。

输入捕获通道1的捕获触发源选择为TRC
在这里插入图片描述
捕获值反映了两个输入变化间的时间延迟,给出了马达速度的信息。

配置过程:

  1. 配置定时器的预分频器与重装载值寄存器
  2. 置TIMx_CR2寄存器的TI1S位为’1’,配置三个定时器输入逻辑或到TI1输入
  3. 设置输入捕获通道1的滤波值(寄存器TIMx_CCMR1的ICF[3:0])
  4. 不需要配置输入捕获通道1的边沿检测器(寄存器TIMx_CCER的CC1P位)
  5. 输入捕获通道1的捕获触发来源选择TRC(寄存器TIMx_CCMR1的CC1S[1:0]位 CC1S = 11)
  6. 输入捕获的分频值(寄存器TIMx_CCMR1的ICPS[1:0]位)
  7. 置TIMx_SMCR寄存器中SMS=100,配置定时器为复位模式;置TIMx_SMCR寄存器中TS=100,选择TI1F_ED作为输入源。
  8. 使能输入捕获通道1(设置TIMx_CCER寄存器的CC1E=1)
  9. 如果需要,通过设置TIMx_DIER寄存器中的CC1IE位允许相关中断请求,通过设置TIMx_DIER寄存器中的CC1DE位允许DMA请求。
    10.使能定时器 置位TIMx_CR1的CEN位
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【STM32】HAL库-通用定时器 的相关文章

随机推荐

  • VSCode调试C/C++项目

    最近写完了自己的操作系统 xff0c 深感有一个方便的调试环境是有多么重要 xff0c 能够提升不少开发效率 恰好最近在的技术交流群里群友在问如何搭建VSCode调试操作系统的环境 xff0c 刚考完试 xff0c 就先把这篇VSCode调
  • 误差与精度

    整理自 误差理论与数据处理 合肥工业大学 机械专业用于教授学生误差与精度概念的课程叫做 公差与测量 或者叫做 机械精度设计 xff0c 而公差或者精度的本质含义就是误差的大小 xff0c 公差越小 xff0c 误差越小 xff0c 精度越高
  • 两个类的头文件互相包含

    两个类的头文件互相包含 我做任务的时候遇到了两个类都互相包含对方的对象的问题 xff0c 本来是有错误的 xff0c 但经过我一番改动 xff0c 两个头文件互相包含同时 xff0c 每个头文件都含有令一个类的前置声明 虽然最后运行正确 x
  • 【C++ STL 容器】——vector

    概述 vector容器也被称作向量 xff0c 实现了动态的数组 xff0c 用于元素数量变化的对象数组 xff0c 算是比较常用的容器 常用函数 构造函数 vector 创建一个空vectorvector int size 创建一个vec
  • 2021-07-22

    MSP432在keil中通过CMSIS DAP下载程序出现cannot enter debug mode的解决办法 xff1a MSP432下载程序出现cannot enter debug mode 可以通过修改如下设置 Debug里面的两
  • 通信协议基础以及常用的串口通信协议

    通信协议 xff1a 串行通信和并行通信 在数据的通信方式中根据数据传输方式的不同可以分为 xff1a 串行通信和并行通信 串行通信 xff1a 串行通信是指使用一条数据线 xff0c 将数据一位一位地依次传输 xff0c 每一位数据占据一
  • Ubuntu安装ROS melodic,管理环境,创建工作空间

    一 安装ROS 1 设置源 xff1a sudo sh c 39 etc lsb release amp amp echo 34 deb http mirrors tuna tsinghua edu cn ros ubuntu 96 lsb
  • HTTP请求报文的结构组成及URL的结构组成

    HTTP请求报文 HTTP 超文本传输协议 Hypertext Transfer Protocol xff0c 简称HTTP 是应用层协议 HTTP 是一种请求 响应式的协议 xff0c 即一个客户端与服务器建立连接后 xff0c 向服务器
  • Qt之旅_001>>Qt常用窗口类之间的关系

    QApplication xff0c QGuiApplication QCoreApplication三者之间的关系 QCoreApplication处于core模块中 xff0c 为应用程序提供了一个非gui的时间循环 xff1b QGu
  • GPIO相关介绍

    文章目录 GPIO概念TXD与RXD GPIO的使用注意STM32IO口哪些兼容5V一定不要接超过5V的电压默认不能做输出的GPIO GPIO硬件原理图GPIO地址 GPIO的八种工作模式浮空输入带上拉输入带下拉输入模拟输入开漏输出推挽输出
  • STM32的常用C语言

    文章目录 一些被坑了的注意点 int16 define结构体与共用体指针 C语言发展史C语言概述C90 标准C99标准C11标准 C编译o代替c 条件语句else ifdo while 变量定义一个字符串字符串结尾 定义一个字符串数组sta
  • STM32应用霍尔转速传感器基于输入捕获

    这里我用通用定时器3的通道1来测量转速 霍尔转速传感器基本介绍霍尔传感器分类和原理关于为什么选用开关型常开PNP型霍尔传感器 STM32程序实现程序介绍程序源码TIM3 CAP HTIM3 CAP H解读TIM3 CAP CTIM3 CAP
  • Android so库开发——使用Studio生成自己的so库(一)

    一 创建Native项目 1 新建 Native 项目 1 xff09 新建项目 选择最下面的 Native C 43 43 下一步即可 2 xff09 填写项目信息 3 xff09 选择C 43 43 版本可以直接选择默认 2 下载并配置
  • C语言实现线性回归求斜率

    2020 11 22 修改 span class token comment 线性回归求斜率 注意数据类型 参数 count 数据个数 数组行 列 的个数 数组的行列数目相等 参数 dataCol X 数据的列数据 参数 dataRow Y
  • 【C语言】详解位域定义与使用

    位域的定义 span class token keyword struct span span class token class name bit span span class token punctuation span span c
  • C语言实现MQTT协议(一)协议讲解

    MQTT介绍 MQTT是一个客户端服务端架构的发布 订阅模式的消息传输协议 它的设计思想是轻巧 开放 简单 规范 xff0c 易于实现 这些特点使得它对很多场景来说都是很好的选择 xff0c 特别是对于受限的环境如机器与机器的通信 xff0
  • 【STM32】HAL库-外部中断

    外部中断框图 产生中断 硬件触发外部中断 配置中断屏蔽寄存器中的屏蔽位 xff0c 允许该外部中断请求 通过AFIO EXTICRx配置GPIO线上的外部中断 事件 xff0c 必须先使能AFIO时钟 选择外部中断的触发边沿 xff0c 上
  • 【STM32】HAL库-系统滴答定时器SysTick

    SysTick定时器被捆绑在NVIC中 xff0c 是一个简单的定时器 xff0c 对于CM3 CM4内核芯片 xff0c 都有Systick定时器 Systick定时器常用来做延时 xff0c 或者实时系统的心跳时钟 这样可以节省MCU资
  • 【STM32】HAL库-串口USART

    USART简介 通用同步异步收发器 USART 提供了一种灵活的方法与使用工业标准NRZ异步串行数据格式的外部设备之间进行全双工数据交换 USART利用分数波特率发生器提供宽范围的波特率选择 一个波特率寄存器 USART BRR xff0c
  • 【STM32】HAL库-通用定时器

    简介 通用定时器是一个通过可编程预分频器驱动的16位自动装载计数器构成 它适用于多种场合 xff0c 包括测量输入信号的脉冲长度 输入捕获 或者产生输出波形 输出比较和PWM 使用定时器预分频器和RCC时钟控制器预分频器 xff0c 脉冲长