第十一章 通用定时器(上篇)
第十一章 通用定时器(上篇)
目录
第十一章 通用定时器(上篇)
1 通用定时器概述
1.1 通用定时器简介
1.2 主要功能
1.3 功能描述
1.3.1时基单元
1.3.2计数器模式
1.3.3时钟选择
1.3.4捕获/比较通道
1.3.5输入捕获模式
1.3.6PWM输入模式
1.3.7强置输出模式
1.3.8输出比较模式
1.3.9PWM 模式
1.3.10单脉冲模式
1.3.11在外部事件时清除OCxREF信号
1.3.12编码器接口模式
1.3.13定时器输入异或功能
1.3.14定时器和外部触发的同步
1.3.15定时器同步
1.3.16调试模式
2 程序设计
2.1 TIM_Basic例程
2.2 TIM_CalibrationLsi例程
3 下载验证
3.1 TIM_Basic例程
3.2 TIM_CalibrationLsi例程
W55MH32的通用定时器为TIM2~TIM5/TIM9~TIM14,由于篇幅有限,这里我们讲解TIM2~TIM5的相关功能,对于通用定时器TIM9~TIM14,感兴趣的朋友查阅《W55MH32参考手册》使用方法一致,功能上存在些许差异,掌握了方法之后都是一通百通的。
本章分为如下几个小节:
1 通用定时器概述
2 程序设计
3 下载验证
1 通用定时器概述
1.1 通用定时器简介
通用定时器是一个通过可编程预分频器驱动的 16 位自动装载计数器构成。它适用于多种场合,包括测量输入信号的脉冲长度(输入捕获)或者产生输出波形(输出比较和PWM)。使用定时器预分频器和 RCC 时钟控制器预分频器,脉冲长度和波形周期可以在几个微秒到几个 毫秒间调整。每个定时器都是完全独立的,没有互相共享任何资源。
1.2 主要功能
通用TIMx (TIM2、TIM3、TIM4和TIM5)定时器功能包括:
- 16位向上、向下、向上/向下自动装载计数器
- 16位可编程(可以实时修改)预分频器,计数器时钟频率的分频系数为1~65536之间的任意 数值
- 4个独立通道:
- 输入捕获
- 输出比较
- PWM生成(边缘或中间对齐模式)
- 单脉冲模式输出
- 使用外部信号控制定时器和定时器互连的同步电路
- 如下事件发生时产生中断/DMA:
- 更新:计数器向上溢出/向下溢出,计数器初始化(通过软件或者内部/外部触发)
- 触发事件(计数器启动、停止、初始化或者由内部/外部触发计数)
- 输入捕获
- 输出比较
- 支持针对定位的增量(正交)编码器和霍尔传感器电路
- 触发输入作为外部时钟或者按周期的电流管理
通用定时器框图如下:
1.3 功能描述
1.3.1时基单元
可编程通用定时器的主要部分是一个16位计数器和与其相关的自动装载寄存器。这个计数器可以向上计数、向下计数或者向上向下双向计数。此计数器时钟由预分频器分频得到。
计数器、自动装载寄存器和预分频器寄存器可以由软件读写,在计数器运行时仍可以读写。时基单元包含:
- 计数器寄存器(TIMx_CNT)
- 预分频器寄存器 (TIMx_PSC)
- 自动装载寄存器 (TIMx_ARR)
自动装载寄存器是预先装载的,写或读自动重装载寄存器将访问预装载寄存器。根据在 TIMx_CR1寄存器中的自动装载预装载使能位(ARPE)的设置,预装载寄存器的内容被立即或在 每次的更新事件UEV时传送到影子寄存器。当计数器达到溢出条件(向下计数时的下溢条件)并当 TIMx_CR1寄存器中的UDIS位等于'0'时,产生更新事件。更新事件也可以由软件产生。随后会详细描述每一种配置下更新事件的产生。
计数器由预分频器的时钟输出CK_CNT驱动,仅当设置了计数器TIMx_CR1寄存器中的计数器使能位(CEN)时,CK_CNT才有效。(有关计数器使能的细节,请参见控制器的从模式描述)。
注:真正的计数器使能信号CNT_EN是在CEN的一个时钟周期后被设置。
预分频器描述
预分频器可以将计数器的时钟频率按1到65536之间的任意值分频。它是基于一个(在TIMx_PSC 寄存器中的)16位寄存器控制的16位计数器。这个控制寄存器带有缓冲器,它能够在工作时被改 变。新的预分频器参数在下一次更新事件到来时被采用。
下面出了在预分频器运行时,更改计数器参数的例子:
当预分频器的参数从1变到2时,计数器的时序图
当预分频器的参数从1变到4时,计数器的时序图
1.3.2计数器模式
向上计数模式
在向上计数模式中,计数器从0计数到自动加载值(TIMx_ARR计数器的内容),然后重新从0开始 计数并且产生一个计数器溢出事件。
每次计数器溢出时可以产生更新事件,在TIMx_EGR寄存器中(通过软件方式或者使用从模式控 制器)设置UG位也同样可以产生一个更新事件。
设置TIMx_CR1寄存器中的UDIS位,可以禁止更新事件;这样可以避免在向预装载寄存器中写 入新值时更新影子寄存器。在UDIS位被清'0'之前,将不产生更新事件。但是在应该产生更新事 件时,计数器仍会被清'0',同时预分频器的计数也被请0(但预分频系数不变)。此外,如果设置 了TIMx_CR1寄存器中的URS位(选择更新请求),设置UG位将产生一个更新事件UEV,但硬件 不设置UIF标志(即不产生中断或DMA请求);这是为了避免在捕获模式下清除计数器时,同时产 生更新和捕获中断。
当发生一个更新事件时,所有的寄存器都被更新,硬件同时(依据URS位)设置更新标志位 (TIMx_SR寄存器中的UIF位)。
- 预分频器的缓冲区被置入预装载寄存器的值(TIMx_PSC寄存器的内容)。
- 自动装载影子寄存器被重新置入预装载寄存器的值(TIMx_ARR)。
下图给出一些例子,当TIMx_ARR=0x36时计数器在不同时钟频率下的动作:
计数器时序图,内部时钟分频因子为1
计数器时序图,内部时钟分频因子为2
计数器时序图,内部时钟分频因子为4
计数器时序图,内部时钟分频因子为N
计数器时序图,当ARPE=0时的更新事件(TIMx_ARR没有预装入)
计数器时序图,当ARPE=1时的更新事件(预装入了TIMx_ARR)
向下计数模式
在向下模式中,计数器从自动装入的值(TIMx_ARR计数器的值)开始向下计数到0,然后从自动 装入的值重新开始并且产生一个计数器向下溢出事件。
每次计数器溢出时可以产生更新事件,在TIMx_EGR寄存器中(通过软件方式或者使用从模式控 制器)设置UG位,也同样可以产生一个更新事件。
设置TIMx_CR1寄存器的UDIS位可以禁止UEV事件。这样可以避免向预装载寄存器中写入新值 时更新影子寄存器。因此UDIS位被清为'0'之前不会产生更新事件。然而,计数器仍会从当前自 动加载值重新开始计数,同时预分频器的计数器重新从0开始(但预分频系数不变)。
此外,如果设置了TIMx_CR1寄存器中的URS位(选择更新请求) ,设置UG位将产生一个更新事 件UEV但不设置UIF标志(因此不产生中断和DMA请求),这是为了避免在发生捕获事件并清除计 数器时,同时产生更新和捕获中断。
当发生更新事件时,所有的寄存器都被更新,并且(根据URS位的设置)更新标志位(TIMx_SR寄 存器中的UIF位)也被设置。
- 预分频器的缓存器被置入预装载寄存器的值(TIMx_PSC寄存器的值)。
- 当前的自动加载寄存器被更新为预装载值(TIMx_ARR寄存器中的内容) 。
注:自动装载在计 数器重载入之前被更新,因此下一个周期将是预期的值。
以下是一些当TIMx_ARR=0x36时,计数器在不同时钟频率下的操作例子。
计数器时序图,内部时钟分频因子为1
计数器时序图,内部时钟分频因子为2
计数器时序图,内部时钟分频因子为4
计数器时序图,内部时钟分频因子为N
计数器时序图,当没有使用重复计数器时的更新事件
中央对齐模式(向上/向下计数)
在中央对齐模式,计数器从0开始计数到自动加载的值(TIMx_ARR寄存器)-1,产生一个计数器 溢出事件,然后向下计数到1并且产生一个计数器下溢事件;然后再从0开始重新计数。
在这个模式,不能写入TIMx_CR1中的DIR方向位。它由硬件更新并指示当前的计数方向。
可以在每次计数上溢和每次计数下溢时产生更新事件;也可以通过(软件或者使用从模式控制器) 设置TIMx_EGR寄存器中的UG位产生更新事件。然后,计数器重新从0开始计数,预分频器也 重新从0开始计数。
设置TIMx_CR1寄存器中的UDIS位可以禁止UEV事件。这样可以避免在向预装载寄存器中写入 新值时更新影子寄存器。因此UDIS位被清为'0'之前不会产生更新事件。然而,计数器仍会根据 当前自动重加载的值,继续向上或向下计数。
此外,如果设置了TIMx_CR1寄存器中的URS位(选择更新请求) ,设置UG位将产生一个更新事 件UEV但不设置UIF标志(因此不产生中断和DMA请求),这是为了避免在发生捕获事件并清除计 数器时,同时产生更新和捕获中断。
当发生更新事件时,所有的寄存器都被更新,并且(根据URS位的设置)更新标志位(TIMx_SR寄 存器中的UIF位)也被设置。
- 预分频器的缓存器被加载为预装载(TIMx_PSC寄存器)的值。
- 当前的自动加载寄存器被更新为预装载值(TIMx_ARR寄存器中的内容)。
注:如果因为计数 器溢出而产生更新,自动重装载将在计数器重载入之前被更新,因此下一个周期将是预期 的值(计数器被装载为新的值)。
以下是一些计数器在不同时钟频率下的操作的例子:
计数器时序图,内部时钟分频因子为1,TIMx_ARR=0x6
1.这里使用了中心对齐模式1。
计数器时序图,内部时钟分频因子为2
计数器时序图,内部时钟分频因子为4,TIMx_ARR=0x36
计数器时序图,内部时钟分频因子为N
计数器时序图,ARPE=1时的更新事件(计数器下溢)
计数器时序图,ARPE=1时的更新事件(计数器溢出)
1.3.3时钟选择
计数器时钟可由下列时钟源提供:
- 内部时钟(CK_INT)
- 外部时钟模式1:外部输入脚(TIx)
- 外部时钟模式2:外部触发输入(ETR)
- 内部触发输入(ITRx):使用一个定时器作为另一个定时器的预分频器,如可以配置一个定时器Timer1而作为另一个定时器Timer2的预分频器。
内部时钟源(CK_INT)
如果禁止了从模式控制器(TIMx_SMCR寄存器的SMS=000),则CEN 、DIR(TIMx_CR1寄存器) 和UG位(TIMx_EGR寄存器)是事实上的控制位,并且只能被软件修改(UG位仍被自动清除)。只 要CEN位被写成'1',预分频器的时钟就由内部时钟CK_INT提供。
下图显示了控制电路和向上计数器在一般模式下,不带预分频器时的操作:
一般模式下的控制电路,内部时钟分频因子为1
外部时钟源模式1
当TIMx_SMCR寄存器的SMS=111时,此模式被选中。计数器可以在选定输入端的每个上升沿 或下降沿计数。
TI2外部时钟连接例子
例如,要配置向上计数器在T12输入端的上升沿计数,使用下列步骤:
1.配置TIMx_CCMR1寄存器CC2S='01',配置通道2检测TI2输入的上升沿。
2.配置TIMx_CCMR1寄存器的IC2F[3:0],选择输入滤波器带宽(如果不需要滤波器,保持 IC2F=0000)。
注:捕获预分频器不用作触发,所以不需要对它进行配置。
3.配置TIMx_CCER寄存器的CC2P='0',选定上升沿极性。
4.配置TIMx_SMCR寄存器的SMS='111',选择定时器外部时钟模式1。
5.配置TIMx_SMCR寄存器中的TS='110',选定TI2作为触发输入源。
6.设置TIMx_CR1寄存器的CEN='1',启动计数器。
当上升沿出现在TI2,计数器计数一次,且TIF标志被设置。
在TI2的上升沿和计数器实际时钟之间的延时,取决于在TI2输入端的重新同步电路。
外部时钟模式1下的控制电路
外部时钟源模式2
选定此模式的方法为:令TIMx_SMCR寄存器中的ECE=1 计数器能够在外部触发ETR的每一个上升沿或下降沿计数。 下图是外部触发输入的框图:
外部触发输入框图
例如,要配置在ETR下每2个上升沿计数一次的向上计数器,使用下列步骤:
1.本例中不需要滤波器,置TIMx_SMCR寄存器中的ETF[3:0]=0000
2.设置预分频器,置TIMx_SMCR寄存器中的ETPS[1:0]=01
3.设置在ETR的上升沿检测,置TIMx_SMCR寄存器中的ETP=0
4.开启外部时钟模式2,置TIMx_SMCR寄存器中的ECE=1
5.启动计数器,置TIMx_CR1寄存器中的CEN=1 计数器在每2个ETR上升沿计数一次。
在ETR的上升沿和计数器实际时钟之间的延时取决于在ETRP信号端的重新同步电路。
外部时钟模式2下的控制电路
1.3.4捕获/比较通道
每一个捕获/比较通道都是围绕着一个捕获/比较寄存器(包含影子寄存器),包括捕获的输入部分
(数字滤波、多路复用和预分频器),和输出部分(比较器和输出控制)。 下面几张图是一个捕获/比较通道概览。
输入部分对相应的TIx输入信号采样,并产生一个滤波后的信号TIxF。然后,一个带极性选择的 边缘检测器产生一个信号(TIxFPx),它可以作为从模式控制器的输入触发或者作为捕获控制。该 信号通过预分频进入捕获寄存器(ICxPS)。
捕获/比较通道(如:通道1输入部分)
输出部分产生一个中间波形OCxRef(高有效)作为基准,链的末端决定最终输出信号的极性。
捕获/比较通道1的主电路
捕获/比较通道的输出部分(通道1)
捕获/比较模块由一个预装载寄存器和一个影子寄存器组成。读写过程仅操作预装载寄存器。
在捕获模式下,捕获发生在影子寄存器上,然后再复制到预装载寄存器中。
在比较模式下,预装载寄存器的内容被复制到影子寄存器中,然后影子寄存器的内容和计数器进行比较。
1.3.5输入捕获模式
在输入捕获模式下,当检测到ICx信号上相应的边沿后,计数器的当前值被锁存到捕获/比较寄存 器(TIMx_CCRx)中。当捕获事件发生时,相应的CCxIF标志(TIMx_SR寄存器)被置'1',如果使能 了中断或者DMA操作, 则将产生中断或者DMA操作。如果捕获事件发生时CCxIF标志已经为 高,那么重复捕获标志CCxOF(TIMx_SR寄存器)被置'1'。写CCxIF=0可清除CCxIF,或读取存 储在TIMx_CCRx寄存器中的捕获数据也可清除CCxIF。写CCxOF=0可清除CCxOF。
以下例子说明如何在TI1输入的上升沿时捕获计数器的值到TIMx_CCR1寄存器中,步骤如下:
- 选择有效输入端:TIMx_CCR1必须连接到TI1输入,所以写入TIMx_CCR1寄存器中的 CC1S=01,只要CC1S不为'00',通道被配置为输入,并且TM1_CCR1寄存器变为只读。
- 根据输入信号的特点,配置输入滤波器为所需的带宽(即输入为TIx时,输入滤波器控制位是 TIMx_CCMRx寄存器中的ICxF位)。假设输入信号在最多5个内部时钟周期的时间内抖动, 我们须配置滤波器的带宽长于5个时钟周期。因此我们可以(以fDTS频率)连续采样8次,以确 认在TI1上一次真实的边沿变换,即在TIMx_CCMR1寄存器中写入IC1F=0011。
- 选择TI1通道的有效转换边沿,在TIMx_CCER寄存器中写入CC1P=0(上升沿)。
- 配置输入预分频器。在本例中,我们希望捕获发生在每一个有效的电平转换时刻,因此预分频器被禁止(写TIMx_CCMR1寄存器的IC1PS=00)。
- 设置TIMx_CCER寄存器的CC1E=1,允许捕获计数器的值到捕获寄存器中。
- 如果需要,通过设置TIMx_DIER寄存器中的CC1IE位允许相关中断请求,通过设置 TIMx_DIER寄存器中的CC1DE位允许DMA请求。
当发生一个输入捕获时:
- 产生有效的电平转换时,计数器的值被传送到TIMx_CCR1寄存器。
- CC1IF标志被设置(中断标志)。当发生至少2个连续的捕获时,而CC1IF未曾被清除, CC1OF也被置'1'。
- 如设置了CC1IE位,则会产生一个中断。
- 如设置了CC1DE位,则还会产生一个DMA请求。
为了处理捕获溢出,建议在读出捕获溢出标志之前读取数据,这是为了避免丢失在读出捕获溢出标志之后和读取数据之前可能产生的捕获溢出信息。
注:设置TIMx_EGR寄存器中相应的CCxG位,可以通过软件产生输入捕获中断和/或DMA请求。
1.3.6PWM输入模式
该模式是输入捕获模式的一个特例,除下列区别外,操作与输入捕获模式相同:
- 两个ICx信号被映射至同一个TIx输入。
- 这2个ICx信号为边沿有效,但是极性相反。
- 其中一个TIxFP信号被作为触发输入信号,而从模式控制器被配置成复位模式。
例如,你需要测量输入到TI1上的PWM信号的长度(TIMx_CCR1寄存器)和占空比(TIMx_CCR2 寄存器),具体步骤如下(取决于CK_INT的频率和预分频器的值)。
- 选择TIMx_CCR1的有效输入:置TIMx_CCMR1寄存器的CC1S=01(选择TI1)。
- 选择TI1FP1的有效极性(用来捕获数据到TIMx_CCR1中和清除计数器):置CC1P=0(上升沿 有效)。
- 选择TIMx_CCR2的有效输入:置TIMx_CCMR1寄存器的CC2S=10(选择TI1)。
- 选择TI1FP2的有效极性(捕获数据到TIMx_CCR2):置CC2P=1(下降沿有效)。
- 选择有效的触发输入信号:置TIMx_SMCR寄存器中的TS=101(选择TI1FP1)。
- 配置从模式控制器为复位模式:置TIMx_SMCR中的SMS=100。
- 使能捕获:置TIMx_CCER寄存器中CC1E=1且CC2E=1。
PWM输入模式时序
由于只有TI1FP1 和TI2FP2 连到了从模式控制器 ,所以 PWM 输入模式只能使用TIMx_CH1 /TIMx_CH2信号。
1.3.7强置输出模式
在输出模式(TIMx_CCMRx寄存器中CCxS=00)下,输出比较信号(OCxREF和相应的OCx)能够 直接由软件强置为有效或无效状态,而不依赖于输出比较寄存器和计数器间的比较结果。
置TIMx_CCMRx寄存器中相应的OCxM=101,即可强置输出比较信号(OCxREF/OCx)为有效状 态。这样OCxREF被强置为高电平(OCxREF始终为高电平有效),同时OCx得到CCxP极性位相 反的值。
例如:CCxP=0(OCx高电平有效),则OCx被强置为高电平。
置TIMx_CCMRx寄存器中的OCxM=100,可强置OCxREF信号为低。
该模式下,在TIMx_CCRx影子寄存器和计数器之间的比较仍然在进行,相应的标志也会被修改。因此仍然会产生相应的中断和DMA请求。这将会在下面的输出比较模式一节中介绍。
1.3.8输出比较模式
此项功能是用来控制一个输出波形,或者指示一段给定的的时间已经到时。当计数器与捕获/比较寄存器的内容相同时,输出比较功能做如下操作:
- 将输出比较模式(TIMx_CCMRx寄存器中的OCxM位)和输出极性(TIMx_CCER寄存器中的 CCxP位)定义的值输出到对应的引脚上。在比较匹配时,输出引脚可以保持它的电平(OCxM=000)、被设置成有效电平(OCxM=001)、被设置成无效电平(OCxM=010)或进行翻转(OCxM=011)。
- 设置中断状态寄存器中的标志位(TIMx_SR寄存器中的CCxIF位)。
- 若设置了相应的中断屏蔽(TIMx_DIER寄存器中的CCxIE位),则产生一个中断。
- 若设置了相应的使能位(TIMx_DIER寄存器中的CCxDE位,TIMx_CR2寄存器中的CCDS位 选择DMA请求功能),则产生一个DMA请求。
TIMx_CCMRx中的OCxPE位选择TIMx_CCRx寄存器是否需要使用预装载寄存器。 在输出比较模式下,更新事件UEV对OCxREF和OCx输出没有影响。
同步的精度可以达到计数器的一个计数周期。输出比较模式(在单脉冲模式下)也能用来输出一个 单脉冲。
输出比较模式的配置步骤:
1.选择计数器时钟(内部,外部,预分频器)
2.将相应的数据写入TIMx_ARR和TIMx_CCRx寄存器中
3.如果要产生一个中断请求和/或一个DMA请求,设置CCxIE位和/或CCxDE位。
4.选择输出模式,例如当计数器CNT与CCRx匹配时翻转OCx的输出引脚,CCRx预装载未 用,开启OCx输出且高电平有效,则必须设置OCxM='011' 、OCxPE='0' 、CCxP='0'和 CCxE='1'。
5.设置TIMx_CR1寄存器的CEN位启动计数器
TIMx_CCRx寄存器能够在任何时候通过软件进行更新以控制输出波形,条件是未使用预装载寄 存器(OCxPE='0',否则TIMx_CCRx影子寄存器只能在发生下一次更新事件时被更新)。下图给出了一个例子:
输出比较模式,翻转OC1
1.3.9PWM 模式
脉冲宽度调制模式可以产生一个由TIMx_ARR寄存器确定频率、由TIMx_CCRx寄存器确定占空比的信号。
在TIMx_CCMRx寄存器中的OCxM位写入'110'(PWM模式1)或'111'(PWM模式2),能够独立地设 置每个OCx输出通道产生一路PWM。必须设置TIMx_CCMRx寄存器OCxPE位以使能相应的预 装载寄存器,最后还要设置TIMx_CR1寄存器的ARPE位,(在向上计数或中心对称模式中)使能 自动重装载的预装载寄存器。
仅当发生一个更新事件的时候,预装载寄存器才能被传送到影子寄存器,因此在计数器开始计数之前,必须通过设置TIMx_EGR寄存器中的UG位来初始化所有的寄存器。
OCx的极性可以通过软件在TIMx_CCER寄存器中的CCxP位设置,它可以设置为高电平有效或 低电平有效。TIMx_CCER寄存器中的CCxE位控制OCx输出使能。详见TIMx_CCERx寄存器的 描述。
在PWM模式(模式1或模式2)下,TIMx_CNT和TIMx_CCRx始终在进行比较,(依据计数器的计数 方向) 以确定是否符合TIMx_CCRx ≤ TIMx_CNT 或者TIMx_CNT ≤ TIMx_CCRx 。然而 为了与 OCREF_CLR的功能(在下一个PWM周期之前, ETR信号上的一个外部事件能够清除OCxREF) 一致,OCxREF信号只能在下述条件下产生:
l当比较的结果改变
l当输出比较模式(TIMx_CCMRx寄存器中的OCxM位)从“冻结”(无比较,OCxM='000')切换到某个PWM模式(OCxM='110'或'111')。
这样在运行中可以通过软件强置PWM输出。
根据TIMx_CR1寄存器中CMS位的状态,定时器能够产生边沿对齐的PWM信号或中央对齐的 PWM信号。
PWM 边沿对齐模式
向上计数配置
当TIMx_CR1寄存器中的DIR位为低的时候执行向上计数。参看0节。
下面是一个PWM模式1的例子。当TIMx_CNT<TIMx_CCRx时PWM信号参考OCxREF为高,否 则为低。如果TIMx_CCRx中的比较值大于自动重装载值(TIMx_ARR),则OCxREF保持为'1'。
如果比较值为0,则OCxREF保持为'0' 。 下图为TIMx_ARR=8时边沿对齐的PWM波形实例。:
边沿对齐的PWM波形(ARR=8)
向下计数的配置
当TIMx_CR1寄存器的DIR位为高时执行向下计数。
在 PWM 模式 1 ,当 TIMx_CNT>TIMx_CCRx 时参考信号 OCxREF 为低,否 则为高。 如果 TIMx_CCRx中的比较值大于TIMx_ARR中的自动重装载值,则OCxREF保持为'1'。该模式下不 能产生0%的PWM波形。
PWM 中央对齐模式
当TIMx_CR1寄存器中的CMS位不为'00'时,为中央对齐模式(所有其他的配置对OCxREF/OCx 信号都有相同的作用)。根据不同的CMS位设置,比较标志可以在计数器向上计数时被置'1'、在 计数器向下计数时被置'1'、或在计数器向上和向下计数时被置'1' 。TIMx_CR1寄存器中的计数方 节的中央对齐模式。
下图给出了一些中央对齐的PWM波形的例子:
- TIMx_ARR=8
- PWM模式1
- TIMx_CR1寄存器中的CMS=01,在中央对齐模式1时,当计数器向下计数时设置比较标 志。
中央对齐的PWM波形(APR=8)
使用中央对齐模式的提示:
- 进入中央对齐模式时,使用当前的向上/向下计数配置;这就意味着计数器向上还是向下计 数取决于TIMx_CR1寄存器中DIR位的当前值。此外,软件不能同时修改DIR和CMS位。
- 不推荐当运行在中央对齐模式时改写计数器,因为这会产生不可预知的结果。特别地:
- 如果写入计数器的值大于自动重加载的值(TIMx_CNT>TIMx_ARR),则方向不会被更新。例如,如果计数器正在向上计数,它就会继续向上计数。
- 如果将0或者TIMx_ARR的值写入计数器,方向被更新,但不产生更新事件UEV。
- 使用中央对齐模式最保险的方法,就是在启动计数器之前产生一个软件更新(设置 TIMx_EGR 位中的UG位),不要在计数进行过程中修改计数器的值。
1.3.10单脉冲模式
单脉冲模式(OPM)是前述众多模式的一个特例。这种模式允许计数器响应一个激励,并在一个程序可控的延时之后,产生一个脉宽可程序控制的脉冲。
可以通过从模式控制器启动计数器,在输出比较模式或者 PWM 模式下产生波形。设置 TIMx_CR1寄存器中的OPM位将选择单脉冲模式,这样可以让计数器自动地在产生下一个更新事件UEV时停止。
仅当比较值与计数器的初始值不同时,才能产生一个脉冲。启动之前(当定时器正在等待触发), 必须如下配置:
向上计数方式:CNT < CCRx ≤ ARR (特别地,0 < CCRx),
向下计数方式:CNT > CCRx。
单脉冲模式的例子
例如,你需要在从TI2输入脚上检测到一个上升沿开始,延迟tDELAY之后,在OC1上产生一个长
度为tPULSE 的正脉冲。
假定TI2FP2作为触发1:
- 置TIMx_CCMR1寄存器中的CC2S='01',把TI2FP2映像到TI2。
- 置TIMx_CCER寄存器中的CC2P='0',使TI2FP2能够检测上升沿。
- 置TIMx_SMCR寄存器中的TS='110' ,TI2FP2作为从模式控制器的触发(TRGI)。
- 置TIMx_SMCR寄存器中的SMS='110'(触发模式),TI2FP2被用来启动计数器。 OPM波形由写入比较寄存器的数值决定(要考虑时钟频率和计数器预分频器)
- tDELAY 由写入TIMx_CCR1寄存器中的值定义。
- tPULSE 由自动装载值和比较值之间的差值定义(TIMx_ARR - TIMx_CCR1)。
- 假定当发生比较匹配时要产生从'0'到'1'的波形,当计数器到达预装载值时要产生一个从'1' 到'0'的波形;首先要置TIMx_CCMR1寄存器的OC1M='111',进入PWM模式2;根据需要有 选择地使能预装载寄存器:置TIMx_CCMR1中的OC1PE='1'和TIMx_CR1寄存器中的ARPE;然后在TIMx_CCR1寄存器中填写比较值,在TIMx_ARR寄存器中填写自动装载值,修改UG位来产生一个更新事件,然后等待在TI2上的一个外部触发事件。本例中, CC1P='0'。
在这个例子中,TIMx_CR1寄存器中的DIR和CMS位应该置低。
因为只需一个脉冲,所以必须设置TIMx_CR1寄存器中的OPM='1',在下一个更新事件(当计数 器从自动装载值翻转到0)时停止计数。
特殊情况:OCx快速使能:
在单脉冲模式下,在TIx输入脚的边沿检测逻辑设置CEN位以启动计数器。然后计数器和比较值 间的比较操作产生了输出的转换。但是这些操作需要一定的时钟周期,因此它限制了可得到的最小延时tDELAY。
如果要以最小延时输出波形,可以设置TIMx_CCMRx寄存器中的OCxFE位;此时OCxREF(和 OCx)被强制响应激励而不再依赖比较的结果,输出的波形与比较匹配时的波形一样。OCxFE只 在通道配置为PWM1和PWM2模式时起作用。
1.3.11在外部事件时清除OCxREF信号
对于一个给定的通道,设置TIMx_CCMRx寄存器中对应的OCxCE位为'1',能够用ETRF输入端 的高电平把OCxREF信号拉低,OCxREF信号将保持为低直到发生下一次的更新事件UEV。
该功能只能用于输出比较和PWM模式,而不能用于强置模式。
例如,OCxREF信号可以联到一个比较器的输出,用于控制电流。这时,ETR必须配置如下:
1.外部触发预分频器必须处于关闭:TIMx_SMCR寄存器中的ETPS[1:0]='00'。
2.必须禁止外部时钟模式2:TIMx_SMCR寄存器中的ECE='0'。
3.外部触发极性(ETP)和外部触发滤波器(ETF)可以根据需要配置。
下图显示了当ETRF输入变为高时,对应不同OCxCE的值,OCxREF信号的动作。在这个例子 中,定时器TIMx被置于PWM模式。
清除TIMx的OCxREF
1.3.12编码器接口模式
选择编码器接口模式的方法是:如果计数器只在TI2的边沿计数,则置TIMx_SMCR寄存器中的 SMS=001;如果只在TI1边沿计数,则置SMS=010;如果计数器同时在TI1和TI2边沿计数,则 置SMS=011。
通过设置TIMx_CCER寄存器中的CC1P和CC2P位,可以选择TI1和TI2极性;如果需要,还可以 对输入滤波器编程。
两个输入TI1和TI2被用来作为增量编码器的接口。参看表75,假定计数器已经启动(TIMx_CR1 寄存器中的CEN='1'),计数器由每次在TI1FP1或TI2FP2上的有效跳变驱动。TI1FP1和TI2FP2 是TI1和TI2在通过输入滤波器和极性控制后的信号; 如果没有滤波和变相, 则TI1FP1=TI1 , TI2FP2=TI2。根据两个输入信号的跳变顺序,产生了计数脉冲和方向信号。依据两个输入信号的跳变顺序,计数器向上或向下计数,同时硬件对TIMx_CR1寄存器的DIR位进行相应的设置。 不管计数器是依靠TI1计数、依靠TI2计数或者同时依靠TI1和TI2计数。在任一输入端(TI1或者 TI2)的跳变都会重新计算DIR位。
编码器接口模式基本上相当于使用了一个带有方向选择的外部时钟。这意味着计数器只在0到 TIMx_ARR寄存器的自动装载值之间连续计数(根据方向,或是0到ARR计数,或是ARR到0计 数)。所以在开始计数之前必须配置TIMx_ARR;同样,捕获器、比较器、预分频器、触发输出特性等仍工作如常。
在这个模式下,计数器依照增量编码器的速度和方向被自动的修改,因此计数器的内容始终指示着编码器的位置。计数方向与相连的传感器旋转的方向对应。下表列出了所有可能的组合,假设TI1和TI2不同时变换。
表75 计数方向与编码器信号的关系
有效边沿 | 相对信号的电平 (TI1FP1对应TI2, TI2FP2对应TI1) | TI1FP1信号 | TI2FP2信号 | ||
上升 | 下降 | 上升 | 下降 | ||
仅在TI1计数 | 高 | 向下计数 | 向上计数 | 不计数 | 不计数 |
低 | 向上计数 | 向下计数 | 不计数 | 不计数 | |
仅在TI2计数 | 高 | 不计数 | 不计数 | 向上计数 | 向下计数 |
低 | 不计数 | 不计数 | 向下计数 | 向上计数 | |
在TI1和TI2上计数 | 高 | 向下计数 | 向上计数 | 向上计数 | 向下计数 |
低 | 向上计数 | 向下计数 | 向下计数 | 向上计数 |
一个外部的增量编码器可以直接与MCU连接而不需要外部接口逻辑。但是, 一般会使用比较器 将编码器的差动输出转换到数字信号,这大大增加了抗噪声干扰能力。编码器输出的第三个信 号表示机械零点,可以把它连接到一个外部中断输入并触发一个计数器复位。
下图是一个计数器操作的实例,显示了计数信号的产生和方向控制。它还显示了当选择了双边沿时,输入抖动是如何被抑制的;抖动可能会在传感器的位置靠近一个转换点时产生。在这个例子中,我们假定配置如下:
- CC1S='01' (TIMx_CCMR1寄存器,IC1FP1映射到TI1)
- CC2S='01' (TIMx_CCMR2寄存器,IC2FP2映射到TI2)
- CC1P='0' (TIMx_CCER寄存器,IC1FP1不反相,IC1FP1=TI1)
- CC2P='0' (TIMx_CCER寄存器,IC2FP2不反相,IC2FP2=TI2)
- SMS='011' (TIMx_SMCR寄存器,所有的输入均在上升沿和下降沿有效).
- CEN='1' (TIMx_CR1寄存器,计数器使能)
编码器模式下的计数器操作实例
下图为当IC1FP1极性反相时计数器的操作实例(CC1P='1',其他配置与上例相同)
IC1FP1反相的编码器接口模式实例
当定时器配置成编码器接口模式时,提供传感器当前位置的信息。使用第二个配置在捕获模式的定时器,可以测量两个编码器事件的间隔,获得动态的信息(速度,加速度,减速度)。指示机 械零点的编码器输出可被用做此目的。根据两个事件间的间隔,可以按照固定的时间读出计数器。如果可能的话,你可以把计数器的值锁存到第三个输入捕获寄存器(捕获信号必须是周期的 并且可以由另一个定时器产生);也可以通过一个由实时时钟产生的DMA请求来读取它的值。
1.3.13定时器输入异或功能
TIMx_CR2寄存器中的TI1S位,允许通道1的输入滤波器连接到一个异或门的输出端,异或门的 3个输入端为TIMx_CH1、TIMx_CH2和TIMx_CH3。
异或输出能够被用于所有定时器的输入功能,如触发或输入捕获。
1.3.14定时器和外部触发的同步
TIMx定时器能够在多种模式下和一个外部的触发同步:复位模式、门控模式和触发模式。
从模式:复位模式
在发生一个触发输入事件时,计数器和它的预分频器能够重新被初始化;同时,如果TIMx_CR1 寄存器的URS位为低,还会产生一个更新事件UEV;然后所有的预装载寄存器(TIMx_ARR , TIMx_CCRx)都会被更新。
在下面的例子中,TI1输入端的上升沿导致向上计数器被清零:
- 配置通道1以检测TI1的上升沿。配置输入滤波器的带宽(在本例中,不需要任何滤波器,因 此保持IC1F=0000)。触发操作中不使用捕获预分频器,所以不需要配置它。CC1S位只选 择输入捕获源,即TIMx_CCMR1寄存器中CC1S=01。置TIMx_CCER寄存器中CC1P=0以 确定极性(只检测上升沿)。
- 置TIMx_SMCR寄存器中SMS=100,配置定时器为复位模式;置TIMx_SMCR寄存器中 TS=101,选择TI1作为输入源。
- 置TIMx_CR1寄存器中CEN=1,启动计数器。
计数器开始依据内部时钟计数,然后正常运转直到TI1出现一个上升沿;此时,计数器被清零然 后从0重新开始计数。同时,触发标志(TIMx_SR寄存器中的TIF位)被设置,根据TIMx_DIER寄 存器中TIE(中断使能)位和TDE(DMA使能)位的设置,产生一个中断请求或一个DMA请求。
下图显示当自动重装载寄存器TIMx_ARR=0x36时的动作。在TI1上升沿和计数器的实际复位之 间的延时,取决于TI1输入端的重同步电路。
复位模式下的控制电路
从模式:门控模式
按照选中的输入端电平使能计数器。
在如下的例子中,计数器只在TI1为低时向上计数:
- 配置通道1以检测TI1上的低电平。配置输入滤波器带宽(本例中,不需要滤波,所以保持 IC1F=0000)。触发操作中不使用捕获预分频器,所以不需要配置。CC1S位用于选择输入 捕获源,置TIMx_CCMR1寄存器中CC1S=01。置TIMx_CCER寄存器中CC1P=1以确定极 性(只检测低电平)。
- 置TIMx_SMCR寄存器中SMS=101,配置定时器为门控模式;置TIMx_SMCR寄存器中 TS=101,选择TI1作为输入源。
- 置TIMx_CR1寄存器中CEN=1,启动计数器。在门控模式下,如果CEN=0,则计数器不能 启动,不论触发输入电平如何。
只要TI1为低,计数器开始依据内部时钟计数,在TI1变高时停止计数。当计数器开始或停止时 都设置TIMx_SR中的TIF标置。
TI1上升沿和计数器实际停止之间的延时,取决于TI1输入端的重同步电路。
门控模式下的控制电路
从模式:触发模式
输入端上选中的事件使能计数器。
在下面的例子中,计数器在TI2输入的上升沿开始向上计数:
- 配置通道2检测TI2的上升沿。配置输入滤波器带宽(本例中,不需要任何滤波器,保持IC2F=0000)。触发操作中不使用捕获预分频器,不需要配置。CC2S位只用于选择输入捕 获源,置TIMx_CCMR1寄存器中CC2S=01。置TIMx_CCER寄存器中CC2P=1以确定极性 (只检测低电平)。
- 置TIMx_SMCR寄存器中SMS=110,配置定时器为触发模式;置TIMx_SMCR寄存器中 TS=110,选择TI2作为输入源。
当TI2出现一个上升沿时,计数器开始在内部时钟驱动下计数,同时设置TIF标志。
TI2上升沿和计数器启动计数之间的延时,取决于TI2输入端的重同步电路。
触发器模式下的控制电路
从模式:外部时钟模式2 + 触发模式
外部时钟模式2可以与另一种从模式(外部时钟模式1和编码器模式除外)一起使用。这时,ETR信 号被用作外部时钟的输入,在复位模式、门控模式或触发模式时可以选择另一个输入作为触发输入。不建议使用TIMx_SMCR寄存器的TS位选择ETR作为TRGI。
下面的例子中,TI1上出现一个上升沿之后,计数器即在ETR的每一个上升沿向上计数一次:
- 通过TIMx_SMCR寄存器配置外部触发输入电路:
- ETF=0000:没有滤波
- ETPS=00:不用预分频器
- ETP=0:检测ETR的上升沿,置ECE=1使能外部时钟模式2
- 按如下配置通道1,检测TI的上升沿:
- IC1F=0000:没有滤波
- 触发操作中不使用捕获预分频器,不需要配置
- 置TIMx_CCMR1寄存器中CC1S=01,选择输入捕获源
- 置TIMx_CCER寄存器中CC1P=0以确定极性(只检测上升沿)
- 置TIMx_SMCR寄存器中SMS=110,配置定时器为触发模式。置TIMx_SMCR寄存器中 TS=101,选择TI1作为输入源。
当TI1上出现一个上升沿时,TIF标志被设置,计数器开始在ETR的上升沿计数。
ETR信号的上升沿和计数器实际复位间的延时,取决于ETRP输入端的重同步电路。
外部时钟模式2+触发模式下的控制电路
1.3.15定时器同步
所有TIMx定时器在内部相连,用于定时器同步或链接。当一个定时器处于主模式时,它可以对另一个处于从模式的定时器的计数器进行复位、启动、停止或提供时钟等操作。
下图显示了触发选择和主模式选择模块的概况。
使用一个定时器作为另一个定时器的预分频器
主/从定时器的例子
如:可以配置定时器1作为定时器2的预分频器。参考上图,进行下述操作:
- 配置定时器1为主模式,它可以在每一个更新事件UEV时输出一个周期性的触发信号。在TIM1_CR2寄存器的MMS='010'时,每当产生一个更新事件时在TRGO1上输出一个上升沿信号。
- 连接定时器1的TRGO1输出至定时器2,设置TIM2_SMCR寄存器的TS='000',配置定时器2为使用ITR1作为内部触发的从模式。
- 然后把从模式控制器置于外部时钟模式1(TIM2_SMCR寄存器的SMS=111);这样定时器2即可由定时器1周期性的上升沿(即定时器1的计数器溢出)信号驱动。
- 最后,必须设置相应(TIMx_CR1寄存器)的CEN位分别启动两个定时器。
注:如果OCx已被选中为定时器1的触发输出(MMS=1xx),它的上升沿用于驱动定时器2的计数器。
使用一个定时器使能另一个定时器
在这个例子中,定时器2的使能由定时器1的输出比较控制。只当定时器1的OC1REF为高时,定时器2才对分频后的内部时钟计数。两个定时器的时钟频率都是由预分频器对CK_INT除以3(fCK_CNT=fCK_INT/3)得到。
- 配置定时器1为主模式,送出它的输出比较参考信号(OC1REF)为触发输出(TIM1_CR2寄存器的MMS=100)
- 配置定时器1的OC1REF波形(TIM1_CCMR1寄存器)
- 配置定时器2从定时器1获得输入触发(TIM2_SMCR寄存器的TS=000)
- 配置定时器2为门控模式(TIM2_SMCR寄存器的SMS=101)
- 置TIM2_CR1寄存器的CEN=1以使能定时器2
- 置TIM1_CR1寄存器的CEN=1以启动定时器1
注:定时器2的时钟不与定时器1的时钟同步,这个模式只影响定时器2计数器的使能信号。
定时器1的OC1REF控制定时器2
在这个例子中,在定时器2启动之前,它们的计数器和预分频器未被初始化,因此它们从当前的数值开始计数。可以在启动定时器1之前复位2个定时器,使它们从给定的数值开始,即在定时器计数器中写入需要的任意数值。写TIMx_EGR寄存器的UG位即可复位定时器。
在下一个例子中,需要同步定时器1和定时器2。定时器1是主模式并从0开始,定时器2是从模式并从0xE7开始;2个定时器的预分频器系数相同。写'0'到TIM1_CR1的CEN位将禁止定时器1,定时器2随即停止。
- 配置定时器1为主模式,送出输出比较1参考信号(OC1REF)做为触发输出(TIM1_CR2寄存器的MMS=100)。
- 配置定时器1的OC1REF波形(TIM1_CCMR1寄存器)。
- 配置定时器2从定时器1获得输入触发(TIM2_SMCR寄存器的TS=000)
- 配置定时器2为门控模式(TIM2_SMCR寄存器的SMS=101)
- 置TIM1_EGR寄存器的UG='1',复位定时器1。
- 置TIM2_EGR寄存器的UG='1',复位定时器2。
- 写'0xE7'至定时器2的计数器(TIM2_CNTL),初始化它为0xE7。
- 置TIM2_CR1寄存器的CEN='1'以使能定时器2。
- 置TIM1_CR1寄存器的CEN='1'以启动定时器1。
- 置TIM1_CR1寄存器的CEN='0'以停止定时器1。
通过使能定时器1可以控制定时器2
使用一个定时器去启动另一个定时器
在这个例子中,使用定时器1的更新事件使能定时器2。一旦定时器1产生更新事件,定时器2即从它当前的数值(可以是非0)按照分频的内部时钟开始计数。在收到触发信号时,定时器2的CEN位被自动地置'1',同时计数器开始计数直到写'0'到TIM2_CR1寄存器的CEN位。两个定时器的时钟频率都是由预分频器对CK_INT除以3(fCK_CNT=fCK_INT/3)。
- 配置定时器1为主模式,送出它的更新事件(UEV)做为触发输出(TIM1_CR2寄存器的MMS=010)。
- 配置定时器1的周期(TIM1_ARR寄存器)。
- 配置定时器2从定时器1获得输入触发(TIM2_SMCR寄存器的TS=000)
- 配置定时器2为触发模式(TIM2_SMCR寄存器的SMS=110)
- 置TIM1_CR1寄存器的CEN=1以启动定时器1。
使用定时器1的更新触发定时器2
在上一个例子中,可以在启动计数之前初始化两个计数器。下图显示在与0相同配置情况下,使用触发模式而不是门控模式(TIM2_SMCR寄存器的SMS=110)的动作。
利用定时器1的使能触发定时器2
使用一个定时器作为另一个的预分频器
这个例子使用定时器1作为定时器2的预分频器。配置如下:
- 配置定时器1为主模式,送出它的更新事件UEV做为触发输出(TIM1_CR2寄存器的MMS='010')。然后每次计数器溢出时输出一个周期信号。
- 配置定时器1的周期(TIM1_ARR寄存器)。
- 配置定时器2从定时器1获得输入触发(TIM2_SMCR寄存器的TS=000)
- 配置定时器2使用外部时钟模式(TIM2_SMCR寄存器的SMS=111)
- 置TIM1_CR2寄存器的CEN=1以启动定时器2。
- 置TIM1_CR1寄存器的CEN=1以启动定时器1。
使用一个外部触发同步地启动2个定时器
这个例子中当定时器1的TI1输入上升时使能定时器1,使能定时器1的同时使能定时器2,为保证计数器的对齐,定时器1必须配置为主/从模式(对应TI1为从,对应定时器2为主):
- 配置定时器1为主模式,送出它的使能做为触发输出(TIM1_CR2寄存器的MMS='001')。
- 配置定时器1为从模式,从TI1获得输入触发(TIM1_SMCR寄存器的TS='100')。
- 配置定时器1为触发模式(TIM1_SMCR寄存器的SMS='110')。
- 配置定时器1为主/从模式,TIM1_SMCR寄存器的MSM='1'。
- 配置定时器2从定时器1获得输入触发(TIM2_SMCR寄存器的TS=000)
- 配置定时器2为触发模式(TIM2_SMCR寄存器的SMS='110')。
当定时器1的TI1上出现一个上升沿时,两个定时器同步地按照内部时钟开始计数,两个TIF标志也同时被设置。
注:在这个例子中,在启动之前两个定时器都被初始化(设置相应的UG位),两个计数器都从0开始,但可以通过写入任意一个计数器寄存器(TIMx_CNT)在定时器间插入一个偏移。下图中能看到主/从模式下在定时器1的CNT_EN和CK_PSC之间有个延迟。
使用定时器1的TI1输入触发定时器1和定时器2
1.3.16调试模式
当微控制器进入调试模式(Cortex-M3核心停止),根据DBG模块中DBG_TIMx_STOP的设置,TIMx计数器或者继续正常操作,或者停止。详见后面的章节:支持定时器、看门狗、bxCAN和I2C的调试。
2 程序设计
2.1 TIM_Basic例程
此例程的主要作用是进行通用定时器的测试。通过配置定时器 TIM3,使其在计数溢出时产生更新中断,在中断服务函数中打印中断服务函数名,以此来验证定时器的中断功能是否正常工作。
系统上电或复位后,程序开始执行。首先会通过串口输出系统时钟频率信息和测试提示信息,之后,定时器 TIM3 开始计数。当计数器的值达到自动重载值 9999 时,会产生更新中断,进入中断服务函数 TIM3_IRQHandler。在中断服务函数中,会清除中断标志位并通过串口输出 TIM3_IRQHandler。
此后,每隔一段时间(由定时器的预分频器和自动重载值决定),定时器就会产生一次更新中断,串口会周期性地输出 TIM3_IRQHandler,表明定时器的中断功能正常工作。
2.2 TIM_CalibrationLsi例程
此例程的主要作用是通过定时器 TIM5 的输入捕获功能来测量内部低速振荡器(LSI)信号的周期和频率。LSI 通常用于实时时钟(RTC)等对时钟精度要求不高的场合,通过测量其周期和频率,可以对 LSI 的性能进行评估。
1.时钟配置
void RCC_ClkConfiguration(void)
{
RCC_DeInit(); // 复位RCC时钟配置到默认状态 // 配置外部高速时钟(HSE)
RCC_HSEConfig(RCC_HSE_ON); // 使能HSE
while (RCC_GetFlagStatus(RCC_FLAG_HSERDY) == RESET); // 等待HSE就绪 // 配置锁相环(PLL):HSE×9=72MHz
RCC_PLLCmd(DISABLE); // 先禁用PLL
RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9); // 设置PLL输入源为HSE,倍频系数9
RCC_PLLCmd(ENABLE); // 使能PLL
while (RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET); // 等待PLL就绪 // 设置系统时钟源为PLL输出
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK); // 选择PLL作为系统时钟源 // 配置总线时钟分频
RCC_HCLKConfig(RCC_SYSCLK_Div1); // AHB总线时钟 = SYSCLK/1 (72MHz)
RCC_PCLK1Config(RCC_HCLK_Div2); // APB1总线时钟 = HCLK/2 (36MHz)
RCC_PCLK2Config(RCC_HCLK_Div1); // APB2总线时钟 = HCLK/1 (72MHz) // 使能内部低速时钟(LSI)和高速时钟(HSI)
RCC_LSICmd(ENABLE); // 使能LSI(约40kHz,用于看门狗等)
while (RCC_GetFlagStatus(RCC_FLAG_LSIRDY) == RESET); // 等待LSI就绪
RCC_HSICmd(ENABLE); // 使能HSI(16MHz内部RC时钟)
while (RCC_GetFlagStatus(RCC_FLAG_HSIRDY) == RESET); // 等待HSI就绪
}
外部高速时钟(HSE):使能 HSE 并等待其就绪,为后续锁相环(PLL)提供稳定的输入时钟源。
锁相环(PLL):以 HSE 为输入源,设置倍频系数为 9,使能 PLL 并等待其就绪,得到更高频率的时钟信号。
系统时钟源:将系统时钟源设置为 PLL 输出,提高系统整体运行速度。
总线时钟分频:对 AHB、APB1 和 APB2 总线时钟进行合理分频,满足不同外设的时钟需求。
内部低速时钟(LSI)和高速时钟(HSI):使能 LSI 和 HSI 并等待它们就绪,其中 LSI 用于后续测量。
2.初始化操作
延时函数:调用 delay_init() 初始化延时函数,为后续可能的延时操作做准备。
串口通信:调用 UART_Configuration(115200) 配置串口通信,波特率为 115200,用于输出系统时钟信息、测试提示以及测量结果。
获取时钟频率:使用 RCC_GetClocksFreq(&clocks) 获取系统时钟频率信息,为定时器配置提供参数。
3. 定时器配置
时钟使能:使能 TIM5 和复用功能(AFIO)的时钟,确保 TIM5 能够正常工作,并允许对其引脚进行重映射。
引脚重映射:将 TIM5 的通道 4 重映射到 LSI 信号,以便对 LSI 信号进行捕获。
时基单元初始化:设置 TIM5 的自动重载值为 0xFFFF,预分频器值根据 PCLK1 频率计算得出,时钟分割为 1,计数模式为向上计数,确定定时器的计数范围和计数速度。
输入捕获配置:将 TIM5 的通道 4 配置为输入捕获模式,采用上升沿捕获,直接映定时器溢出和捕获到信号边沿时能够及时响应。
定时器使能:使能 TIM5,开始对 LSI 信号进行计数和捕获。
4.主循环处理
int main(void)
{// ...(前半部分初始化代码略)TIM_Configuration(); // 初始化TIM5while (1){if (TIM5_CAPTURE_STA & 0X80) // 检测捕获完成标志(最高位为1){// 计算总时间(考虑定时器溢出次数)
temp = (TIM5_CAPTURE_STA & 0X3F) * 65536 + TIM5_CAPTURE_VAL; // 溢出次数×65536 + 捕获值printf("LSI The period is:%d us\r\n", temp); // 输出周期(微秒)printf("LSI The frequency is:%f Hz\r\n", (float)(1000000 / temp)); // 计算频率并输出
TIM5_CAPTURE_STA = 0; // 清零标志,准备下一次捕获}}
}
使用TI4,不分频且不进行滤波,以准确捕获 LSI 信号的上升沿和下降沿。
中断配置:配置 TIM5 的中断优先级,使能更新中断和通道 4 捕获中断,确保在
在主循环中,持续检查 TIM5_CAPTURE_STA 的最高位。若该位为 1,表示成功捕获到一个完整的 LSI 信号周期。此时,计算该周期的总时间(考虑定时器溢出情况),并通过串口输出 LSI 的周期和频率。最后,将 TIM5_CAPTURE_STA 清零,准备下一次捕获。
5. 中断服务函数处理
当 TIM5 产生更新中断或通道 4 捕获中断时,进入中断服务函数:
若还未成功捕获到一个完整的周期:
对于更新中断,若已捕获到上升沿,则记录定时器溢出次数。
对于通道 4 捕获中断:
若已捕获到上升沿,此时捕获到下降沿,标记成功捕获到一个完整的高脉冲宽度,并记录捕获值。
若还未开始捕获,此时捕获到上升沿,清零相关变量,设置计数器为 0,并标记捕获到上升沿。
最后,清除更新中断和通道 4 捕获中断标志位,为下一次中断做好准备。
3 下载验证
3.1 TIM_Basic例程
烧录完成后,硬件启动,串口输出系统时钟频率信息及“TIM Basic Test.”提示,定时器TIM3配置为向上计数模式,计数周期达9999时触发更新中断,在中断服务函数中检查并清除中断标志,通过串口输出函数名`TIM3_IRQHandler,之后主函数进入无限循环持续等待并响应定时器中断。
3.2 TIM_CalibrationLsi例程
代码烧录后,系统先对时钟进行配置,启动串口并输出系统时钟频率信息及“TIM5 Calibration LSI Test.”提示,接着配置TIM5定时器用于测量低速内部时钟(LSI),当TIM5捕获到LSI信号的上升沿和下降沿后,主循环会计算并通过串口输出LSI的周期和频率,期间持续等待新的捕获事件。