一、通用定时器
1.1 回顾
stm32f103共有八个定时器,高级定时器(TIM1,TIM8);基本定时器(TIM6,TIM7);通过定时器(TIM2~TIM5); 本章重点讲解通用定时器的时钟模式,捕获输入,比较输出

1.2 特性
<1>计数器16bit(计数值:0~65535),支持递增计数、递减计数、中间计数
<2>预分频器16bit(分频系数:0~65535)
<3>可用于出发DAC、ADC
<4>在更新事件、触发事件、输入捕获、输出比较时可以产生中断/DMA请求
<5>4条独立通道可用于输入捕获、输出比较、输出PWM、单脉冲模式
<6>使用外部信号控制定时器且实现定时器级联
<7>支持编码器和霍尔传感器电路(一般用于电机控制)
二、定时器时钟
2.1 概要
计数器时钟可由下列时钟源提供
<1>内部时钟(CK_INT) :来自于RCC时钟(72Mhz)
<2>外部时钟模式1:外部输入脚(TIx),来自定时器通道1或者通道2引脚信号
<3>外部时钟模式2:外部触发输入(ETR),来自可以复用为TIMx_ETR的IO引脚
<4>内部触发输入(ITRx):使用一个定时器作为另一个定时器的预分频器,如可以配置一个定时器Timer1而作为另一个定时器Timer2的预分频器。

2.2 内部时钟

设置从模式控制寄存器(TIMx_SMCR)的SMS=000,则计数器时钟由内部时钟(72MHz)提供(常用)
2.3 外部时钟模式1
设置从模式控制寄存器(TIMx_SMCR)的SMS=111 (如图2.2)可以开启 外部时钟模式1

由图2.1可知:外部时钟模式1共有三路给到计数器,通过TS(图2.3)位可以进行选择
<1>SMS=111且TS=101时:TI1FP1(单边沿)给到计数器,也就是说当输入信号为上升沿/下降沿时计数器记一次数
<2>SMS=111且TS=110时:TI2FP2(单边沿)给到计数器,也就是说当输入信号为上升沿/下降沿时计数器记一次数
<3>SMS=111且TS=100时:TI1F_ED(双边沿)给到计数器,也就是说当输入信号为上升沿和下降沿时计数器记一次数,若相同的信号选择<3>的情况的计数器计的数是选择<2>或<1>的情况计数器计的数的2倍

如图2.3.1所示,可以通过配置ECE=0(该位用于关闭外部时钟模式2),SMS=111(该位开启外部时钟模式1) ,TS=110(该位用于输入选择),就可以将TI2FP2给到计数器
2.3.1 滤波器 ICF
TI2信号首先进入滤波器进行滤波,目的就是去除噪音、毛刺等不想要的信号

CK_INT为RCC时钟72MHz ,假设CKD=00,IC1F=0011;则采样频率为72MHz,此时N=8;也就意味着滤波器以72MHz进行采样,在如果连续8次所采样的信号都是相同的电平,则滤波后的信号就为对应的信号;如果连续八次内由不同的电平信号,则滤波后的信号则为上一次连续8次相同电平的信号

2.4 外部时钟模式2

由图2.1可知:对于外部时钟模式2,当输入信号从TIMx_ETR经过输入滤波器滤波后,分为两路,一路到ETRF,一路到TRGI;
由图2.4可知:当ECE=1时,信号从ETRF给到计数器;当SMS=111且TS=111(图2.3)时,信号从TRGI给到计数器

如图2.4.1所示,如果要配置在ETR下每2个上升沿计数一次的向上计数器,也就是说ETR两个上升沿,经过分频后的ETRP变为一个上升沿,所以需要2分频,步骤:
<1>开启外部时钟输入模式(ECE=1)
<2>开启上升沿检测(ETP=1)
<3>本例中不需要滤波器
<4>分频器开启2分频
2.5 内部触发模式
定时器级联:就是一个定时器(主模式)触发的信号作为另一个定时器(从模式)的时钟输入

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

对于主模式:
例如,时钟为RCC-72MHz,预分频器:7199,计数器:99,也就是说计数器更新事件10ms一次,即TRGO1——10ms产生一个脉冲给到ITR1
对于从模式:
ITR1的输入时钟为10ms->100Hz,设置从模式的预分频器为:9,则给到从模式计数器频率为10Hz
三、模式
3.1 比较(输出)

如图3.1 捕获/比较预装载器(CCR1)的值由用户写入,其对应的影子寄存器(不可直接访问)是否使能由OC1PE位决定;当compare_transfe=1时,预装载寄存器中的值写入对应影子寄存器,compare_transfe的值取决于①②③,也就是说想让compare_transfe=1,则①=0,②=1,③=1
<1>当write_in_progress=1说明用户正在往预装载寄存器中写值,这是(①到与门前要反向)compare_transfe不可能为1
<2>用户不在往预装载寄存器中写值,则write_in_progress=0,即①=0;CC1S位是配置通道的模式的,这里CC1S=00 ->②=1
<3>OCIPE位是决定是否使能影子寄存器的,OCIPE=1时(使能),只有当发生更新时间(UEV=1)时,③=1,由<1><2>知①=0,②=1,compare_transfe=1;若OCIPE=0时(不使能),这时③=1,写入预装载寄存器中的值立即生效

ETRF信号在图2.1 的底部,或者是外部时钟模式2的信号

OC1M位可以设置PWM模式1/PWM模式2
3.1.1 输出PWM原理
装载寄存器的值(ARR)与捕获/比较寄存器(CRRx)的值是由用户写的

图3.1.1.1 对应PWM模式1(OC1M=110)可知:PWM的周期/频率由ARR决定,占空比由CRRx决定
这里就可以解释为什么标题是比较(输出)了,计数器的值与自动(重)装载寄存器的值(ARR),捕获/比较寄存器(CRRx)的值相比较,根据一定规则输出高电平或者低电平。
3.2 捕获(输入)
外部信号输入到MCU,可以进行捕获


注意:由于捕获/比较影子寄存器不可以直接访问,而捕获/比预装载寄存器是可以直接访问的;如想要知道计数器的值,需要先将计数器的值捕获到 捕获/比较影子寄存器中,再将 捕获/比较影子寄存器中的值转到 捕获/比预装载寄存器中
<1>当发生捕获事件时,计数器中的值会被加载到 捕获/比较影子寄存器中,捕获事件可以由软件将CC1G置1发生;也可以检测到IC1PS信号并且开启使能CC1E=1时由硬件发生
<2>当capture_transfer=1时, 捕获/比较影子寄存器中的值会被转移的 捕获/比较预装载寄存器中;何时capture_transfer=1?当CC1S配置为输入且没有进行读操作(read_in_progress=0)时
3.2.1 输入脉宽测量原理

<1>现在有一个脉冲信号通过通道(CHx)进入,如何知道高电平的的时间t呢?
可以这样:当这个脉冲发生上升沿时(t1时刻),CNT的值会被捕获到CCRx寄存器中,发生了事件,此时,我们要做两件事,一是将CNT的值清零,二是将通道检测改为下降沿,这样在t2时刻下降沿触发,CNT的值又会被捕获到捕获寄存器CCRx中,若CNT=ARR是会发生溢出事件,当发生溢出事件时进行记录(溢出次数的总和为N),(若没有溢出N=0)这样在高电平期间,计数器计数的个数=N*(ARR+1)+CRR_t2,再根据计时器的频率就可以算出t了
<2>还有另一种方法,由图2.1 可知通道CH1的TI1FP1进入CH1的捕获输入寄存器中,TI1FP2可以进入CH2的捕获输入寄存器中,也就是说相同的信号可以进入不同的寄存器,如果将TI1FP1设置为上升沿检测,将TI1FP2设置为下升沿检测,当t1时刻来临时,计数器CNT的值捕获到CCR1;当t2时刻来临时,计数器CNT的值捕获到CCR2,在记录下溢出的次数,也可以算出高电平的时长
四、代码
代码就放在后面的文章里了。