【stm32】定时器(超详细)

TIM定时器

定时器可以对输入的时钟进行计数,并在计数值达到设定值时触发中断

16位 计数器、预分频器、自动重装寄存器(计数的目标值)的时基单元,在72MHz计数时钟下可以实现最大59.65s的定时(72M/65526/65526 = 中断频率,取倒数就为59.65s ,2的16次方=65526)

更长时间:级联模式,即一个定时器的输出,当作另一个定时器的输入,这样最大时间就是58.65s × 65536 × 65536

不仅具备基本的定时中断 功能,而且还包含内外时钟源选择、输入捕获、输出比较、编码器接口、主从触发模式等多种功能

根据复杂度和应用场景分为了高级定时器、通用定时器、基本定时器 三种类型

STM32F103C8T6定时器资源:TIM1、TIM2、TIM3、TIM4

基本定时器


预分频器,自动重装寄存器,计数器 ,构成了最基本的计数计时电路,叫作时基单元

预分频器之前连接的是基准计数时钟的输入,因为基本定时器只能选择内部时钟,所以可以认为直接连到了输入端,即内部时钟CK_INT,内部时钟的来源是RCC_TIMxCLK,频率值一般都是系统的主频72MHz,所以通向时基单元的计数基准频率为72M

预分频器 可以对这72MHz的计数时钟进行预分频,比如,预分频器写0,这时输入频率 = 输出频率 = 72MHz ; 预分频器写1,为2分频,此时输出频率 = 输入频率/2 = 36MHz;预分频器写2,为3分频,此时输出频率 = 输入频率/3 ,所以预分频器的值和实际分频系数相差1,即实际分频系数 = 预分频器的值 + 1,因为为16位,最大可以写65535,即65536分频

计数器可以对预分频后的计数时钟进行计数,因为为16位,所以里面的值可以从0一直加到65535,再加就会从0重新开始。计数器的值在计时过程中会不断自增运行,当自增运行到目标值,产生中断,就完成了定时的任务

自动重装寄存器,存储目标值,当计数值 = 自动重装值,也就是计数时间到了,就会产生一个中断信号,并清零计数器,计数器自动开启下一次的计数计时

图中向上折线箭头 ,代表这里会产生中断信号,像这样,计数值 = 自动重装值产生的中断,一般叫做"更新中断",这个更新中断之后就会通往NVIC,我们再配置好NVIC的定时器通道,那么定时器的更新中断就能够得到CPU的响应了

图中向下折线的箭头 ,代表会产生一个事件,叫作"更新事件",不会触发中断,但可以触发内部其他电路的工作

主模式触发DAC功能 :能让内部的硬件在不受程序控制下实现自动运行,在某些场景下可以极大减轻CPU负担
用途 :在我们使用DAC的时候,可能会用DAC输出一段波形,那就需要每隔一段时间触发一次DAC,让它输出下一个电压点,
正常思路 :先设置一个定时器产生中断,每隔一段时间在中断程序中调用代码手动触发一次DAC转换,然后DAC输出,没有问题,但是却会使主程序处于频繁被中断的状态,会影响主程序的运行和其他中断的响应,故定时器设计了主模式,可以把定时器的更新事件,映射到触发输出TRGO的位置,然后TRGO直接接到DAC的触发转换引脚上,这样,定时器的更新就不需要通过中断来触发DAC转换了,仅需把更新事件通过主模式映射到TRGO,然后TRGO就会直接触发DAC,实现了硬件的自动化

通用定时器

基本定时器仅支持向上计数模式

通用定时器和高级定时器还支持向下计数模式和中央对齐模式
中央对齐模式:从0开始,先向上自增,计到重装值,申请中断;再向下自减,减到0,申请中断,循环

内外时钟源选择结构:通用定时器时钟源不仅可以选择内部72MHz时钟,也可以选择外部时钟

TIMx_ETR

引脚定义表中,TIM2_CH1_ETR,就是TIM2的CH1和ETR都复用在PA0引脚

可以在TIM2的ETR引脚,也就是PA0上接一个外部方波时钟,再配置一下内部的极性选择、边沿检测和预分频器电路 ,再配置输入滤波电路 ,这两个电路可以对外部时钟进行一定整形,因为外部引脚的时钟难免会有毛刺,那么这些电路就可以对输入的波形进行滤波,滤波后的信号,兵分两路 ,上面一路ETRF进入触发控制器,紧跟着就可以作为时基单元的时钟。如果想在ETR外部引脚提供时钟,或者想对ETR时钟进行计数,把这个定时器当作计数器 来用,就可以配置这一路的电路,这一路叫作"外部时钟模式2 ";下面一路TRGI也可以提供时钟,主要是用作触发输入 来使用,触发输入可以触发定时器的从模式,当TRGI当作外部时钟使用时,这一路叫作"外部时钟模式1"

外部输入模式1:

ETR引脚的信号可以通过上一路当作时钟,也可以通过下一路当作时钟,两种情况对于时钟输入是等价的,只不过下一路输入会占用触发输入的通道。

ITR信号 ,这一部分的时钟信号是来自其他定时器 的,这个主模式的输出TRGO可以通向其他定时器,通向其他定时器时,就接到了其他定时器的ITR引脚上了,ITR0到ITR3分别来自其他4个定时器的TRGO输出

比如,可以先初始化TIM3,然后使用主模式将它的更新事件映射到TRGO上,再初始化TIM2(选择ITR2,对应的是TIM3的TRGO),后面再选择时钟为外部时钟模式1,这样TIM3的更新事件就可以驱动TIM2的时基单元,也就实现了定时器的级联

也可选择TI1F_ED,连接的是输入捕获单元的CH1引脚,也就是从CH1引脚获得时钟,后缀加一个ED(edge)就是边沿的意思,也就是通过这一路输入的时钟,上升沿和下降沿均有效

也可以通过TI1FP1TI2FP2获得,TI1FP1是CH1引脚的时钟,TI2FP2是CH2引脚的时钟

编码器接口:可以读取正交编码器的输出波形

定时器的主模式输出,这部分电路可以把内部的一些事件映射到TRGO引脚上,我们可以把定时器内部的一些事件映射到这里来,用于触发其他定时器、DAC或ADC,触发输出的范围比基本定时器更广

右边为输出比较电路 ,总共有四个通道,分别对应CH1到CH4的引脚,可以用于输出PWM波形,驱动电机;左边为输入捕获电路 ,也有四个通道,对应也是CH1到CH4的引脚,可以用于测输入方波的频率;中间这个寄存器是捕获/比较寄存器,为输入捕获电路和输出比较电路共用,因为输入捕获和输出比较不能同时使用,所以寄存器是共用的,引脚也是共用的

高级定时器

相较于通用定时器,不同处:

申请中断的地方,增加一个重复次数计数器,可以实现每隔几个计数周期,才发生一次更新事件和更新中断,相当于对输出的更新信号又做了一次分频

DTG(死区生成电路) ,右边的输出引脚由原来的一个,变为了两个互补的输出,可以输出一对互补的PWM波,这些电路是为了驱动三相无刷电机,因为三相无刷电机一般需要三个桥臂,每个桥臂需要两个大功率开关管来控制,所以这里输出PWM引脚的前三路就变为了互补输出。

为了防止互补输出的PWM驱动桥臂时,在开关切换的瞬间,由于器件不理想,造成短暂直通现象,所以前面就加上了死区生成电路,在开关切换的瞬间,产生一定时长的死区,让桥臂的上下管全都关断,防止直通现象。

刹车输入功能:为了给电机驱动提供安全保障,如果外部引脚BKIN产生了刹车信号,或者内部时钟失效,产生了故障,那么控制电路就会自动切断电机的输出,防止意外的发生

定时中断基本结构

中断信号会现在状态寄存器里置一个中断标志位,这个标志位会通过中断输出控制 ,到NVIC申请中断

定时器有很多部分需要申请中断,如更新中断,触发信号,输入捕获和输出比较,这些中断都需要经过中断输出控制(中断输出的允许位)

预分频器时序


CK_PSC ,预分频器的输入时钟
CNT_EN ,计数器使能,高电平计数器正常运行,低电平计数器停止
CK_CNT,计数器时钟,既是预分频器的时钟输出,也是计数器的时钟输入

图中,刚开始,计数器未使能,计数器时钟不运行,使能后,前半段预分频器系数为1,计数器的时钟等于预分频器前的时钟,后半段,预分频器的系数变为2,计数器时钟就变为预分频器前时钟的一半了。

在计时器时钟的驱动下,下面的计数器寄存器也跟随时钟的上升沿不断自增,在中间FC位置之后,计数值变为0,ARR自动重装值就是FC,同时,下面产生一个更新事件。

预分频器缓冲机制:

预分频寄存器实际有两个,一是预分频控制寄存器 ,供我们读写用,并不直接决定分频系数,,二是缓冲寄存器(影子寄存器) ,真正起作用。当我在计数记到一半时改变了分频值,这个变化不会立刻生效,而是等到本次计数周期结束时 ,预分频计数器的值才会被传递到缓冲寄存器里去,才会生效。

预分频器内部实际上也是靠计数分频,预分频值为0时,计数器就一直为0,直接输出原频率;当预分频器为1时,计数器就0、1、0、1这样计数,在回到0的时候输出一个脉冲,这样输出频率就是输入频率的二分频。

复制代码
计数器计数频率:CK_CNT = CK_PSC / (PSC + 1)

计数器时序

内部时钟分频因子 为2,即分频系数 为2
CK_INT ,内部时钟72MHz

计数器在每个上升沿自增,增到0036,发生溢出,下一个上升沿,计数器清零,产生一个更新事件脉冲,还会置一个更新中断标志位UIF,这个标志位只要置1,就会申请中断,然后中断响应后,需要在中断程序中手动清零

复制代码
 计数器溢出频率:CK_CNT_OV = CK_CNT / (ARR + 1)
				         = CK_PSC / (PSC + 1) / (ARR + 1)

ARR+1?:因为计数器的计数周期是 0 → ARR,总共经历了 (ARR + 1) 个时钟脉冲

在图中,带有黑色阴影的寄存器都具有影子寄存器这样的缓冲机制,比如,预分频器,自动重装寄存器,捕获比较寄存器,这个缓冲寄存器可以自己设置是否使用

计时器无预装时序(没有缓冲寄存器)

计数器正在自增计数,突然更改自动重装寄存器的值,由FF改为36,故,计数器寄存器自增到36时,直接更新,开启下一轮计数

计时器有预装时序

计数器正在自增计数,突然更改自动重装寄存器的值,由F5改为36,故,计数器寄存器自增到F5时,才产生更新事件,同时要更改的36才被传递到影子寄存器。

引入影子寄存器目的实际上是为了同步,让值的变化和更新事件同步发生,防止在运行途中更改造成错误。图中,更改自动重装寄存器时,计数器已经增到了F1,已经超过了36,如果不使用影子寄存器,F1只能一直增加,一直加到FFFF,再回到0,再加到36,才能产生更新

通过设置ARPE位,可以选择是否使用预装功能

RCC时钟树

时钟树 ,STM32中用来产生和配置时钟,并把配置好的时钟发送到各个外设的系统,时钟是所有外设运行的基础,所以时钟也是最先需要配置的东西,程序主函数之前还会执行一个SystemInit函数,这个函数就是用来配置时钟树的

左边是时钟的产生电路 ,右边是时钟的分配电路 ,中间SYSCLK 就是系统时钟72MHz

在时钟产生电路,有四个震荡源,分别为,内部8MHz高速RC振荡器(8 MHz HSI RC)外部4-16Hz高速石英晶体振荡器(4-16 MHz HSE OSE) ,也就是晶振,一般接8MHz,外部32.768KHz低速晶振(LSE OSC 32.768 KHz) ,一般是给RTC提供时钟,内部40KHz低速RC振荡器(LSI OSC 40 KHz) ,可以给看门狗提供时钟。

前两个高速晶振,是用来提供系统时钟的,AHB,APB1,APB2的时钟都是来源于这两个高速晶振,内部和外部的8MHz的晶振,外部的石英振荡器比内部的RC振荡器更加稳定,一般用外部晶振

ST配置过程:

首先会启动内部时钟,选择内部8MHz为系统时钟,暂时以内部8MHz的时钟运行,然后再启动外部时钟,配置外部时钟走上一路,进入PLL锁相环进行倍频,8MHz倍频9倍,得到72HMz,等到锁相环输出稳定后,选择锁相环输出为系统时钟

外部晶振出问题------程序时钟慢了大概十倍

CSS(时钟安全系统) ,负责切换时钟,可以监测外部时钟运行状态,一旦外部时钟失效,就会自动把外部时钟切换回内部时钟,保证系统时钟运行,防止程序卡死造成事故。

在高级定时器的刹车输入,一旦CSS检测到外部时钟失效,就会通过或门,立刻反映到输出比较,让输出控制的点击立刻停止,防止意外

在分配电路,首先系统时钟72MHz进入AHB总线,AHB总线有个预分频器,在SystemInit里配置的分配系数为1,那么AHB时钟就是72MHz,然后进入APB1总线,这里配置的分配系数为2,故APB1总线的时钟为72MHz/2 = 36MHz

注:本文为b站江协课程,为笔记

相关推荐
酷飞飞15 小时前
RTC和看门狗基于GD32F407VE的天空星的配置
stm32·单片机·嵌入式硬件·mcu
qq_4017004116 小时前
STM32的HardFault错误处理技巧
stm32
WD1372980155717 小时前
WD5030A,24V降5V,15A 大电流,应用于手机、平板、笔记本充电器
stm32·单片机·嵌入式硬件·智能手机·汽车·电脑·51单片机
日更嵌入式的打工仔17 小时前
GPIO 中断通用配置指南
stm32·单片机·嵌入式硬件
平凡灵感码头17 小时前
基于 STM32 的智能门锁系统,系统界面设计
stm32·单片机·嵌入式硬件
Truffle7电子18 小时前
STM32理论 —— 存储、中断
stm32·嵌入式硬件·嵌入式·存储·中断
报错小能手18 小时前
linux学习笔记(32)网络编程——UDP
单片机·嵌入式硬件
XiangrongZ20 小时前
江协科技STM32课程笔记(四)—定时器TIM(输入捕获)
笔记·科技·stm32
xyx-3v20 小时前
SPI四种工作模式
stm32·单片机·嵌入式硬件·学习
qiuiuiu41321 小时前
正点原子RK3568学习日志6-驱动模块传参
linux·c语言·开发语言·单片机·学习