2.4 定时器与TIM中断


时钟与时钟树

频率:如72Mhz即为每秒72M个脉冲

  • 时钟的源头
    晶振

  • 时钟树的分支
    分频器:分频器是一种将输入时钟信号的频率降低到其整数倍的电路。
    倍频器:倍频器则是将输入时钟信号的频率提高到其整数倍的电路。
    参考CSDN文章_时钟系统

他们可以通过改变频率实现不同频率的分支。

stm32时钟树

在这里插入图片描述
《STM32F103C8T6从入门到精通》SystemInit函数详细讲解
St公司的配置程序:江科大

  1. 8Mhz HSI做系统时钟
  2. 再打开HSE取8Mhz 再通过图中黄色路线到锁相环(PLL)倍频9倍,待锁相环输出稳定后,(红色区域)切换锁相环输出为系统时钟 但是,如果外部晶振HSE出现问题,就不会切换,而是继续使用系统内部时钟HSI.
  • 在参考手册中的RCC的CR寄存器中的HSION位的部分 找到了对上面过程的说明
    在这里插入图片描述
  1. APB1二分频为36mhz APB2不分频,为72mhz
    • PCLK2通常指的是APB2 (Advanced Peripheral Bus 2) 的时钟频率。它的频率通常是由更高频率的AHB (Advanced High-performance Bus) 时钟通过一个分频器来调整得到的。
    • 参考以下代码(位于systemInit函数中调用的SetSysClockTo72函数中)
      在这里插入图片描述
      在这里插入图片描述

stm32时钟树_站内跳转

时钟树动画简介

可以手动把系统时钟72mhz改成其他的吗?

可以通过更改这里的宏来实现。
具体代码梳理
在这里插入图片描述

ST公司给的外围设备配置文件 的 默认配置说明

《STM32F103C8T6从入门到精通》SystemInit函数详细讲解 该函数配置了系统时钟
在system_stm32f10x.c文件中提到

  • HSI 作为默认时钟源
    HSI (High Speed Internal):内部高速时钟,频率为 8 MHz。每次设备复位后,HSI 自动作为系统时钟源。
    SystemInit() 函数:在启动文件 startup_stm32f10x_xx.s 中定义的函数,用于配置系统时钟。该函数在跳转到主程序前被调用。
  • 时钟源故障处理
    如果用户选择的系统时钟源未能成功启动(例如,外部时钟源未正常工作),SystemInit() 函数将不做任何处理,系统将继续使用 HSI 作为时钟源。
    用户可以在 SetSysClock() 函数中添加代码来处理这种情况,例如重新配置时钟源或进行错误处理。
  • HSE 晶振配置
    HSE (High Speed External):外部高速时钟,通常由外部晶振提供。
    默认情况下,HSE 晶振的频率设置为 8 MHz 或 25 MHz,具体取决于所使用的 STM32F10x 产品。
    HSE_VALUE 定义在 stm32f10x.h 文件中,用于指定 HSE 的频率。
    如果使用 HSE 作为系统时钟源(直接或通过 PLL),并且使用了不同的晶振频率,需要调整 HSE_VALUE 以匹配实际使用的晶振频率。

定时器

cortex-M3 内核里有一个systick定时器(江科大的Delay函数就是用systick实现的)
而下面要提到的是核外外设,高级、通用、普通定时器

什么是定时器

定时器就是计数器
定时器就是计数器
定时器就是计数器
动画演示_B站
在这里插入图片描述

PS: 预分频器和计数器的长度都是16bit ,216 = 65536

  • 预分频器(Prescaler)·:预分频器的值规定在0 ~ n-1(n是输入时钟频率的数值)
    它像是计数器的一个助手,规定每隔几个脉冲向计数器报告一次,让计数器加1

    1. 当预分频的值为零时,每一个脉冲计数器加一次;设定值为1时,每隔两个脉冲,计数器加1。
    2. 预分频器的作用:可以增加定时器的定时上限:
    • 当预分频器设置为0时,一个脉冲就记一次,因为计数器最多定65536下,对应65536 * (1/72M) ≈ 0.00091秒。
    • 而当预分频器设置为65535时,每72M个脉冲记一次,因为计数器还是最多定65536下,对应时间为,65536 * 65536 * (1/72M) ≈ 59.65 秒 (计数器的值预分频器处理的记一次对应的脉冲数 再乘 一个脉冲对应的时间)
    • 可见,预分配器正是通过自己额外处理时钟脉冲数来提高总时间的
  • 计数器(Counter)

    • 基本定时器只有向上计数模式。(从零开始加)
    • 通用定时器与高级定时器有向上计数、向下计数(从设定值开始减)、中央计数模式。
  • 自动重装载寄存器(Auto Reload Register):在计数器到达该寄存器设定值时清零计数器,并同时(如果配置了)
    可触发中断。

定时器的类型

类型编号总线功能
高级定时器TIM1、TIM8APB2拥有通用定时器全部功能,并额外具有重复计数器、死区生成、互补输出、刹车输入等功能
通用定时器TIM2、TIM3、TIM4、TIM5APB1拥有基本定时器全部功能,并额外具有内外时钟源选择、输入捕获、输出比较、编码器接口、主从触发模式等功能
基本定时器TIM6、TIM7APB1拥有定时中断、主模式触发DAC的功能 如何理解主模式触发

STM32C8T6 只有TIM1,TIM2,TIM3,TIM4

影子寄存器 | 预装载寄存器(Preload Register)

在学习TIM定时器时了解到。影子寄存器的主要功能缓冲后台存储数据或配置设置,这样在执行某些关键操作时,可以避免由于直接修改主寄存器而导致的问题。

  • 作用(用时序图作示例)
    • 可看出当 预分频控制寄存器更改数值后,对应在定时器时钟的输出没有随之改变(预分频缓冲器在缓冲)
      而是等上一个定时器时钟记满(到下一个计数周期,触发更新事件),才起更改作用。
    • 省流版:让值的变化更新事件同步发生
      在这里插入图片描述
  • 在框图中的阴影标识 江科大

相关工程问题

一上电就进了定时中断?可能为了是避免影子寄存器的缓冲带来的副作用
在配置时基单元时,库函数为了让预分频器立刻起作用(因为有缓冲,要等事件才会更新数据),手动配置了一个事件,同时触发了定时中断


通用定时器 相关框图

用作文章查阅参考

在这里插入图片描述

  • 绿色部分(IC input compare)的细节图
    在这里插入图片描述
    TIM_ICInit、TIX、ICX、TIXFPX是什么
    • TIx :如用的是定时器2,TI1和TI2对应是 TIM2->CH1 和TIM2->CH2对应的引脚信号就是外部信号,是直接与管脚相连的信号,即通道x对应的引脚,图中还有一个问题就是TI1是可以是第一通道的外部信号进行触发,也可以设置为,第一通道,第二通道,第三通道异或进行触发。外部信号送往滤波器和边沿检测器
    • TIxFPx :经过滤波器和带极性选择的边缘检测器过后的产生的信号,叫触发有效信号,与管脚直连的信号可以被设置为高、低边沿触发
      至于TI1FP1和TI2FP2信号在上身沿计数还是下降沿计数受两点影响:
      1,极性(是否反向)
      2,边缘检测(上升沿还是下降沿)
    • ICx:映射信号
      IC1 IC2 IC3 IC4:通道有效信号,在他的前面是TIxFP和TRC信号,可以看出,TI1FP与TI2FP可以互相对应IC1和IC2,TI3FP和TI4FP可以互相对应IC3和IC4,这样的不同通道的交叉连接,就可以使一个TIxFP信号对应两个ICx也就是对应两个通道。这样做的目的是,可以通过两个通道去检测一个引脚上的信号,实现PWM输入时,可以由1个来计算周期,另一个来计算占空比。ICx信号被送入预分频器。 (PWMI模式用到)
      如下图可实现同时检测同一个引脚的两种特性
  • TI1FP2就是CH2(下面这一路)的交叉信号,TI1FP2是CH1的直连信号
    在这里插入图片描述
  • 红色部分 (OC Output Compare)

在这里插入图片描述

主从触发模式 (省去了中断,避免占用软件资源)

配置的库函数
1.TIM_SelectOutputTrigger(选择主模式输出触发源)
2.TIM_SelectInputTrigger (从模式选择输入)
3.TIM_SelectSlaveMode (从模式选择输出触发模式)

对于主从触发模式,st的数据手册手册介绍比较少,可参照定时器的信号触发与主从模式
在这里插入图片描述

  • 主模式: 选择信号用于触发别的外设 (控制别人)
    在手册的CCR1j寄存器部分有解释
    在这里插入图片描述
  • 从模式:接收其他外设或者自身外设的信号 用于控制自身定时器的运行。(被控制)
    在这里插入图片描述
    具体用法可查阅手册 定时器->定时器同步的章节

主模式输出TRGO至另一个从模式的ITRx跳转结构图,以完成定时器级联功能。
但是从模式的触发源不一定是上一个定时器的TRGO,也可以是其他信号。所以当我们选择一个定时器为从模式,不一定要有主模式的定时器的配置,只是单单希望利用一下从模式的功能比如复位、门控和触发功能也是未尝不可的


定时中断

在这里插入图片描述
一. 配置时钟源 (注意一点:这里的内部外部时钟的概念【脉冲】与时钟树的内部外部时钟源【震荡源输出到AHB总线】不同)
- 如果第二步打算配置为rcc的话,就初始化对应定时器的rcc时钟 (选择系统时钟rcc作为输入,起定时作用)
- 若第二步选择外部时钟,则配置为ETR (选择外部脉冲作为输入,如对射红外传感器,遮挡一次一个脉冲)(注意GPIO是指定的)
二. 选择输入时基单元的时钟(上图中黄色部分)

  • 以下是相关库函数 详细讲解
    在这里插入图片描述
    在这里插入图片描述
    配置外部时钟模式1,模式2可参考的文章:
    要有外部时钟模式2的原因:
    1. 在从模式控制器被占用时,还可以通过该模式直接引入ETR外部信号,对外部信号进行计数 视频解析
    2. 方便快捷
      这个文章直观的解释了:定时器时钟模式1、2与主从模式

b站大佬动画讲解
三. 配置时基单元
void TIM_TimeBaseInit(TIM_TypeDef* TIMx, TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct)

  • 参数1:对应定时器
  • 参数2:结构体里有五个参数
    • TIM_Period
      TIM_Period 设置了在下一个更新事件装入活动的自动重装载寄存器周期的值。

    • TIM_Prescaler
      TIM_Prescaler 设置了用来作为 TIMx 时钟频率除数的预分频值。

    • TIM_CounterMode
      配置计数方式(向上计数、向下计数、中央对齐计数)

    • TIM_ClockDivision (用于输入滤波)
      按一定频率对信号进行采样,来判断信号是否稳定(而这个采样频率来自于系统内部时钟,这里的参数就是对内部时钟再进行分频) b站讲解
      主要用于输入检测、死区时间设定等 STM32 时钟分割TIM_ClockDivision配置及使用详细说明

    • TIM_RepetitionCounter (高级定时器才有的功能,配置通用定时器时给0)
      重复计数器

四. 配置输出控制
- TIM_ITConfig用这个函数
- 其中有一个参数比较关键:TIM_IT (毕竟TIM外设有很多不同的中断)
- 在这里插入图片描述
更新中断(Update Interrupt) 是基于定时器自身的计数完成事件。
捕获/比较中断(Capture/Compare Interrupts) 是基于定时器计数器与特定通道的CCR值之间的关系。
触发中断(Trigger Interrupt) 是基于外部触发信号的到达。

五. 配置NVIC(配置中断优先级)

六. 运行控制(相当与一个总开关)开启定时器

OC(Output Compare)输出比较

  • 输出比较可以通过比较CNT与CCR寄存器值的关系,来对输出电平进行置1、置0或翻转的操作,用于输出一定频率和占空比的PWM波形
  • 每个高级定时器和通用定时器都拥有4个输出比较通道
  • 高级定时器的前3个通道额外拥有死区生成和互补输出的功能(多用于驱动三相无刷电机)

点击跳转比较输出结构图

OC_Mode 输出模式控制

模式介绍

模式描述
冻结CNT=CCR时,REF保持为原状态
匹配时置有效电平(理解为高电平)CNT=CCR时,REF置有效电平
匹配时置无效电平(理解为低电平)CNT=CCR时,REF置无效电平
匹配时电平翻转CNT=CCR时,REF电平翻转
强制为无效电平CNT与CCR无效,REF强制为无效电平
强制为有效电平CNT与CCR无效,REF强制为有效电平
PWM模式1向上计数:CNT<CCR时,REF置有效电平,CNT≥CCR时,REF置无效电平
向下计数:CNT>CCR时,REF置无效电平,CNT≤CCR时,REF置有效电平
PWM模式2向上计数:CNT<CCR时,REF置无效电平,CNT≥CCR时,REF置有效电平
向下计数:CNT>CCR时,REF置有效电平,CNT≤CCR时,REF置无效电平

PWM (Pulse Width Modulation)脉冲宽度调制

在具有惯性的系统中,可以通过对一系列脉冲的宽度进行调制,来等效地获得所需要的模拟参量,常应用于电机控速等领域

PWM参数:

  1. 频率 = 1 / TS
    频率越高越平稳
  2. 占空比 = TON / TS
    等效输出比
  3. 分辨率 = 占空比变化步距
    占空比变化的精细程度

在这里插入图片描述

  • PWM输出流程
  1. 按照定时中断配置的前两步配置好时钟(通常选择内部脉冲RCC)输入

  2. 接着配置时基单元

  3. 初始化输出比较单元

    • 其中要注意配置输出模式(TIM_Mode)及输出极性时 有几点要注意
      1. 输出模式 (这里要选择pwm1 或 pwm2 )
        在手册中对 捕获/比较 模式寄存器(TIMx_CCMR1)的描述中
        下面的
        有效电平(active)取决于输出极性
        的配置 在这里插入图片描述
        2.输出极性
        在手册对捕获/比较使能寄存器的描述中
        定义了有效电平(active)对应的电平状态
        在这里插入图片描述
  4. 需要注意的一点是:初始化GPIO时,要配置为复用推挽输出模式(将输出的控制权从输出寄存器转到定时器

  5. 最后配置计数器使能(总开关)
    在这里插入图片描述

    • 对于输出比较单元的配置函数参数,有一个结构体,在配置通用定时器时很多都用不到,所以我们可以用给的结构体初始化函数先给结构体初始化一下。
  • PWM参数计算
    • 一个变化周期 对应 计数器的计数周期
    • 频率等于一个变化周期的倒数
    • 占空比 Duty = CCR / (ARR + 1) 高电平计数值 比 总计数值
    • 分辨率 Reso = 1 / (ARR + 1)

IC (Input Compare) 输入捕获

  • 输入捕获模式下,当通道输入引脚出现指定电平跳变时,当前CNT的值将被锁存到CCR中,可用于测量PWM波形的频率、占空比、脉冲间隔、电平持续时间等参数
  • 每个高级定时器和通用定时器都拥有4个输入捕获通道
  • 可配置为PWMI模式,同时测量频率和占空比
  • 可配合主从触发模式,实现硬件全自动测量

点击跳转文内的 输入捕获结构框图讲解

频率测量

在这里插入图片描述

  • 测频法:在闸门时间T内,对上升沿计次,得到N,则频率
    𝑓𝑥=𝑁 / 𝑇 (即为测1s内的脉冲数) (适合高频信号)
  • 测周法:两个上升沿内,以标准频率fc计次,得到N ,则频率
    𝑓𝑥=𝑓𝑐 / 𝑁 (即为测一个周期的时间再取到倒数)(适合低频信号)

中界频率:测频法与测周法误差相等的频率点 (可用于判断用那种方法测量)
𝑓𝑚=√(𝑓𝑐 / 𝑇)

  • (大于fm测频法)当标准信号频率远低于被测信号频率时,Tc1窗口内的被测信号脉冲很多(N1很大),测频法得到的结果就越准确。 //要两个定时器实现,一个计时,一个记录脉冲
  • (小于fm测周法)当被测信号频率远低于标准信号频率时,Tx2窗口内的被测信号脉冲很多(N2很大),测周法得到的结果就很准确。 //只要一个定时器,输入捕获脉冲就开始计数,下一个边沿到达,读取时间。
    用STM32定时器测量信号频率——测频法和测周法

输入捕获模式 与 PWM输入模式

PWM输入模式是输入捕获模式的一个特例(具体不同请翻阅手册 定时器->PWM输入模式的章节)
在这里插入图片描述

  1. 按照定时中断配置的前两步配置好时钟(通常选择内部脉冲RCC)输入
  2. 接着配置时基单元
  3. 初始化输入捕获单元
    • 边沿检测 里可选择 上升、下降或是双边沿触发
    • 分频器的作用像是一个缓冲区:不分频就是每一个触发信号有效一次,二分频就是每两个触发信号有效一次。(在测PWM频率时应选不分频)
    • TIM_ICSelection:选择直连通道或是交叉(间接)通道或是TRC。 (看不明白请参考结构图)

如果要配置PWMI(PWM INPUT),即同时检测占空比、频率时。如果正常配置需要配置两次输入捕获单元,但是有一个库函数简化了过程 PWMI_Config函数 函数介绍 只支持ch1、ch2

  1. 配置从模式 (点击跳转主从模式讲解)
    • TIM_SelectInputTrigger (从模式选择输入)选择触发源
      在这里插入图片描述在这里插入图片描述
      表78的黄色部分可看出:TIM3可以通过TIM1(在TS = 000时),TIM2(在TS = 001时),TIM5(在TS = 010时)以及TIM4(在TS = 011时)进行触发。

    • TIM_SelectSlaveMode (从模式选择输出触发模式) //如果要检测PWM频率 就选reset

  2. 使能计数器

编码器模式

配置步骤:

  1. 首先初始化对应gpio(不要忘了rcc时钟,gpio和定时器的都要)
  2. 初始化时基单元 (可不预分频、预装载直接拉满)
    //可注意到:编码器模式不用配置时钟输入,因为编码器充当了信号输入
  3. 配置输入捕获单元(由结构图可知,只需配置 输入滤波与输入极性)
  4. 配置编码器输入
  5. 使能计数器

即使stm32硬件上不支持编码器模式,我们还可以通过exti中断处理其中一项信号,在上升/下降沿触发 读取另一项的电平


总结与反思

其实想输出比较、输入捕获、编码器模式这些都是硬件在支持,以减轻软件资源的压力。若是以后接触到的没有这些模式,也无妨,可以通过外部中断其实都可以实现,就是软件上麻烦一些。

对于中断有几点我容易忽略
1.stm32任何中断最后都要通过NVIC,所以不要忘记配置。
2.中断函数内不要放延时函数
3.中断函数最后记得清除标志位(而且保证清除对应的中断),否则将会出现抽象的问题,难以排查。

对于定时器的配置:
1.无论什么用定时器的哪个模式,最后一定不要忘记 给实际单元使能! TIM_Cmd(TIM3, ENABLE);
2.若用到gpio或是时钟输入 千万千万记得开启rcc时钟 (事故多发地)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值