资讯详情

【STM32】HAL库-通用定时器

简介

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

在这里插入图片描述

时基单元

  • 当前计数值寄存器CNT

  • 寄存器自动重装ARR ,具有,根据TIMx_CR预加载寄存器中的自动重装载使能量位置(ARPE),写入ARR寄存器的内容可以立即或每次更新事件()传送到它的影子寄存器。

  • 预分频寄存器PSC ,具有,有缓冲,新的预分频值将在下一个更新事件中工作(更新事件()将值传输到其影子寄存器之前)。

更新事件UEV使能和来源

  • 更新事件的使能位 TIMx_CR1寄存器的UDIS位
  • 更新事件的来源 更新中断和DMA请求的来源 TIMx_CR1寄存器的URS位

软件触发更新事件

写入事件产生寄存器TIM_EGR寄存器的UG位 置位UG位置产生更新事件 这是为了避免在捕获模式下同时清除计数器 中断生更新和捕获。

计数模式

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

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

  • 中央对齐计数模式(向上/向下计数) 在中央对齐模式下,计数器从0开始计数到自动加载值(TIMx_ARR寄存器)?1,产生一个计数器溢出事件,然后向下计数到1并且产生一个计数器下溢事件;然后再从0开始重新计数。在每次计数上溢和每次计数下溢时产生更新事件 可通过(软件或使用从模式控制器)设置TIMx_EGR寄存器中的UG位置产生更新事件。然后,计数器从0开始,预分频器从0开始。

时钟源

定时器时钟来源

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

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

外部时钟模式1

当TIMx_SMCR寄存器的SMS=111时,选择此模式。计数器可以在选定输入端的每个上升或下降沿计数。 配置过程

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

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

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

定时器更新中断回调函数

工程文件下载链接

外部时钟模式2

选择此模式的方法如下:令TIMx_SMCR寄存器中的ECE=1 计数器可以在外部触发ETR的每一个计数。

配置过程

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

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

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

定时器更新中断回调函数 下载工程文件链接

输入捕获

输入部分对应(引脚上的电平)输入信号采样,产生滤波后的信号(逻辑信号0/1)。然后,选择极性(上升/下降)的边缘检测器产生信号(),它可以作为模式控制器的输入触发或捕获控制。()预分频(预分频器含有预分频计数器用于计算TIxFPx进入捕获寄存器的数量)()。

通过CC1S来选择IC1的信号来源 通过ICPS来选择几个IC1信号等效于IC1PS信号。

捕获发生在阴影寄存器上,然后复制到预装载寄存器中。 当捕获发生时,计数器CNT该值将被复制到捕获/比较阴影寄存器,然后从阴影寄存器复制到捕获/比较预装载寄存器。

在输入捕获模式下,定到捕获/比较寄存器(TIMx_CCRx)中。,若能中断或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 计数器每计数一次需要时间.0001s = 100us = 0.1ms 预分频器为72MHz / 10KHz = 7200 - 1 = 7199 计数器重装载值为65535 因此,最长计数为6.5535秒 PA定时器输入捕获通道1(CH一、下降沿捕获,CH1连接IC 根据实际需求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()的代码也是这样写的,如下 工程文件下载链接

PWM输入捕获

PWM输入捕获,用来测量PWM信号的周期与占空比,如下图:

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

  2. 同1

通过URS位来确定是否需要使用复位模式产生的中断 不需要则置位URS位

配置过程

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位来确定是否要使用这个更新事件

定时器初始化函数用户添加的代码 回调函数

主函数

也可以使能触发中断

__HAL_TIM_ENABLE_IT(&htim2, TIM_IT_TRIGGER);

回调函数如下 工程文件下载链接

输出比较

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

输出模式如下图:

OCxM位的值:

  1. 000:CCR与CNT寄存器的值进行比较不能影响OC引脚的电平状态,被冻结,对OCxREF也没影响。
  2. 001:,将OC引脚的电平状态设置位有效电平,OCxREF为高电平。OC有效电平由捕获/比较使能寄存器(TIMx_CCER) 的CCxP位进行设置。
  3. 010: ,将OC引脚的电平状态设置位无效电平,OCxREF为低电平。
  4. 011:,OC引脚电平状态进行翻转,OCxREF也翻转。
  5. 100:不介绍
  6. 101:不介绍
  7. 110:PWM1, 。 在向下计数模式,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输出-呼吸灯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调整一次占空比

工程文件下载链接

单脉冲模式

单脉冲模式(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,可以自己画一下波形图分析。

定时器2设置 定时器3设置

HAL库的TIM2初始化函数添加用户代码 捕获回调函数 HAL库的TIM3初始化添加用户代码 主函数 工程文件下载链接

定时器的从模式

通用定时器有以下几种从模式,通过寄存器TIMx_SMCR寄存器中SMS位来选择从模式。

从模式的触发信号TRGI的来源,寄存器TIMx_SMCR寄存器中TS位

复位模式

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

。 定时器的通道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信号被激活,即复位模式被激活,当复位模式激活时,,复位模式将CNT寄存器清零,产生一个更新事件(如果使能更新中断,则会产生一个更新中断,更新事件会更新影子寄存器与其对应的寄存器),产生一个通道1(IC1)捕获中断,进入中断服务函数中。

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

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

门控模式

当触发输入(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的差距。亮则计数,灭则暂停计数。

建议:设计电路的时候可根据需要添加上拉/下拉电阻。

主函数程序 定时器2初始化函数添加用户代码

原因:仅配置定时器为门控模式,并不会配置IC1为输入捕获模式。如果没有配置为输入捕获模式,则不会捕获CNT寄存器的值 在HAL_TIM_IRQHandler()函数中

输入捕获回调函数

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

串口助手显示的结果

工程文件下载链接

触发模式

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

工程文件下载链接

外部时钟模式1

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

工程文件下载链接

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

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

配置过程

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

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

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

主函数代码 每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)

定时器初始化函数添加用户代码 如果需要使用捕获功能,请开启定时器全局中断,并调用void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)输入捕获中断回调函数

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

定时器同步

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

主模式下的定时器触发信号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。

通过此表来设置定时器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的更新中断,在更新中断回调函数发送相应的数据。

主函数代码

定时器更新中断回调函数

串口助手 工程文件下载链接

输入异或功能

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位

标签: trc传感器

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台