STM32学习笔记(四)丨TIM定时器及其应用(定时中断、内外时钟源选择)_tim时钟

实际分频系数=预分配器写入的值+1
  预分频器是16位的寄存器,故最大值可以写入65535(

2

16

2^{16}

216),也就是65536分频。
  CNT计数器可以对预分频后的计数时钟CK_CNT进行计数。计数时钟CK_CNT每来一个上升沿,计数器的值就+1(只能递增)。计数器也是16位的,它的值可以是0~65535,如果再+1,计数器就会回到0重新开始计数。
  ARR自动重装寄存器存入计数器的计数目标,它也是16位的寄存器。在计数器运行不断自增的过程中,自动重装置就是一个固定的目标。计数器不断与重装寄存器进行比较,当计数值 = 自动重装值时,就说明计时时间到,这时自动重装寄存器就会输出一个中断信号,并且清零计数器,计数器自动开始下一次的计数计时。
  在图中的折线向上的箭头,就代表产生的一个中断信号。UI意为Update Interrupt,即更新中断,它是计数值等于自动重装值的中断。更新中断会通往NVIC,只要配置好NVIC的中断通道,那么定时器的更新中断就能得到CPU的响应了。
  在图中折线向下的箭头,就代表产生的一个事件。这里的U意为Update,即更新事件。更新中断不会触发中断,但可触发其他内部电路的工作。图中可以看到,自动重装寄存器也可响应其他外设产生的事件。

主从触发模式
  STM32的一大特色就是主从触发模式。它能让内部的硬件在不受程序的控制下实现自动运行,即实现硬件自动化。
  这里我的理解是:主模式,即作为信号的主人的模式,电路输出的信号能触发其他处于从模式的电路的响应。 正常来讲,在一个时刻只能执行一段代码,完成一个操作,如果能合理使用主从触发,就可以实现”一心二用“,将会极大地减少CPU运行负担(这里仅做简单了解即可,后续还会讲到)。
  以基本定时器主模式触发DAC为例:在我们使用DAC的时候,可能会用DAC输出一段波形,那就需要每隔一段时间来触发一次DAC,让它输出下一个电压点。如果按中断的思路,需要先设置一个定时器产生中断,每隔一段时间在中断程序中用代码手动触发一次DAC转换,然后DAC输出波形。这样操作没有错,但是这样会使主程序频繁处于被中断的状态,有可能会影响主程序的运行和其他中断的响应。所以定时器的主模式可以把定时器的更新事件U映射到触发输出TRGO(Trigger Out)的位置,再通过TRGO直接连接到DAC的触发转换引脚上。这样DAC转换就不需要定时器产生的中断来触发了,仅需要把更新事件U通过主模式映射到TRGO,TRGO自动触发DAC就可以实现。这里体现了主模式的作用:整个过程不需要软件的参与,实现了硬件的自动化

1.2.2 通用定时器工作原理及其结构

通用定时器拥有基本定时器全部功能,并额外具有内外时钟源选择、输入捕获、输出比较、编码器接口、主从触发模式等功能。 通用定时器的结构框图如下如所示:
在这里插入图片描述

  1. 通用定时器与基本定时器的异同

通用定时器最基本的结构也是时基单元,与基本定时器相同。可以认为通用定时器就是在基本定时器的基础上扩展了许多功能得到的。它在时基单元模块与基本定时器的区别是:计数器的计数模式不止向上计数一种。除了与基本定时器相同的向上计数的模式外,它还拥有以下两种模式:

  • 向下计数模式:计数从重装值开始,向下自减,到0之后回到重装值,同时产生更新中断和更新事件,依此循环。
  • 中央对齐模式:计数从0开始,向上自增,达到重装值后产生更新中断和更新之间,然后向下自减,达到重装值之后产生更新中断和更新事件,以此循环。
  1. 内外时钟源选择功能

结构图的上部分,为内外时钟源选择和主从触发模式的工作结构:
在这里插入图片描述
  首先来看内外时钟源选择的工作原理。基本定时器只能选择来自芯片内部的内部时钟CK_INT,也就是系统频率72MHz。而通用定时器不仅可以选择内部时钟,还可以选择外部时钟。具体有以下三种:

  • 来自TIMx_ETR引脚上的外部时钟ETR
    在这里插入图片描述
      TIMx_ETR引脚的位置可以参考引脚定义表中关于默认复用功能和重定义功能的定义,如下图所示。可以看到TIM2的CH1和ETR都复用在了引脚PA0上。其他定时器的引脚也可以在表中找到。
    在这里插入图片描述
      我们在TIMx_ETR引脚上外接一个方波时钟,进入的外部时钟ETR通过内部的极性选择、边沿检测和预分频器电路,产生外部时钟脉冲ETRP(这里我猜测P就是Pulse,即脉冲,暂时没有找到相关的解释)。之后再通过输入滤波电路,之后的信号兵分两路,上面的信号ETRF进入触发控制器(与内部时钟流程类似),之后就可以作为时基单元的时钟输入了,在STM32中,这一路称为 外部时钟模式2(如图中红线所示);另一路与其他信号通过一个数据选择器输出TRGI(Trigger In),当这个TRGI当作外部时钟来使用时,这一路就称为 外部时钟模式1(如图中黄线所示)。后者从名字上看,它主要是作为触发输入来使用的,这个触发输入可以触发定时器的从模式。关于从模式的内容之后再涉及,本节主要考量把这个触发输入当作外部时钟来考虑的情况。
  • 来自其他定时器的信号ITR
    请添加图片描述
      主模式的输出TRGO可以通向其他定时器,实际上通向的就是ITR引脚,通过这一路就可以实现定时器级联的功能。如上如黄线所示,ITR0到ITR3分别来自其他4个定时器的TRGO输出,具体的连接方式如下表所示:
    在这里插入图片描述
  • 来自TIMx_CH1的TI1_ED,即从CH1引脚连接的输入捕获模块获得时钟,ED意为Edge,意为通过这一路的时钟,上升沿和下降沿均有效。
  • 来自TIMx_CH1的TI1FP1和来自TIMx_CH2的TI2FP2

总结一下,外部时钟模式1的输入可以是ETR引脚、其他定时器、CH1引脚的边沿、CH1引脚和CH2引脚;外部时钟模式2的输入只能是ETR引脚。

  1. 编码器接口功能

图中的编码器接口,它可以读取正交编码器的输出模型,后续的课程也会讲到。

  1. 主从触发模式功能

图中的TRGO与基本定时器类似,它可以将定时器内部的一些事件映射到其他电路,从而完成其他电路的功能。

  1. 输出比较功能

通用定时器结构图的右下角即为定时器的输出比较功能的结构,如下图所示。有四个输出通道,分别对应CH1到CH4的引脚,可以用来输出PWM波形,驱动电机。
在这里插入图片描述

  1. 输入捕获电路

通用定时器的左下角即为输入捕获电路的结构图,它同输出比较功能一样有四个通道,对应CH1到CH4。可以用于测量输入方波的频率。因为输入捕获和输出比较不能同时使用,故中间的捕获/比较寄存器是输入捕获和输出比较电路共用的,CH1到CH4的引脚也是共用的。

### 关于江科大 STM32 输入捕获 学习笔记 教程 #### 什么是输入捕获? 输入捕获是一种通过定时器捕捉外部信号变化的功能。它通常用于测量脉冲宽度、频率或其他时间相关的参数。STM32定时器模块提供了强大的输入捕获功能,可以通过配置通道来检测特定事件并记录对应的时间戳。 在江科大的 STM32 学习笔记中提到,STM32定时器支持多种高级特性,其中包括 **输入捕获** 功能[^3]。该功能允许用户利用定时器的输入通道捕获外部信号的变化时刻,并将其转换为计数值以便进一步处理。 --- #### 配置输入捕获的关键步骤 以下是实现输入捕获的主要技术要点: 1. **选择合适的定时器** - 使用具有输入捕获功能的通用定时器(如 TIM2, TIM3 等)。这些定时器具备多个通道,可作为输入捕获使用。 2. **设置时钟** - 定时器的工作依赖内部或外部时钟。对于输入捕获应用,可以选择外部时钟以同步外部信号[^3]。 3. **配置输入捕获模式** - 设置定时器通道为输入捕获模式(IC Mode),并通过滤波器减少噪声干扰。 - 配置极性(上升沿、下降沿或双边沿触发)以及捕获预分频系数。 4. **启用中断或 DMA** - 当捕获到指定事件时,可通过中断服务程序读取捕获寄存器中的值,或者借助 DMA 将数据传输至内存缓冲区。 5. **计算实际时间间隔** - 利用捕获寄存器存储的计数值和定时器时基频率,可以推导出两次捕获之间的时间差。 --- #### 示例代码:基于 STM32 的输入捕获实现 以下是一个简单的输入捕获示例代码片段,展示如何配置 TIM2 进行输入捕获操作: ```c #include "stm32f10x.h" void TIM2_InputCapture_Init(void) { GPIO_InitTypeDef GPIO_InitStructure; TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_ICInitTypeDef TIM_ICInitStructure; // 启用相关外设时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); // 配置 PA0 (TIM2_CH1) 为复用输入模式 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; // 上拉输入 GPIO_Init(GPIOA, &GPIO_InitStructure); // 初始化 TIM2 时间基准结构体 TIM_TimeBaseStructInit(&TIM_TimeBaseStructure); TIM_TimeBaseStructure.TIM_Period = 65535; // 自动重装载值 TIM_TimeBaseStructure.TIM_Prescaler = 72 - 1; // 预分频器,假设系统时钟为 72 MHz TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); // 初始化 TIM2 输入捕获结构体 TIM_ICStructInit(&TIM_ICInitStructure); TIM_ICInitStructure.TIM_Channel = TIM_Channel_1; // 选择通道 1 TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising; // 上升沿捕获 TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; // 直接映射 TI1 TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1; // 不分频 TIM_ICInitStructure.TIM_ICFilter = 0xF; // 数字滤波器 TIM_ICInit(TIM2, &TIM_ICInitStructure); // 开启 TIM2 中断 TIM_ITConfig(TIM2, TIM_IT_CC1, ENABLE); // 启动定时器 TIM_Cmd(TIM2, ENABLE); } // 中断服务函数 void TIM2_IRQHandler(void) { if (TIM_GetITStatus(TIM2, TIM_IT_CC1) != RESET) { // 检查 CC1 中断标志 uint16_t capture_value = TIM_GetCapture1(TIM2); // 获取捕获值 TIM_ClearITPendingBit(TIM2, TIM_IT_CC1); // 清除中断标志 } } ``` 此代码展示了如何初始化 TIM2 并配置其通道 1 为输入捕获模式。当检测到上升沿时,会触发中断并将捕获值保存下来。 --- #### 参考资推荐 除了上述内容之外,还可以参考以下资深入学习: - STMicroelectronics 提供的《STM32 Reference Manual》详细描述了定时器架构及其工作原理[^1]。 - `Delay.h` 文件定义了一些基础延时函数,虽然不直接涉及输入捕获,但可以帮助理解硬件延迟的概念[^2]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值