STM32定时器

1、TIM 简介
  定时器 (Timer) 最基本的功能就是定时了,比如定时发送 USART 数据、定时采集 AD 数据等等。如果把定时器与 GPIO 结合起来使用的话可以实现非常丰富的功能,可以测量输入信号的脉冲宽度,可以生产输出波形。定时器生产 PWM 控制电机状态是工业控制普遍方法,这方面知识非常有必要深入了解。
  STM32F4xx 系列控制器有 2 个高级控制定时器、 10 个通用定时器和 2 个基本定时器,还有 2 个看门狗定时器。控制器上所有定时器都是彼此独立的,不共享任何资源。各个定时器特性参考下表:

  1.1、定时器的时钟源

  定时器要实现计数必须有个时钟源,基本定时器时钟只能来自内部时钟,高级控制定时器和通用定时器还可以选择外部时钟源或者直接来自其他定时器等待模式。我们可以通过 RCC 专用时钟配置寄存器 (RCC_DCKCFGR) 的 TIMPRE 位设置所有定时器的时钟频率,我们一般设置该位为默认值 0。

   RCC_DCKCFGR寄存器的TIMPRE设置为0时,只有APBx为1分频时,TIMx_CLK=1*PCLKx,当APB为其它分频时,TIMx_CLK=2*PCLKx。

  定时器时钟一般配置为下图所示,基本定时器和通用定时器的时钟来源于APB1为TIMxCLK = APB1_CLK*2=42*2=84MHz,高级定时器的的时钟来源于APB2为TIMxCLK = APB2_CLK*2=84*2=168MHz。

2、基本定时器
  基本定时器比高级控制定时器和通用定时器功能少,结构简单,理解起来更容易,我们就开始先讲解基本定时器内容。基本定时器主要两个功能,第一就是基本定时功能,生成时基,第二就是专门用于驱动数模转换器 (DAC)。
  控制器有两个基本定时器 TIM6 和 TIM7,功能完全一样,但所用资源彼此都完全独立,可以同时使用。
  基本上定时器 TIM6 和 TIM7 是一个 16 位向上递增的定时器,当我在自动重载寄存器(TIMx_ARR) 添加一个计数值后并使能 TIMx,计数寄存器 (TIMx_CNT) 就会从 0 开始递增,当TIMx_CNT 的数值与 TIMx_ARR 值相同时就会生成事件并把 TIMx_CNT 寄存器清 0,完成一次循环过程。如果没有停止定时器就循环执行上述过程。

  2.1、基本定时器的特性

  基本定时器( TIM6 和 TIM7)的特性包括:
    16 位自动重载递增计数器。
    16 位可编程预分频器,用于对计数器时钟频率进行分频(即运行时修改),分频系数介于 1 和 65536 之间。
    用于触发 DAC 的同步电路。
    发生如下更新事件时会生成中断/DMA 请求:计数器上溢。

  2.2、基本定时器功能框图
  基本定时器的功能框图包含了基本定时器最核心内容,掌握了功能框图,对基本定时器就有一个整体的把握,在编程时思路就非常清晰,见图 31‑1。
  首先先看图 31‑1 中绿色框内容,第一个是带有阴影的方框,方框内容一般是一个寄存器名称,比如图中主体部分的自动重载寄存器 (TIMx_ARR) 或 PSC 预分频器 (TIMx_PSC),这里要特别突出的是阴影这个标志的作用,它表示这个寄存器还自带有影子寄存器,在硬件结构上实际是有两个寄存器,源寄存器是我们可以进行读写操作,而影子寄存器我们是完全无法操作的,有内部硬件使用。影子寄存器是在程序运行时真正起到作用的,源寄存器只是给我们读写用的,只有在特定时候 (特定事件发生时) 才把源寄存器的值拷贝给它的影子寄存器。多个影子寄存器一起使用可以到达同步更新多个寄存器内容的目的。

  什么是影子寄存器?从框图上看,可以看到图 31‑1 中的预分频器 PSC 后面有一个影子,自动重载寄存器也有个影子,这就表示这些寄存器有影子寄存器。 影子寄存器是一个实际起作用的寄存器, 不可直接访问。举个例子:我们可以把预分频系数写入预分频器寄存器(TIMx_PSC),但是预分频器寄存器只是起到缓存数据的作用,只有等到更新事件发生时,预分频器寄存器的值才会被自动写入其影子寄存器中,这时才真正起作用。
  自动重载寄存器及其影子寄存器的作用和上述同理。不同点在于自动重载寄存器是否具有缓冲作用还受到 ARPE 位的控制,当该位置 0 时, ARR 寄存器不进行缓冲,我们写入新的ARR 值时,该值会马上被写入 ARR 影子寄存器中,从而直接生效;当该位置 1 时, ARR 寄存器进行缓冲,我们写入新的 ARR 值时,该值不会马上被写入 ARR 影子寄存器中,而是要等到更新事件发生才会被写入 ARR 影子寄存器,这时才生效。预分频器寄存器则没有这样相关的控制位,这就是它们不同点。
  值得注意的是, 更新事件的产生有两种情况,一是由软件产生,将 TIMx_EGR 寄存器的位 UG 置 1,产生更新事件后,硬件会自动将 UG 位清零。二是由硬件产生,满足以下条件即可:计数器的值等于自动重装载寄存器影子寄存器的值。下面来讨论一下硬件更新事件。
  基本定时器的计数器(CNT)是一个递增的计数器,当寄存器(TIMx_CR1)的 CEN 位置 1(即使能定时器),每来一个 CK_CNT 脉冲, TIMx_CNT(计数器) 的值就会递增加 1。当 TIMx_CNT(计数器)值与 TIMx_ARR(自动重载寄存器) 的设定值相等时, TIMx_CNT 的值就会被自动清零并且会生成更新事件(如果开启相应的功能,就会产生 DMA 请求、产生中断信号或者触发 DAC 同步电路),然后下一个 CK_CNT 脉冲到来, TIMx_CNT 的值就会递增加 1,如此循环。在此过程中, TIMx_CNT等于 TIMx_ARR 时,我们称之为定时器溢出,因为是递增计数,故而又称为定时器上溢。 定时器溢出就伴随着更新事件的发生。
  由上述可知,我们只要设置预分频寄存器和自动重载寄存器的值就可以控制定时器更新事件发生的时间。自动重载寄存器(TIMx_ARR)是用于存放一个与计数器作比较的值,当计数器的值等于自动重载寄存器的值时就会生成更新事件,硬件自动置位相关更新事件的标志位,如:更新中断标志位。
  下面举个例子来学习如何设置预分频寄存器和自动重载寄存器的值来得到我们想要的定时器上溢事件发生的时间周期。比如我们需要一个 500ms 周期的定时器中断,一般思路是先设置预分频寄存器,然后才是自动重载寄存器。考虑到我们设置的 CK_INT 为 84MHZ,我们把 预 分 频 系 数 设 置 为 8400 , 即 写 入 预 分 频 寄 存 器 的 值 为 8399 , 那 么fCK_CNT=84MHZ/8400=10KHZ。这样就得到计数器的计数频率为 10KHZ,即计数器 1 秒钟可以计 10000 个数。我们需要 500ms 的中断周期,所以我们让计数器计数 5000 个数就能满足要求,即需要设置自动重载寄存器的值为 4999,另外还要把定时器更新中断使能位 UIE (更新中断使能位)置 1,CEN(计数器使能位) 位也要置 1。
  接下来是一个指向右下角的图标,它表示一个事件,而一个指向右上角的图标表示中断和 DMA输出。这个我们把它放在图中主体更好理解。图中的自动重载寄存器有影子寄存器,它左边有一个带有“U”字母的事件图标,表示在更新事件生成时就把自动重载寄存器内容拷贝到影子寄存器内,这个与上面分析是一致。寄存器右边的事件图标、中断和 DMA 输出图标表示在自动重载寄存器值与计数器寄存器值相等时生成事件、中断和 DMA 输出。

   (1)、 时钟源

  定时器要实现计数必须有个时钟源,基本定时器时钟只能来自内部时钟,高级控制定时器和通用定时器还可以选择外部时钟源或者直接来自其他定时器等待模式。定时器的时钟配置可见1.1.
  基本定时器只能使用内部时钟,当 TIM6 和 TIM7 控制寄存器 1(TIMx_CR1) 的 CEN (计数器使能位)位置 1 时,启动基本定时器,并且预分频器的时钟来源就是 CK_INT。对于高级控制定时器和通用定时器的时钟源可以来找控制器外部时钟、其他定时器等等模式,较为复杂。

  CEN( TIMx_CR1 寄存器中计数器使能位)和 UG 位( TIMx_EGR 寄存器中)为实际控制位,并且只能通过软件进行更改(保持自动清零的 UG 除外)。当对 CEN 位写入 1 时,预分频器的时钟就由内部时钟 CK_INT 提供。
  图 197 显示了正常模式下控制电路与递增计数器的行为(没有预分频的情况下)。

  (2)、控制器
  定时器控制器控制实现定时器功能,控制定时器复位、使能、计数是其基础功能,基本定时器还专门用于 DAC 转换触发。

  (3)、计数器(时基单元)
  基本定时器计数过程主要涉及到三个寄存器内容,分别是计数器寄存器 (TIMx_CNT)、预分频器寄存器 (TIMx_PSC)、自动重载寄存器 (TIMx_ARR),这三个寄存器都是 16 位有效数字,即可设置值为 0 至 65535。

  可编程定时器的主要模块由一个 16 位递增计数器及其相关的自动重载寄存器组成。计数器的时钟可通过预分频器进行分频。
  计数器、自动重载寄存器和预分频器寄存器可通过软件进行读写。即使在计数器运行时也可执行读写操作。
  时基单元包括:
  ● 计数器寄存器 (TIMx_CNT):计数
  ● 预分频器寄存器 (TIMx_PSC):分频
  ● 自动重载寄存器 (TIMx_ARR):设定定时器的计数上限

  自动重载寄存器是预装载的。每次尝试对自动重载寄存器执行读写操作时,都会访问预装载寄存器。预装载寄存器的内容既可以直接传送到影子寄存器,也可以在每次发生更新事件 UEV 时传送到影子寄存器,这取决于 TIMx_CR1 寄存器中的自动重载预装载使能位 (ARPE)。当计数器达到上溢值并且 TIMx_CR1 寄存器中的 UDIS 位为 0(使能更新事件) 时,将发送更新事件。该更新事件也可由软件产生。下文将针对各配置的更新事件的产生进行详细介绍。
  计数器由预分频器输出 CK_CNT 提供时钟,仅当 TIMx_CR1 寄存器中的计数器启动位 (CEN)置 1 时,才会启动计数器。
  请注意,实际的计数器使能信号 CNT_EN 在 CEN 置 1 的一个时钟周期后被置 1。
  我们再来看图 31‑1 中预分频器 PSC,它有一个输入时钟 CK_PSC 和一个输出时钟 CK_CNT。输入时钟 CK_PSC 来源于控制器部分,基本定时器只有内部时钟源所以 CK_PSC 实际等于 CK_INT,即 84MHz。在不同应用场所,经常需要不同的定时频率,通过设置预分频器 PSC 的值可以非常方便得到不同的 CK_CNT,实际计算为: fCK_CNT == fCK_PSC/(PSC[15:0]+1)。

  预分频器说明
  预分频器可对计数器时钟频率进行分频,分频系数介于 1 和 65536 之间。该预分频器基于TIMx_PSC 寄存器中的 16 位寄存器所控制的 16 位计数器。由于 TIMx_PSC 控制寄存器有缓冲,因此可对预分频器进行实时更改。而新的预分频比将在下一更新事件发生时被采用。
  图 189 和图 190 给出了在预分频比发生实时变化时一些计数器行为的示例。

  下图是将预分频器 PSC 的值从 1 改为 2或4时计数器时钟变化过程。原来是 1 分频, CK_PSC 和CK_CNT 频率相同。向 TIMx_PSC 寄存器写入新值时,并不会马上更新 CK_CNT 输出频率,而是等到更新事件发生时,把 TIMx_PSC 寄存器值更新到影子寄存器中,使其真正产生效果。更新为 2或4 分频后,在 CK_PSC 连续出现 2个或4 个脉冲后 CK_CNT 才产生一个脉冲。

  在定时器使能 (CEN 置 1) 时,计数器 COUNTER 根据 CK_CNT 频率向上计数,即每来一个CK_CNT 脉冲, TIMx_CNT 值就加 1。当 TIMx_CNT 值与 TIMx_ARR 的设定值相等时就自动生成事件并 TIMx_CNT 自动清零,然后自动重新开始计数,如此重复以上过程。为此可见,我们只要设置 CK_PSC 和 TIMx_ARR 这两个寄存器的值就可以控制事件生成的时间,而我们一般的应用程序就是在事件生成的回调函数中运行的。在 TIMx_CNT 递增至与 TIMx_ARR 值相等,我们叫做为定时器上溢。
  自动重载寄存器 TIMx_ARR 用来存放于计数器值比较的数值,如果两个数值相等就生成事件,将相关事件标志位置位,生成 DMA 和中断输出。 TIMx_ARR 有影子寄存器,可以通过 TIMx_CR1寄存器的 ARPE 位控制影子寄存器功能,如果 ARPE 位置 1,影子寄存器有效,只有在事件更新时才把 TIMx_ARR 值赋给影子寄存器。如果 ARPE 位为 0,修改 TIMx_ARR 值马上有效。

  2.3、计数模式
  计数器从 0 计数到自动重载值( TIMx_ARR 寄存器的内容),然后重新从 0 开始计数并生成计数器上溢事件。
  每次发生计数器上溢时会生成更新事件,或将 TIMx_EGR 寄存器中的 UG(更新生成) 位置 1(通过软件或使用从模式控制器)也可以生成更新事件。
  通过软件将 TIMx_CR1 寄存器中的 UDIS(更新禁止位) 位置 1 可禁止 UEV 事件。这可避免向预装载寄存器写入新值时更新影子寄存器。这样,直到 UDIS 位中写入 0 前便不会生成任何更新事件,但计数器和预分频器计数器都会重新从 0 开始计数(而预分频比保持不变)。此外,如果TIMx_CR1 寄存器中的 URS 位(更新请求选择)已置 1,则将 UG 位置 1 会生成更新事件UEV,但不会将 UIF 标志置 1(因此,不会发送任何中断或 DMA 请求)。
  发生更新事件时,将更新所有寄存器且将更新标志( TIMx_SR 寄存器中的 UIF 位)置 1(取决于 URS 位):
  ● 使用预装载值( TIMx_PSC 寄存器的内容)重新装载预分频器的缓冲区
  ● 使用预装载值 (TIMx_ARR) 更新自动重载影子寄存器
  以下各图显示了当 TIMx_ARR=0x36 时不同时钟频率下计数器行为的示例。

  2.4、定时器周期计算
  经过上面分析,我们知道定时事件生成时间主要由 TIMx_PSC 和 TIMx_ARR 两个寄存器值决定,这个也就是定时器的周期。比如我们需要一个 1s 周期的定时器,具体这两个寄存器值该如何设置内。假设,我们先设置 TIMx_ARR 寄存器值为 9999,即当 TIMx_CNT 从 0 开始计算,刚好等于 9999 时生成事件,总共计数 10000 次,那么如果此时时钟源周期为 100us 即可得到刚好 1s 的定时周期。接下来问题就是设置 TIMx_PSC 寄存器值使得 CK_CNT 输出为 100us 周期 (10000Hz) 的时钟。预分频器的输入时钟 CK_PSC 为 84MHz,所以设置预分频器值为 (8400-1) 即可满足。

3、高级控制定时器
  高级控制定时器 (TIM1 和 TIM8) 和通用定时器在基本定时器的基础上引入了外部引脚,可以实现输入捕获和输出比较功能。高级控制定时器比通用定时器增加了可编程死区互补输出、重复计数器、带刹车 (断路) 功能,这些功能都是针对工业电机控制方面。
  高级控制定时器时基单元包含一个 16 位自动重装载寄存器 ARR,一个 16 位的计数器 CNT,可向上/下计数,一个 16 位可编程预分频器 PSC,预分频器时钟源有多种可选,有内部的时钟、外部时钟。还有一个 8 位的重复计数器 RCR,这样最高可实现 40 位的可编程定时
  STM32F407ZGT6 的高级/通用定时器的 IO 分配具体见表 32-1。配套开发板因为 IO 资源紧缺,定时器的 IO 很多已经复用它途,故下表中的 IO 只有部分可用于定时器的实验。
  表 32‑1 高级控制和通用定时器通道引脚分布

  3.1、高级定时器TIM1 和 TIM8 主要特性

  TIM1 和 TIM8 定时器具有以下特性:
  ● 16 位递增、递减、递增/递减自动重载计数器。
  ● 16 位可编程预分频器,用于对计数器时钟频率进行分频(即运行时修改),分频系数介于 1 到 65536 之间。
  ● 多达 4 个独立通道,可用于:
  — 输入捕获
  — 输出比较
  — PWM 生成(边沿和中心对齐模式)
  — 单脉冲模式输出
  ● 带可编程死区的互补输出。
  ● 使用外部信号控制定时器且可实现多个定时器互连的同步电路。
  ● 重复计数器,用于仅在给定数目的计数器周期后更新定时器寄存器。
  ● 用于将定时器的输出信号置于复位状态或已知状态的断路输入。
  ● 发生如下事件时生成中断/DMA 请求:
  — 更新:计数器上溢/下溢、计数器初始化(通过软件或内部/外部触发)
  — 触发事件(计数器启动、停止、初始化或通过内部/外部触发计数)
  — 输入捕获
  — 输出比较
  — 断路输入
  ● 支持定位用增量(正交)编码器和霍尔传感器电路。
  ● 外部时钟触发输入或逐周期电流管理。

  3.2、 高级控制定时器功能框图

  高级控制定时器功能框图包含了高级控制定时器最核心内容,掌握了功能框图,对高级控制定时器就有一个整体的把握,在编程时思路就非常清晰,见图中有些寄存器是带影子的,表示其有影子寄存器。

  3.2.1、 时钟源
  高级控制定时器有四个时钟源可选:
    内部时钟源 CK_INT。
    外部时钟模式 1:外部输入引脚 TIx(x=1,2,3,4)。
    外部时钟模式 2:外部触发输入 ETR。
    内部触发输入 (ITRx):使用一个定时器作为另一定时器的预分频器,例如,可将定时器1 配置为定时器 2 的预分频器。
  (1)、内部时钟源 (CK_INT)
    内部时钟 CK_INT 即来自于芯片内部,等于 168M,一般情况下,我们都是使用内部时钟。当从模式控制寄存器 TIMx_SMCR 的 SMS 位等于 000 时,则使用内部时钟。

  如果禁止从模式控制器 (SMS=000),则 TIMx_CR1 寄存器中CEN 位(计数器使能位)、 DIR 位(方向,即递增递减)和TIMx_EGR 寄存器中 UG 位(更新生成)为实际控制位,并且只能通过软件进行更改( UG 除外,仍保持自动清零)。当对 CEN 位写入 1 时,预分频器的时钟就由内部时钟 CK_INT 提供。
  图 92 显示了正常模式下控制电路与递增计数器的行为(没有预分频的情况下)。

  (2)外部时钟模式 1    

  1)时钟信号输入引脚

  当使用外部时钟模式 1 的时候,时钟信号来自于定时器的输入通道,总共有 4 个,分别为 TI1/2/3/4,即 TIMx_CH1/2/3/4。具体使用哪一路信号,由 TIM_CCMRx 的位 CCxS[1:0] 配置,其中 CCMR1控制 TI1/2, CCMR2 控制 TI3/4。
  2)滤波器
  如果来自外部的时钟信号的频率过高或者混杂有高频干扰信号的话,我们就需要使用滤波器对信号重新采样,来达到降频或者去除高频干扰的目的,具体的由 TIMx_CCMRx 的位 ICxF[3:0] 配置。
  3)边沿检测
  边沿检测的信号来自于滤波器的输出,在成为触发信号之前,需要进行边沿检测,决定是上升沿有效还是下降沿有效,具体的由 TIMx_CCER 的位 CCxP 和 CCxNP 配置。
  4)触发选择
  当使用外部时钟模式 1 时,触发源有两个,一个是滤波后的定时器输入 1(TI1FP1)和滤波后的定时器输入 2(TI2FP2),具体的由 TIMxSMCR 的位 TS[2:0] 配置。
  5)从模式选择
  选定了触发源信号后,最后我们需把信号连接到 TRGI 引脚,让触发信号成为外部时钟模式 1 的输入,最终等于 CK_PSC,然后驱动计数器 CNT 计数。具体的配置 TIMx_SMCR 的位 SMS[2:0]为 000 即可选择外部时钟模式 1。
  6)使能计数器
  经过上面的 5 个步骤之后,最后我们只需使能计数器开始计数,外部时钟模式 1 的配置就算完成。使能计数器由 TIMx_CR1 的位 CEN 配置。

  当 TIMx_SMCR 寄存器中的 SMS=111(从模式选择) 时,可选择此模式。计数器可在选定的输入信号上出现上升沿或下降沿时计数。

  例如,要使递增计数器在 TI2 输入出现上升沿时计数,请执行以下步骤:
  A. 通过在 TIMx_CCMR1 寄存器中写入 CC2S =“01”来配置通道 2,使其能够检测 TI2输入的上升沿。
  B. 通过在 TIMx_CCMR1 寄存器中写入 IC2F[3:0] 位来配置输入滤波时间(如果不需要任何滤波,请保持 IC2F=0000)。
  C. 通过在 TIMx_CCER 寄存器中写入 CC2P=0 和 CC2NP=0 来选择上升沿极性。
  D. 通过在 TIMx_SMCR 寄存器中写入 SMS=111,使定时器在外部时钟模式 1 下工作。
  E. 通过在 TIMx_SMCR 寄存器中写入 TS=110 来选择 TI2 作为触发输入源。
  F. 通过在 TIMx_CR1 寄存器中写入 CEN=1 来使能计数器。
  注意: 由于捕获预分频器不用于触发操作,因此无需对其进行配置。

  当 TI2 出现上升沿时,计数器便会计数一次并且 TIF 标志置 1。
  TI2 的上升沿与实际计数器时钟之间的延迟是由于 TI2 输入的重新同步电路引起的。

  (3)外部时钟模式 2

  1)时钟信号输入引脚
  当使用外部时钟模式 2 的时候,时钟信号来自于定时器的特定输入通道 TIMx_ETR,只有 1 个。
  2)外部触发极性
  来自 ETR 引脚输入的信号可以选择为上升沿或者下降沿有效,具体的由 TIMx_SMCR 的位 ETP配置。
  3)外部触发预分频器
  由于 ETRP 的信号的频率不能超过 TIMx_CLK(72M)的 1/4,当触发信号的频率很高的情况下,就必须使用分频器来降频,具体的由 TIMx_SMCR 的位 ETPS[1:0] 配置。
  4)滤波器
  如果 ETRP 的信号的频率过高或者混杂有高频干扰信号的话,我们就需要使用滤波器对 ETRP 信号重新采样,来达到降频或者去除高频干扰的目的。具体的由 TIMx_SMCR 的位 ETF[3:0] 配置,其中的 fDTS 是由内部时钟 CK_INT 分频得到,具体的由 TIMx_CR1 的位 CKD[1:0] 配置。
  5)从模式选择
  经过滤波器滤波的信号连接到 ETRF 引脚后,触发信号成为外部时钟模式 2 的输入,最终等于CK_PSC,然后驱动计数器 CNT 计数。具体的配置 TIMx_SMCR 的位 ECE 为 1 即可选择外部时钟模式 2。
  6)使能计数器
  经过上面的 5 个步骤之后,最后我们只需使能计数器开始计数,外部时钟模式 2 的配置就算完成。使能计数器由 TIMx_CR1 的位 CEN 配置。

  通过在 TIMx_SMCR 寄存器中写入 ECE=1 可选择此模式。
  计数器可在外部触发输入 ETR 出现上升沿或下降沿时计数。

  例如,要使递增计数器在 ETR 每出现 2 个上升沿时计数,请执行以下步骤:
  A. 由于此例中不需滤波器,因此在 TIMx_SMCR 寄存器中写入 ETF[3:0]=0000
  B. 通过在 TIMx_SMCR 寄存器中写入 ETPS[1:0]=01 来设置预分频器。
  C. 通过在 TIMx_SMCR 寄存器中写入 ETP=0 来选择 ETR 引脚的上升沿检测。
  D. 通过在 TIMx_SMCR 寄存器中写入 ECE=1 来使能外部时钟模式 2
  E. 通过在 TIMx_CR1 寄存器中写入 CEN=1 来使能计数器。
  ETR 每出现 2 个上升沿,计数器计数一次。
  ETR 的上升沿与实际计数器时钟之间的延迟是由于 ETRP 信号的重新同步电路引起的。

  (4)内部触发输入
  内部触发输入是使用一个定时器作为另一个定时器的预分频器。硬件上高级控制定时器和通用定时器在内部连接在一起,可以实现定时器同步或级联。主模式的定时器可以对从模式定时器执行复位、启动、停止或提供时钟。高级控制定时器和部分通用定时器 (TIM2 至 TIM5) 可以设置为主模式或从模式, TIM9 和 TIM10 可设置为从模式。 图 32_21 为主模式定时器 (TIM1) 为从模式定时器 (TIM2) 提供时钟,即 TIM1 用作 TIM2 的预分频器。

  3.2.2、控制器

  高级控制定时器控制器部分包括触发控制器、从模式控制器以及编码器接口触发控制器用来针对片内外设输出触发信号,比如为其它定时器提供时钟和触发 DAC/ADC 转换编码器接口专门针对编码器计数而设计从模式控制器可以控制计数器复位、启动、递增/递减、计数

  3.2.3 、时基单元

                                          图 31‑4 高级定时器时基单元
  高级控制定时器时基单元功能包括四个寄存器,分别是计数器寄存器 (CNT)、预分频器寄存器(PSC)、自动重载寄存器 (ARR) 和重复计数器寄存器 (RCR)。其中重复计数器 RCR 是高级定时器独有,通用和基本定时器没有。前面三个寄存器都是 16 位有效, TIMx_RCR 寄存器是 8 位有效。

  可编程高级控制定时器的主要模块是一个 16 位计数器及其相关的自动重载寄存器。计数器可递增计数、递减计数或交替进行递增和递减计数。计数器的时钟可通过预分频器进行分频。
  计数器、自动重载寄存器和预分频器寄存器可通过软件进行读写。即使在计数器运行时也可执行读写操作。
  时基单元包括:
  ● 计数器寄存器 (TIMx_CNT):计数
  ● 预分频器寄存器 (TIMx_PSC):分频
  ● 自动重载寄存器 (TIMx_ARR):设定定时器的计数上限
  ● 重复计数器寄存器 (TIMx_RCR):RCR的作用是让定时器必须溢出多次(RCR+1次)后,才真正触发一次更新事件。
  自动重载寄存器是预装载的。对自动重载寄存器执行写入或读取操作时会访问预装载寄存器。预装载寄存器的内容既可以直接传送到影子寄存器,也可以在每次发生更新事件 (UEV)时传送到影子寄存器,这取决于 TIMx_CR1 寄存器中的自动重载预装载使能位 (ARPE)。当计数器达到上溢值(或者在递减计数时达到下溢值)并且 TIMx_CR1 寄存器中的 UDIS 位为0 时,将发送更新事件。该更新事件也可由软件产生。
  计数器由预分频器输出 CK_CNT 提供时钟,仅当 TIMx_CR1 寄存器中的计数器启动位 (CEN)置 1 时,才会启动计数器。
  注意,计数器将在 TIMx_CR1 寄存器的 CEN 位置 1 时刻的一个时钟周期后开始计数。

  (1)预分频器 PSC

  预分频器可对计数器时钟频率进行分频,分频系数介于 1 和 65536 之间。该预分频器基于TIMx_PSC 寄存器中的 16 位寄存器所控制的 16 位计数器。由于该控制寄存器具有缓冲功能,因此可对预分频器进行实时更改。而新的预分频比将在下一更新事件发生时被采用。
  预分频器 PSC,有一个输入时钟 CK_PSC 和一个输出时钟 CK_CNT。输入时钟 CK_PSC 就是上面时钟源的输出,输出 CK_CNT 则用来驱动计数器 CNT 计数。通过设置预分频器 PSC 的值可以得到不同的 CK_CNT,实际计算为: fCK_CNT 等于 fCK_PSC/(PSC[15:0]+1),可以实现 1 至 65536 分频。

  图 72 73 以一些示例说明在预分频比实时变化时计数器的行为:

  (2)计数器 CNT
  高级控制定时器的计数器有三种计数模式,分别为递增计数模式、递减计数模式和递增/递减 (中心对齐) 计数模式。
    1) 递增计数模式下,计数器从 0 开始计数,每来一个 CK_CNT 脉冲计数器就增加 1,直到计数器的值与自动重载寄存器 ARR 值相等,然后计数器又从 0 开始计数并生成计数器上溢事件,计数器总是如此循环计数。如果禁用重复计数器,在计数器生成上溢事件就马上生成更新事件 (UEV);如果使能重复计数器,每生成一次上溢事件重复计数器内容就减 1,直到重复计数器内容为 0 时才会生成更新事件。
    2) 递减计数模式下,计数器从自动重载寄存器 ARR 值开始计数,每来一个 CK_CNT 脉冲计数器就减 1,直到计数器值为 0,然后计数器又从自动重载寄存器 ARR 值开始递减计数并生成计数器下溢事件,计数器总是如此循环计数。如果禁用重复计数器,在计数器生成下溢事件就马上生成更新事件;如果使能重复计数器,每生成一次下溢事件重复计数器内容就减 1,直到重复计数器内容为 0 时才会生成更新事件。
    3) 中心对齐模式下,计数器从 0 开始递增计数,直到计数值等于 (ARR-1) 值生成计数器上溢事件,然后从 ARR 值开始递减计数直到 1 生成计数器下溢事件。然后又从 0 开始计数,如此循环。每次发生计数器上溢和下溢事件都会生成更新事件。

  下面通过一张图给大家展示定时器工作在不同计数模式下,更新事件发生的情况。

  (3)自动重载寄存器 ARR
  自动重载寄存器 ARR 用来存放与计数器 CNT 比较的值,如果两个值相等就递减重复计数器。可以通过 TIMx_CR1 寄存器的 ARPE 位控制自动重载影子寄存器功能,如果 ARPE 位置 1,自动重载影子寄存器有效,只有在事件更新时才把 TIMx_ARR 值赋给影子寄存器。如果 ARPE 位为 0,则修改 TIMx_ARR 值马上有效。
  (4)重复计数器 RCR
  在基本/通用定时器发生上/下溢事件时直接就生成更新事件,但对于高级控制定时器却不是这样,高级控制定时器在硬件结构上多出了重复计数器,在定时器发生上溢或下溢事件是递减重复计数器的值,只有当重复计数器为 0 时才会生成更新事件。在发生 N+1 个上溢或下溢事件 (N 为RCR 的值) 时产生更新事件。这里需要注意的是重复计数器寄存器是具有影子寄存器的,所以 RCR 寄存器只是起缓冲的作用。 RCR 寄存器的值会在更新事件发生时,被转移至其影子寄存器中,从而真正生效。重复计数器的特性,在控制生成 PWM 信号时很有用,后面会有相应的实验。

  第 14.3.1 节:时基单元介绍如何因计数器上溢/下溢而生成更新事件 (UEV)。实际上,只有当重复计数器达到零时,才会生成更新事件。这在生成 PWM 信号时很有用。
  这意味着,每当发生 N+1 个计数器上溢或下溢(其中, N 是 TIMx_RCR 重复计数器寄存器中的值),数据就将从预装载寄存器转移到影子寄存器( TIMx_ARR 自动重载寄存器、TIMx_PSC 预分频器寄存器以及比较模式下的 TIMx_CCRx 捕获/比较寄存器)。
  重复计数器在下列情况下递减:
  ● 递增计数模式下的每个计数器上溢。
  ● 递减计数模式下的每个计数器下溢。
  ● 中心对齐模式下每个计数器上溢和计数器下溢。尽管这使得最大重复次数不超过 128 个
  PWM 周期,但在每个 PWM 周期内可更新占空比两次。当在中心对齐模式下,每个PWM 周期仅刷新一次比较寄存器时,由于模式的对称性,最大分辨率为 2xTck。
  重复计数器是自动重载类型;其重复率为 TIMx_RCR 寄存器所定义的值(请参见图 91)。
  当更新事件由软件(通过将 TIMx_EGR 寄存器的 UG 位置 1)或硬件(通过从模式控制器)生成时,无论重复计数器的值为多少,更新事件都将立即发生,并且在重复计数器中重新装载 TIMx_RCR 寄存器的内容。
  在中心对齐模式下,如果 RCR 值为奇数,更新事件将在上溢或下溢时发生,这取决于何时写入 RCR 寄存器以及何时启动计数器。如果在启动计数器前写入 RCR,则 UEV 在上溢时发生。如果在启动计数器后写入 RCR,则 UEV 在下溢时发生。例如,如果 RCR = 3, UEV将在每个周期的第四个上溢或下溢事件时生成(取决于何时写入 RCR)。

  3.3、捕获/比较通道

  每个捕获/比较通道均围绕一个捕获/比较寄存器(包括一个影子寄存器)、一个捕获输入阶段(数字滤波、多路复用和预分频器)和一个输出阶段(比较器和输出控制)构建而成。
  图 97 到图 100 概括介绍了一个捕获/比较通道。
  输入阶段对相应的 TIx 输入进行采样,生成一个滤波后的信号 TIxF。然后,带有极性选择功能的边沿检测器生成一个信号 (TIxFPx),该信号可用作从模式控制器的触发输入,也可用作捕获命令。该信号先进行预分频 (ICxPS),而后再进入捕获寄存器。

   输出阶段生成一个中间波形作为基准: OCxRef(高电平有效)。链的末端决定最终输出信号的极性。

  捕获/比较模块由一个预装载寄存器和一个影子寄存器组成。始终可通过读写操作访问预装载寄存器。
  在捕获模式下,捕获实际发生在影子寄存器中,然后将影子寄存器的内容复制到预装载寄存器中。
  在比较模式下,预装载寄存器的内容将被复制到影子寄存器中,然后将影子寄存器的内容与计数器进行比较。

  3.3.1、输入捕获

  在输入捕获模式下,当相应的 ICx 信号检测到跳变沿后,将使用捕获/比较寄存器 (TIMx_CCRx)来锁存计数器的值。发生捕获事件时,会将相应的 CCXIF 标志( TIMx_SR 寄存器)置 1,并可发送中断或 DMA 请求(如果已使能)。如果发生捕获事件时 CCxIF 标志已处于高位,则会将重复捕获标志 CCxOF( TIMx_SR 寄存器)置 1。可通过软件向 CCxIF 写入 0 来给CCxIF 清零,或读取存储在 TIMx_CCRx 寄存器中的已捕获数据。向 CCxOF 写入“0”后会将其清零。
  以下示例说明了如何在 TI1 输入出现上升沿时将计数器的值捕获到 TIMx_CCR1 中。具体操作步骤如下:
  ● 选择有效输入: TIMx_CCR1 必须连接到 TI1 输入,因此向 TIMx_CCMR1 寄存器中的 CC1S位写入 01。只要 CC1S 不等于 00,就会将通道配置为输入模式,并且 TIMx_CCR1 寄存器将处于只读状态。
  ● 根据连接到定时器的信号,对所需的输入滤波时间进行编程(如果输入为 TIx 输入,则对 TIMx_CCMRx 寄存器中的 ICxF 位进行编程)。假设信号边沿变化时,输入信号最多在 5 个内部时钟周期内发生抖动。因此,我们必须将滤波时间设置为大于 5 个内部时钟周期。在检测到 8 个具有新电平的连续采样(以 fDTS 频率采样)后,可以确认 TI1上的跳变沿。然后向 TIMx_CCMR1 寄存器中的 IC1F 位写入 0011。
  ● 通过在 TIMx_CCER 寄存器中将 CC1P 位和 CC1NP 位写入 0,选择 TI1 上的有效转换边沿(本例中为上升沿)。
  ● 对输入预分频器进行编程。在本例中,我们希望每次有效转换时都执行捕获操作,因此需要禁止预分频器(向 TIMx_CCMR1 寄存器中的 IC1PS 位写入“00”)。
  ● 通过将 TIMx_CCER 寄存器中的 CC1E 位置 1,允许将计数器的值捕获到捕获寄存器中。
  ● 如果需要,可通过将 TIMx_DIER 寄存器中的 CC1IE 位置 1 来使能相关中断请求,并且/或者通过将该寄存器中的 CC1DE 位置 1 来使能 DMA 请求。发生输入捕获时:
  ● 发生有效跳变沿时, TIMx_CCR1 寄存器会获取计数器的值。
  ● 将 CC1IF 标志置 1(中断标志)。如果至少发生了两次连续捕获,但 CC1IF 标志未被清零,这样 CC1OF 捕获溢出标志会被置 1。
  ● 根据 CC1IE 位生成中断。
  ● 根据 CC1DE 位生成 DMA 请求。
  要处理重复捕获,建议在读出捕获溢出标志之前读取数据。这样可避免丢失在读取捕获溢出标志之后与读取数据之前可能出现的重复捕获信息。
  注意: 通过软件将 TIMx_EGR 寄存器中的相应 CCxG 位置 1 可生成 IC 中断和/或 DMA 请求。

  输入捕获可以对输入的信号的上升沿,下降沿或者双边沿进行捕获,常用的有测量输入信号的脉宽和测量 PWM 输入信号的频率和占空比这两种。
  输入捕获的大概的原理就是,当捕获到信号的跳变沿的时候,把计数器 CNT 的值锁存到捕获寄存器 CCR 中,把前后两次捕获到的 CCR 寄存器中的值相减,就可以算出脉宽或者频率。如果捕获的脉宽的时间长度超过你的捕获定时器的周期,就会发生溢出,这个我们需要做额外的处理。

  (1)输入通道
  需要被测量的信号从定时器的外部引脚 TIMx_CH1/2/3/4 进入,通常叫 TI1/2/3/4,在后面的捕获讲解中对于要被测量的信号我们都以 TIx 为标准叫法。
  (2)输入滤波器和边沿检测器
  当输入的信号存在高频干扰的时候,我们需要对输入信号进行滤波,即进行重新采样,根据采样定律,采样的频率必须大于等于两倍的输入信号。比如输入的信号为 1M,又存在高频的信号干扰,那么此时就很有必要进行滤波,我们可以设置采样频率为 2M,这样可以在保证采样到有效信号的基础上把高于 2M 的高频干扰信号过滤掉。
  滤波器的配置由 CR1 寄存器的位 CKD[1:0] 和 CCMR1/2 的位 ICxF[3:0] 控制。从 ICxF 位的描述可知,采样频率 fSAMPLE 可以由 fCK_INT 和 fDTS 分频后的时钟提供,其中是 fCK_INT 内部时钟, fDTS是 fCK_INT 经过分频后得到的频率,分频因子由 CKD[1:0] 决定,可以是不分频, 2 分频或者是 4分频。
  边沿检测器用来设置信号在捕获的时候是什么边沿有效,可以是上升沿、下降沿,或者是双边沿,具体的由 CCER 寄存器的位 CCxP 和 CCxNP 决定。
  (3)捕获通道
  捕获通道就是图中的 IC1/2/3/4,每个捕获通道都有相对应的捕获寄存器 CCR1/2/3/4,当发生捕获的时候,计数器 CNT 的值就会被锁存到捕获寄存器中。
  这里我们要搞清楚输入通道和捕获通道的区别,输入通道是用来输入信号的,捕获通道是用来捕获输入信号的通道,一个输入通道的信号可以同时输入给两个捕获通道。比如输入通道 TI1 的信号经过滤波边沿检测器之后的 TI1FP1 和 TI1FP2 可以进入到捕获通道 IC1 和 IC2,其实这就是我们后面要讲的 PWM 输入捕获,只有一路输入信号(TI1)却占用了两个捕获通道(IC1 和 IC2)。当只需要测量输入信号的脉宽时候,用一个捕获通道即可。输入通道和捕获通道的映射关系具体由寄存器 CCMRx 的位 CCxS[1:0] 配置。

  (4) 预分频器
  ICx 的输出信号会经过一个预分频器,用于决定发生多少个事件时进行一次捕获。具体的由寄存器 CCMRx 的位 ICxPSC 配置,如果希望捕获信号的每一个边沿,则不分频。
  (5) 捕获寄存器
  经过预分频器的信号 ICxPS 是最终被捕获的信号,当发生捕获时(第一次),计数器 CNT 的值会被锁存到捕获寄存器 CCR 中,还会产生 CCxI 中断,相应的中断位 CCxIF(在 SR 寄存器中)会被置位,通过软件或者读取 CCR 中的值可以将 CCxIF 清 0。如果发生第二次捕获(即重复捕获:CCR 寄存器中已捕获到计数器值且 CCxIF 标志已置 1),则捕获溢出标志位 CCxOF(在 SR 寄存器中)会被置位, CCxOF 只能通过软件清零。

  3.3.2、输出比较

  输出比较就是通过定时器的外部引脚对外输出控制信号,有冻结、将通道 X(x=1,2,3,4)设置为匹配时输出有效电平、将通道 X 设置为匹配时输出无效电平、翻转、强制变为无效电平、强制变为有效电平、 PWM1 和 PWM2 这八种模式,具体使用哪种模式由寄存器 CCMRx 的位 OCxM[2:0]配置。其中 PWM 模式是输出比较中的特例,使用的也最多。
  (1)比较寄存器
  当计数器 CNT 的值跟比较寄存器 CCR 的值相等的时候,输出参考信号 OCxREF 的信号的极性就会改变,其中 OCxREF=1(高电平)称之为有效电平, OCxREF=0(低电平)称之为无效电平,并且会产生比较中断 CCxI,相应的标志位 CCxIF(SR 寄存器中)会置位。然后 OCxREF 再经过一系列的控制之后就成为真正的输出信号 OCx/OCxN。
  (2)死区发生器
  在生成的参考波形 OCxREF 的基础上,可以插入死区时间,用于生成两路互补的输出信号 OCx和 OCxN,死区时间的大小具体由 BDTR 寄存器的位 DTG[7:0] 配置。死区时间的大小必须根据与输出信号相连接的器件及其特性来调整。下面我们简单举例说明下带死区的 PWM 信号的应用,我们以一个板桥驱动电路为例。

                             图 31‑7 半桥驱动电路
  在这个半桥驱动电路中, Q1 导通, Q2 截止,此时我想让 Q1 截止 Q2 导通,肯定是要先让 Q1 截止一段时间之后,再等一段时间才让 Q2 导通,那么这段等待的时间就称为死区时间,因为 Q1关闭需要时间(由 MOS 管的工艺决定)。如果 Q1 关闭之后,马上打开 Q2,那么此时一段时间内相当于 Q1 和 Q2 都导通了,这样电路会短路。
  图 31_8 是针对上面的半桥驱动电路而画的带死区插入的 PWM 信号,图中的死区时间要根据MOS 管的工艺来调节。

                     图 31‑8 带死区插入的互补输出

  用户必须根据与输出相连接的器件及其特性来调整死区时间。
  死区时间计算
  下面来看一下定时器的死区时间是怎么计算并设置的?死区时间是由 TIMx_CR1 寄存器的 CKD[1:0]位和 TIMx_BDTR 寄存器的 DTG[7:0]位来设置,如下图所示:

   死区时间计算分三步走:
  第一步:通过 CKD[1:0]位确定 tDTS。根据 CKD[1:0]位的描述,可以得到下面的式子:

  CKD[1:0]: CKD[1:0]位设置的值。
  Tclk: 定时器的时钟源频率(单位为 MHz)。
  假设定时器时钟源频率是 168MHz,我们设置 CKD[1:0]位的值为 2,代入上面的式子可得:

  通过上式可得 tDTS 约等于 23.81ns,本实验例程中我们也是这样设置的。
  第二步:根据 DTG[7:5]选择计算公式。
  第三步:代入选择的公式计算。
  下面给大家举个例子,假设定时器时钟源频率是 168MHz,我们设置 CKD[1:0]位的值为2, DTG[7:0]位的值为 250。从上面的例子知道 CKD[1:0]位的值为 2,得到的 tDTS=23.81ns。下面来看一下 DTG[7:0]位的值为 250,应该选择 DTG[7:0]位描述中哪条公式? 250 的二进制数为 11111010,即 DTG[7:5]为 111,所以选择第四条公式: DT=(32+ DTG[4:0]) * t dtg, 其中 tdtg = 16 * tDTS。可以看到手册上的式子符号大小写乱乱的,这里大小写不敏感。由手册的公式可以得到 DT = (32+ DTG[4:0]) * 16 * tDTS = (32+ 26) * 16 * 23.81ns = 22095.68ns = 22.01us,即死区时间为 22.01us。死区时间计算方法就给大家介绍到这里。

  (3)、 输出控制

                      图 31‑9 输出比较(通道 1~3)的输出控制框图
  在输出比较的输出控制中,参考信号 OCxREF 在经过死区发生器之后会产生两路带死区的互补信号 OCx_DT 和 OCxN_DT(通道 1~3 才有互补信号,通道 4 没有,其余跟通道 1~3 一样),这两路带死区的互补信号然后就进入输出控制电路,如果没有加入死区控制,那么进入输出控制电路的信号就直接是 OCxREF。
  进入输出控制电路的信号会被分成两路,一路是原始信号,一路是被反向的信号,具体的由寄存器 CCER 的位 CCxP 和 CCxNP 控制。经过极性选择的信号是否由 OCx 引脚输出到外部引脚CHx/CHxN 则由寄存器 CCER 的位 CxE/CxNE 配置。
  如果加入了断路(刹车)功能,则断路和死区寄存器 BDTR 的 MOE、 OSSI 和 OSSR 这三个位会共同影响输出的信号。

  (4)输出引脚
  输出比较的输出信号最终是通过定时器的外部 IO 来输出的,分别为 CH1/2/3/4,其中前面三个通道还有互补的输出通道 CH1/2/3N。更加详细的 IO 说明还请查阅相关的数据手册。

  3.4、高级定时器功能分类与层级关系

  3.4.1、信号输入层

  (1) 测量外部信号边沿时间(脉宽/频率)

                     图 31‑10 脉宽/频率测量示意图

  1) 测量频率(周期)
  当捕获通道 TIx 上出现上升沿时,发生第一次捕获,计数器 CNT 的值会被锁存到捕获寄存器 CCR中,而且还会进入捕获中断,在中断服务程序中记录一次捕获(可以用一个标志变量来记录),并把捕获寄存器中的值读取到 value1 中。当出现第二次上升沿时,发生第二次捕获,计数器 CNT的值会再次被锁存到捕获寄存器 CCR 中,并再次进入捕获中断,在捕获中断中,把捕获寄存器的值读取到 value3 中,并清除捕获记录标志。利用 value3 和 value1 的差值我们就可以算出信号的周期(频率)。
  2)测量脉宽(一个周期内高电平的时间)
  当捕获通道 TIx 上出现上升沿时,发生第一次捕获,计数器 CNT 的值会被锁存到捕获寄存器 CCR中,而且还会进入捕获中断,在中断服务程序中记录一次捕获(可以用一个标志变量来记录),并把捕获寄存器中的值读取到 value1 中。然后把捕获边沿改变为下降沿捕获,目的是捕获后面的下降沿。当下降沿到来的时候,发生第二次捕获,计数器 CNT 的值会再次被锁存到捕获寄存器CCR 中,并再次进入捕获中断,在捕获中断中,把捕获寄存器的值读取到 value3 中,并清除捕获记录标志。然后把捕获边沿设置为上升沿捕获。
  在测量脉宽过程中需要来回的切换捕获边沿的极性,如果测量的脉宽时间比较长,定时器就会发生溢出,溢出的时候会产生更新中断,我们可以在中断里面对溢出进行记录处理。
  (2)PWM 输入模式(捕获PWM信号的周期/占空比)

  测量脉宽和频率还有一个更简便的方法就是使用 PWM 输入模式,该模式是输入捕获的特例。其实现步骤与输入捕获模式基本相同,仅存在以下不同之处:
  ● 两个 ICx 信号被映射至同一个 TIx 输入。
  ● 这两个 ICx 信号在边沿处有效,但极性相反。
  ● 选择两个 TIxFP 信号之一作为触发输入,并将从模式控制器配置为复位模式。例如,可通过以下步骤对应用于 TI1 的 PWM 的周期(位于 TIMx_CCR1 寄存器中)和占空比(位于 TIMx_CCR2 寄存器中)进行测量(取决于 CK_INT 频率和预分频器的值):
  ● 选择 TIMx_CCR1 的有效输入:向 TIMx_CCMR1 寄存器中的 CC1S 位写入 01(选择 TI1)。
  ● 选择 TI1FP1 的有效极性(用于在 TIMx_CCR1 中捕获和计数器清零):向 CC1P 位和CC1NP 位写入“0”(上升沿有效)。
  ● 选择 TIMx_CCR2 的有效输入:向 TIMx_CCMR1 寄存器中的 CC2S 写入 10(选择 TI1)。
  ● 选择 TI1FP2 的有效极性(用于在 TIMx_CCR2 中捕获):向 CC2P 位和 CC2NP 位写入“1”(下降沿有效)。
  ● 选择有效触发输入:向 TIMx_SMCR 寄存器中的 TS 位写入 101(选择 TI1FP1)。
  ● 将从模式控制器配置为复位模式:向 TIMx_SMCR 寄存器中的 SMS 位写入 100。
  ● 使能捕获:向 TIMx_CCER 寄存器中的 CC1E 位和 CC2E 位写入“1”。

  PWM 输入模式只能使用通道 1 和通道 2,通道 3 和通道 4 使用不了。与上面那种只使用一个捕获寄存器测量脉宽和频率的方法相比, PWM 输入模式需要占用两个捕获寄存器。

                          图 31‑11 输入通道和捕获通道的关系映射图
  当使用 PWM 输入模式的时候,因为一个输入通道 (TIx) 会占用两个捕获通道 (ICx),所以一个定时器在使用 PWM 输入的时候最多只能使用两个输入通道 (TIx)。

  我们以输入通道 TI1 工作在 PWM 输入模式为例来讲解下具体的工作原理,其他通道以此类推即可。
  PWM 信号由输入通道 TI1 进入,因为是 PWM 输入模式的缘故,信号会被分为两路,一路是TI1FP1,另外一路是 TI1FP2。其中一路是周期,另一路是占空比,具体哪一路信号对应周期还是占空比,得从程序上设置哪一路信号作为触发输入,作为触发输入的哪一路信号对应的就是周期,另一路就是对应占空比。作为触发输入的那一路信号还需要设置极性,是上升沿还是下降沿捕获,一旦设置好触发输入的极性,另外一路硬件就会自动配置为相反的极性捕获,无需软件配置。一句话概括就是:选定输入通道,确定触发信号,然后设置触发信号的极性即可,因为是PWM 输入的缘故,另一路信号则由硬件配置,无需软件配置。
  当使用 PWM 输入模式的时候必须将从模式控制器配置为复位模式(配置寄存器 SMCR 的位SMS[2:0] 来实现),即当我们启动触发信号开始进行捕获的时候,同时把计数器 CNT 复位清零。
  下面我们以一个更加具体的时序图来分析下 PWM 输入模式。

                图 31‑12 PWM 输入模式时序
  PWM 信号由输入通道 TI1 进入,配置 TI1FP1 为触发信号,上升沿捕获。当上升沿的时候 IC1 和IC2 同时捕获,计数器 CNT 清零,到了下降沿的时候, IC2 捕获,此时计数器 CNT 的值被锁存到捕获寄存器 CCR2 中,到了下一个上升沿的时候, IC1 捕获,计数器 CNT 的值被锁存到捕获寄存器 CCR1 中。其中 CCR2+1 测量的是脉宽, CCR1+1 测量的是周期。这里要注意的是 CCR2 和CCR1 的值在计算占空比和频率的时候都必须加 1,因为计数器是从 0 开始计数的。
  从软件上来说,用 PWM 输入模式测量脉宽和周期更容易,付出的代价是需要占用两个捕获寄存器。

  (3)编码器接口模式(读取正交编码器信号,反馈位置/速度,可触发输出比较或6步PWM换相(闭环控制))
  选择编码器接口模式时,如果计数器仅在 TI2 边沿处计数,在 TIMx_SMCR 寄存器中写入SMS=“001”;如果计数器仅在 TI1 边沿处计数,写入 SMS=“010”;如果计数器在 TI1和 TI2 边沿处均计数,则写入 SMS=“011”。
  通过编程 TIMx_CCER 寄存器的 CC1P 和 CC2P 位,选择 TI1 和 TI2 极性。如果需要,还可对输入滤波器进行编程。 CC1NP 和 CC2NP 必须保持低电平。
  每个定时器只有TI1 和 TI2 两个输入用于连接编码器,TI3 和 TI4不支持编码器功能 。请参见表 71。如果使能计数器(在 TIMx_CR1 寄存器的 CEN 位中写入“1”),则计数器的时钟由 TI1FP1 或 TI2FP2 上的每次有效信号转换提供。 TI1FP1 和 TI2FP2 是进行输入滤波器和极性选择后 TI1 和 TI2 的信号,如果不进行滤波和反相,则 TI1FP1=TI1, TI2FP2=TI2。将根据两个输入的信号转换序列,产生计数脉冲和方向信号。根据该信号转换序列,计数器相应递增或递减计数,同时硬件对 TIMx_CR1寄存器的 DIR 位进行相应修改。任何输入( TI1 或 TI2)发生信号转换时(无论上升沿还是下降沿),都会计算 DIR位,无论计数器是仅在 TI1 或 TI2 边沿处计数,还是同时在 TI1 和 TI2 处计数。

  在STM32的定时器编码器接口模式下,硬件设计上仅支持双边沿检测(即自动四倍频),无法直接配置为仅单边沿触发(如仅上升沿或仅下降沿)。
  编码器接口模式就相当于带有方向选择的外部时钟。这意味着,计数器仅在 0 到 TIMx_ARR寄存器中的自动重载值之间进行连续计数(根据具体方向,从 0 递增计数到 ARR,或从ARR 递减计数到 0)。因此,在启动前必须先配置 TIMx_ARR。同样,捕获、比较、预分频器、重复计数器及触发输出功能继续正常工作。编码器模式和外部时钟模式 2 不兼容,因此不能同时选择。
  在此模式下,计数器会根据增量编码器的速度和方向自动进行修改,因此,其内容始终表示编码器的位置。计数方向对应于所连传感器的旋转方向。下表汇总了可能的组合(假设 TI1和 TI2 不同时切换)。

  外部增量编码器可直接与 MCU 相连,无需外部接口逻辑。不过,通常使用比较器将编码器的差分输出转换为数字信号。这样大幅提高了抗噪声性能。用于指示机械零位的第三个编码器输出可与外部中断输入相连,用以触发计数器复位。
  图 112 以计数器工作为例,说明了计数信号的生成和方向控制。同时也说明了选择双边沿时如何对输入抖动进行补偿。将传感器靠近其中一个切换点放置时可能出现这种情况。本例中假设配置如下:
  ● CC1S=“01”( TIMx_CCMR1 寄存器, TI1FP1 映射到 TI1 上)。
  ● CC2S=“01”( TIMx_CCMR2 寄存器, TI1FP2 映射到 TI2 上)。
  ● CC1P=“0”, CC1NP=“0”,且 IC1F =“0000”(TIMx_CCER 寄存器, TI1FP1 未反相, TI1FP1=TI1)。
  ● CC2P=“0”, CC2NP=“0”,且 IC2F =“0000”(TIMx_CCER 寄存器, TI1FP2 未反相, TI1FP2= TI2)。
  ● SMS=“011”( TIMx_SMCR 寄存器,两个输入在上升沿和下降沿均有效)。
  ● CEN=“1”( TIMx_CR1 寄存器,使能计数器)。

 图 113 举例说明 TI1FP1 极性反相时计数器的行为(除 CC1P=“ 1” 外,其它配置与上例相同)。

 

  定时器配置为编码器接口模式时,会提供传感器当前位置的相关信息。使用另一个配置为捕获模式的定时器测量两个编码器事件之间的周期,可获得动态信息(速度、加速度和减速度)。指示机械零位的编码器输出即可用于此目的。根据两个事件之间的时间间隔,还可定期读取计数器。如果可能,可以将计数器值锁存到第三个输入捕获寄存器来实现此目的(捕获信号必须为周期性信号,可以由另一个定时器产生);还可以通过由实时时钟生成的DMA 请求读取计数器值。

  (4)定时器输入异或功能(对TI1/TI2信号异或滤波,消除噪声)
  通过 TIMx_CR2 寄存器中的 TI1S 位,可将通道 1 的输入滤波器连接到异或门的输出,从而将 TIMx_CH1 到 TIMx_CH3 这三个输入引脚组合在一起。
  异或输出可与触发或输入捕获等所有定时器输入功能配合使用。下面的以连接霍尔传感器为例介绍了此功能。
  (5)连接霍尔传感器(读取霍尔信号,确定转子位置,触发6步PWM换相)
  可通过用于生成电机驱动 PWM 信号的高级控制定时器( TIM1 或 TIM8)以及图 114 中称为“接口定时器”的另一个定时器 TIMx( TIM2、 TIM3、 TIM4 或 TIM5) ,实现与霍尔传感器的连接。 3 个定时器输入引脚( TIMx_CH1、 TIMx_CH2 和 TIMx_CH3)通过异或门连接到TI1 输入通道(通过将 TIMx_CR2 寄存器中的 TI1S 位置 1 来选择),并由“接口定时器”进行捕获。
  从模式控制器配置为复位模式;从输入为 TI1F_ED。这样,每当 3 个输入中有一个输入发生切换时,计数器会从 0 开始重新计数。这样将产生由霍尔输入的任何变化而触发的时基。
  在“接口定时器”上,捕获/比较通道 1 配置为捕获模式,捕获信号为 TRC(请参见第 344页的图 97:捕获/比较通道(例如:通道 1 输入阶段) )。捕获值对应于输入上两次变化的间隔时间,可提供与电机转速相关的信息。
  “接口定时器”可用于在输出模式下产生脉冲,以通过触发 COM 事件更改高级控制定时器( TIM1 或 TIM8)各个通道的配置。 TIM1 定时器用于生成电机驱动 PWM 信号。为此,必须对接口定时器通道进行编程,以便在编程的延迟过后产生正脉冲(在输出比较或 PWM 模式中)。该脉冲通过 TRGO 输出发送到高级控制定时器( TIM1 或 TIM8)。
  示例:霍尔输入与一个 TIMx 定时器相连接,每当霍尔输入发生更改,需要在所编程的延迟过后更改高级控制定时器 TIM1 的 PWM 配置。
  ● 向 TIMx_CR2 寄存器的 TI1S 位写入“1”,使 3 个定时器输入经过异或运算后进入 TI1输入通道。
  ● 时基编程:向 TIMx_ARR 写入其最大值(计数器必须通过 TI1 的变化清零)。设置预分频器,以得到最大计数器周期,该周期长于传感器上两次变化的间隔时间。
  ● 将通道 1 编程为捕获模式(选择 TRC):向 TIMx_CCMR1 寄存器的 CC1S 位写入“11”。如果需要,还可以编程数字滤波器。
  ● 将通道 2 编程为 PWM 2 模式,并具有所需延迟:向 TIMx_CCMR1 寄存器的 OC2M 位写入“111”, CC2S 位写入“00”。
  ● 选择 OC2REF 作为 TRGO 上的触发输出:向 TIMx_CR2 寄存器的 MMS 位写入“101”。
  在高级控制定时器 TIM1 中,必须选择正确的 ITR 输入作为触发输入,定时器编程为可产生PWM 信号,捕获/比较控制信号进行预装载( TIMx_CR2 寄存器的 CCPC=1),并且 COM事件由触发输入控制( TIMx_CR2 寄存器中 CCUS=1)。发生 COM 事件后,在 PWM 控制位( CCxE、 OCxM)中写入下一步的配置,此操作可在由 OC2REF 上升沿产生的中断子程序中完成。
  图 114 为本示例的示意图,从图中可以看出当霍尔信号发生跳变时,会触发一次捕获事件,将CNT计数器的值存储到捕获寄存器CCR1中,同时触发定时器霍尔信号中断,然后CNT计数器复位清零又从0开始累加计数,计数到与CCR2寄存器的值相同时,会触发TRGO信号,然后生成COM事件。

  3.4.2、信号输出层

  3.4.2.1、信号输出层的功能

 

  (1)输出比较模式(生成基础PWM/脉冲信号(如OCxREF))

  输出比较模式总共有 8 种,具体的由寄存器 CCMRx 的位 OCxM[2:0] 配置。

 

    1)前4种模式

  当捕获/比较寄存器与计数器之间相匹配时,输出比较功能:
  ● 将为相应的输出引脚分配一个可编程值,该值由输出比较模式( TIMx_CCMRx 寄存器中的 OCxM 位)和输出极性( TIMx_CCER 寄存器中的 CCxP 位)定义。匹配时,输出引脚既可保持其电平 (OCXM=000),也可设置为有效电平 (OCXM=001)、无效电平(OCXM=010) 或进行翻转 (OCxM=011)。
  ● 将中断状态寄存器中的标志置 1( TIMx_SR 寄存器中的 CCxIF 位)。
  ● 如果相应中断使能位( TIMx_DIER 寄存器中的 CCXIE 位)置 1,将生成中断。
  ● 如果相应 DMA 使能位( TIMx_DIER 寄存器的 CCxDE 位, TIMx_CR2 寄存器的 CCDS位,用来选择 DMA 请求)置 1,将发送 DMA 请求。
  使用 TIMx_CCMRx 寄存器中的 OCxPE 位,可将 TIMx_CCRx 寄存器配置为带或不带预装载寄存器。
  在输出比较模式下,更新事件 UEV 对 OCxREF 和 OCx 输出毫无影响。同步的精度可以达到计数器的一个计数周期。输出比较模式也可用于输出单脉冲(在单脉冲模式下)。
  步骤:
  A. 选择计数器时钟(内部、外部、预分频器)。
  B. 在 TIMx_ARR 和 TIMx_CCRx 寄存器中写入所需数据。
  C 如果要生成中断请求,则需将 CCxIE 位置 1。
  D 选择输出模式。例如:
  — 当 CNT 与 CCRx 匹配时,写入 OCxM = 011 以翻转 OCx 输出引脚
  — 写入 OCxPE = 0 以禁止预装载寄存器
  — 写入 CCxP = 0 以选择高电平有效极性
  — 写入 CCxE = 1 以使能输出
  E. 通过将 TIMx_CR1 寄存器中的 CEN 位置 1 来使能计数器。
  可通过软件随时更新 TIMx_CCRx 寄存器以控制输出波形,前提是未使能预加载寄存器(OCxPE=“0”,否则仅当发生下一个更新事件 UEV 时,才会更新 TIMx_CCRx 影子寄存器)。 图 102 给出了一个示例。

    2)强置输出模式(100强制变为无效电平,101强制变为有效电平

  强置输出这种模式允许用户直接控制输出引脚的电平状态,即强制将输出引脚设置为高电平或低电平,而不依赖于定时器的计数和比较功能。

  在输出模式( TIMx_CCMRx 寄存器中的 CCxS 位 = 00,即CCx 通道配置为输出)下,可直接由软件将每个输出比较信号( OCxREF 和 OCx/OCxN)强制设置为有效电平或无效电平,而无需考虑输出比较寄存器和计数器之间的任何比较结果。
  要将输出比较信号 (OCXREF/OCx) 强制设置为有效电平,只需向相应 TIMx_CCMRx 寄存器中的 OCxM 位(输出比较 1 模式 )写入 101。 OCXREF 进而强制设置为高电平( OCxREF 始终为高电平有效),同时 OCx 获取 CCxP 极性位的相反值。
  例如: CCxP=0( OCx 高电平有效) => OCx 强制设置为高电平。
  通过向 TIMx_CCMRx 寄存器中的 OCxM 位(输出比较 x模式 )写入 100,可将 OCxREF 信号强制设置为低电平。无论如何, TIMx_CCRx 影子寄存器与计数器之间的比较仍会执行,而且允许将标志置 1。因此可发送相应的中断和 DMA 请求。下面的输出比较模式一节对此进行了介绍。

    3) PWM 输出模式

  脉冲宽度调制模式可以生成一个信号,该信号频率由 TIMx_ARR 寄存器值决定,其占空比则由 TIMx_CCRx 寄存器值决定。
  通过向 TIMx_CCMRx 寄存器中的 OCxM 位写入 110 ( PWM 模式 1)或 111 ( PWM 模式2),可以独立选择各通道 (每个 OCx 输出对应一个 PWM)的 PWM 模式。必须通过将TIMx_CCMRx 寄存器中的 OCxPE 位置 1 使能相应预装载寄存器,最后通过将 TIMx_CR1寄存器中的 ARPE 位置 1 使能自动重载预装载寄存器(在递增计数或中心对齐模式下)。

  由于只有在发生更新事件时预装载寄存器才会传送到影子寄存器,因此启动计数器之前,必须通过将 TIMx_EGR 寄存器中的 UG 位置 1 来初始化所有寄存器。
  OCx 极性可使用 TIMx_CCER 寄存器的 CCxP 位来编程。既可以设为高电平有效,也可以设为低电平有效。通过 CCxE、 CCxNE、 MOE、 OSSI 和 OSSR 位( TIMx_CCER 和TIMx_BDTR 寄存器)的组合使能 OCx 输出。有关详细信息,请参见 TIMx_CCER 寄存器说明。
  在 PWM 模式( 1 或 2)下, TIMx_CNT 总是与 TIMx_CCRx 进行比较,以确定是TIMx_CCRx TIMx_CNT 还是 TIMx_CNTTIMx_CCRx(取决于计数器计数方向)。
  根据 TIMx_CR1 寄存器中的 CMS 位状态,定时器能够产生边沿对齐模式或中心对齐模式的PWM 信号。

  PWM 输出就是对外输出脉宽(即占空比)可调的方波信号,信号频率由自动重装寄存器 ARR 的值决定,占空比由比较寄存器 CCR 的值决定。
  PWM 模式分为两种, PWM1 和 PWM2,总得来说是差不多,就看你怎么用而已,具体的区别见表格 31‑1。

                        表格 31‑1 PWM1 与 PWM2 模式的区别

  下面我们以 PWM1 模式来讲解,以计数器 CNT 计数的方向不同还分为边沿对齐模式和中心对齐模式。 PWM 信号主要都是用来控制电机,一般的电机控制用的都是边沿对齐模式, FOC 电机一般用中心对齐模式。我们这里只分析这两种模式在信号感官上(即信号波形)的区别,具体在电机控制中的区别不做讨论,到了你真正需要使用的时候就会知道了。
  ①PWM 边沿对齐模式
  在递增计数模式下,计数器从 0 计数到自动重载值(TIMx_ARR 寄存器的内容),然后重新从 0 开始计数并生成计数器上溢事件

                   图 31‑13 PWM1 模式的边沿对齐波形


  在边沿对齐模式下,计数器 CNT 只工作在一种模式,递增或者递减模式。这里我们以 CNT 工作在递增模式为例,在中, ARR=8, CCR=4, CNT 从 0 开始计数,当 CNT<CCR 的值时, OCxREF为有效的高电平,于此同时,比较中断寄存器 CCxIF 置位。当 CCR=<CNT<=ARR 时, OCxREF为无效的低电平。然后 CNT 又从 0 开始计数并生成计数器上溢事件,以此循环往复。
  ②PWM 中心对齐模式

                          图 31‑14 PWM1 模式的中心对齐波形
  在中心对齐模式下,计数器 CNT 是工作做递增/递减模式下。开始的时候,计数器 CNT 从 0 开始计数到自动重载值减 1(ARR-1),生成计数器上溢事件;然后从自动重载值开始向下计数到 1 并生成计数器下溢事件。之后从 0 开始重新计数。
  图 31_14 是 PWM1 模式的中心对齐波形, ARR=8, CCR=4。第一阶段计数器 CNT 工作在递增模式下,从 0 开始计数,当 CNT<CCR 的值时, OCxREF 为有效的高电平,当 CCR=<CNT«ARR 时,OCxREF 为无效的低电平。第二阶段计数器 CNT 工作在递减模式,从 ARR 的值开始递减,当CNT>CCR 时, OCxREF 为无效的低电平,当 CCR=>CNT>=1 时, OCxREF 为有效的高电平。
  在波形图上我们把波形分为两个阶段,第一个阶段是计数器 CNT 工作在递增模式的波形,这个阶段我们又分为 ① 和 ② 两个阶段,第二个阶段是计数器 CNT 工作在递减模式的波形,这个阶段我们又分为 ③ 和 ④ 两个阶段。要说中心对齐模式下的波形有什么特征的话,那就是 ① 和 ③ 阶段的时间相等, ② 和 ④ 阶段的时间相等。
  中心对齐模式又分为中心对齐模式 1/2/3 三种,具体由寄存器 CR1 位 CMS[1:0] 配置。具体的区别就是比较中断中断标志位 CCxIF 在何时置 1:中心模式 1 在 CNT 递减计数的时候置 1,中心对齐模式 2 在 CNT 递增计数时置 1,中心模式 3 在 CNT 递增和递减计数时都置 1。

  (2) 互补输出和死区插入(生成互补PWM(如CHx/CHxN),插入死区时间保护功率器件)

  高级控制定时器( TIM1 和 TIM8)可以输出两路互补信号,并管理输出的关断与接通瞬间。这段时间通常称为死区,用户必须根据与输出相连接的器件及其特性(电平转换器的固有延迟、开关器件产生的延迟...)来调整死区时间.
  每路输出可以独立选择输出极性(主输出 OCx 或互补输出 OCxN)。可通过对 TIMx_CCER寄存器中的 CCxP 和 CCxNP 位执行写操作来完成极性选择。
  互补信号 OCx 和 OCxN 通过以下多个控制位的组合进行激活: TIMx_CCER 寄存器中的 CCxE和 CCxNE 位以及 TIMx_BDTR 和 TIMx_CR2 寄存器中的 MOE、 OISx、 OISxN、 OSSI 和OSSR 位。更多详细信息,请参见第 382 页的表 73:具有断路功能的互补通道 OCx 和 OCxN的输出控制位。应当注意,切换至 IDLE(MOE 下降到 0)的时刻,死区仍然有效。
  CCxE 和 CCxNE 位同时置 1 并且 MOE 位置 1(如果存在断路)时,将使能死区插入。TIMx_BDTR 寄存器中的 DTG[7:0] 位用于控制所有通道的死区生成。将基于参考波形OCxREF 生成 2 个输出 OCx 和 OCxN。如果 OCx 和 OCxN 为高电平有效:
  ● 输出信号 OCx 与参考信号相同,只是其上升沿相对参考上升沿存在延迟。
  ● 输出信号 OCxN 与参考信号相反,并且其上升沿相对参考下降沿存在延迟。
  如果延迟时间大于有效输出( OCx 或 OCxN)的宽度,则不会产生相应的脉冲。
  下图所示为死区发生器的输出信号与参考信号 OCxREF 之间的关系(在这些示例中,假定 CCxP=0、 CCxNP=0、 MOE=1、 CCxE=1 并且 CCxNE=1),假设已经配置好各个寄存器, 显示出死区发生器的输出信号和当前参考信号 OCxREF 之间的关系。 OCx 输出信号与参考信号相同,知识它的上升沿相对于参考信号的上升沿有一个延迟; OCxN 输出信号与参考信号相反,知识它的上升沿相对于参考信号的下降沿有一个延迟每一个通道都有一个 10 位的死区发生器, 每一个通道额死区延时都是相同的,是由 TIMx_BDTR 寄存器中的 DTG 位编程配置。

  死区延迟对于所有通道均相同,可通过 TIMx_BDTR 寄存器中的 DTG 位进行编程。有关延迟时间计算的信息,请参见第 386 页的第 14.4.18 节: TIM1 和 TIM8 断路和死区寄存器(TIMx_BDTR)。
  将 OCxREF 重定向到 OCx 或 OCxN
  在输出模式(强制输出模式、输出比较模式或 PWM 模式)下,通过配置 TIMx_CCER 寄存器中的 CCxE 和 CCxNE 位,可将 OCxREF 重定向到 OCx 输出或 OCxN 输出。
  通过此功能,可以在一个输出上发送特定波形(如 PWM 或静态有效电平),而同时使互补输出保持其无效电平。或者,使两个输出同时保持无效电平,或者两个输出同时处于有效电平,两者互补并且带死区。
  注意: 如果仅使能 OCxN (CCxE=0, CCxNE=1),两者不互补,一旦 OCxREF 为高电平, OCxN 即变为有效。例如,如果 CCxNP=0,则 OCxN=OCxRef。另一方面,如果同时使能 OCx 和OCxN (CCxE=CCxNE=1), OCx 在 OCxREF 为高电平时变为有效,而 OCxN 则与之互补,在 OCxREF 为低电平时变为有效。

  3.4.2.2、信号输出层的应用

  (1)生成 6 步 PWM(生成驱动三相无刷电机的6步换相PWM序列,结合输出比较、互补输出、死区插入和霍尔传感器接口实现)

  当通道使用互补输出时, OCxM、 CCxE 和 CCxNE 位上提供预装载位。发生 COM 换向事件时,这些预装载位将传输到影子位。因此,用户可以预先编程下一步骤的配置,并同时更改所有通道的配置。 COM 可由软件通过将 TIMx_EGR 寄存器中的 COM 位置 1 而生成,也可以由硬件在 TRGI 上升沿生成。
  发生 COM 事件时,某个标志位(TIMx_SR 寄存器中的 COMIF 位)将会置 1。这时,如果TIMx_DIER 寄存器中的 COMIE 位置 1,将产生中断;如果 TIMx_DIER 寄存器中的 COMDE位置 1,则将产生 DMA 请求。

  110 3 种不同的编程配置为例,显示了发生 COM 事件时 OCx OCxN 输出的行为。

  (2)单脉冲模式(输出单个可控宽度的脉冲,基于输出比较模式的特殊应用)

  单脉冲模式 (OPM) 是上述模式的一个特例。在这种模式下,计数器可以在一个激励信号的触发下启动,并可在一段可编程的延时后产生一个脉宽可编程的脉冲。
  可以通过从模式控制器启动计数器。可以在输出比较模式或 PWM 模式下生成波形。将TIMx_CR1 寄存器中的 OPM 位置 1,即可选择单脉冲模式。这样,发生下一更新事件 UEV时,计数器将自动停止。
  只有当比较值与计数器初始值不同时,才能正确产生一个脉冲。启动前(定时器等待触发时),必须进行如下配置:
  ● 递增计数模式下: CNT < CCRx ARR(特别注意, 0 < CCRx)
  ● 递减计数模式下: CNT > CCRx

  例如,用户希望达到这样的效果:在 TI2 输入引脚检测到正沿时,经过 tDELAY 的延迟,在OC1 上产生一个长度为 tPULSE 的正脉冲。
  使用 TI2FP2 作为触发 1:
  ● 在 TIMx_CCMR1 寄存器中写入 CC2S=“01”,以将 TI2FP2 映射到 TI2。
  ● 在 TIMx_CCER 寄存器中写入 CC2P=“0”和 CC2NP=“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 和TIMx_CR1 寄存器的 ARPE 中写入“1”,以使能预装载寄存器。这种情况下,必须在TIMx_CCR1 寄存器中写入比较值并在 TIMx_ARR 寄存器中写入自动重载值,通过将 UG位置 1 来产生更新,然后等待 TI2 上的外部触发事件。本例中, CC1P 的值为“0”。
在本例中, TIMx_CR1 寄存器中的 DIR 和 CMS 位应为低。
  由于仅需要 1 个脉冲(单脉冲模式),因此应向 TIMx_CR1 寄存器的 OPM 位写入“1”,以便在发生下一更新事件(计数器从自动重载值返回到 0)时使计数器停止计数。 TIMx_CR1寄存器中的 OPM 位置“0”时,即选择重复模式。
  特例: OCx 快速使能:
  在单脉冲模式下, TIx 输入的边沿检测会将 CEN 位置 1,表示使能计数器。然后,在计数器值与比较值之间发生比较时,将切换输出。但是,完成这些操作需要多个时钟周期,这会限制可能的最小延迟( tDELAY 最小值)。

  如果要输出延迟时间最短的波形,可以将 TIMx_CCMRx 寄存器中的 OCxFE 位置 1。这样会强制 OCxRef(和 OCx)对激励信号做出响应,而不再考虑比较的结果。其新电平与发生比较匹配时相同。仅当通道配置为 PWM1 或 PWM2 模式时, OCxFE 才会起作用。
  3.4.3、控制与保护层

  (1)强置输出模式(100强制变为无效电平,101强制变为有效电平)

  强置输出这种模式允许用户直接控制输出引脚的电平状态,即强制将输出引脚设置为高电平或低电平,而不依赖于定时器的计数和比较功能。

  在输出模式( TIMx_CCMRx 寄存器中的 CCxS 位 = 00,即CCx 通道配置为输出)下,可直接由软件将每个输出比较信号( OCxREF 和 OCx/OCxN)强制设置为有效电平或无效电平,而无需考虑输出比较寄存器和计数器之间的任何比较结果。
  要将输出比较信号 (OCXREF/OCx) 强制设置为有效电平,只需向相应 TIMx_CCMRx 寄存器中的 OCxM 位(输出比较 模式 )写入 101。 OCXREF 进而强制设置为高电平( OCxREF 始终为高电平有效),同时 OCx 获取 CCxP 极性位的相反值。
  例如: CCxP=0( OCx 高电平有效) => OCx 强制设置为高电平。
  通过向 TIMx_CCMRx 寄存器中的 OCxM 位(输出比较 x模式 )写入 100,可将 OCxREF 信号强制设置为低电平。无论如何, TIMx_CCRx 影子寄存器与计数器之间的比较仍会执行,而且允许将标志置 1。因此可发送相应的中断和 DMA 请求。

  (2)使用断路功能(紧急关闭PWM输出(如硬件故障时强制拉低))

  断路功能就是电机控制的刹车功能,使能断路功能时,根据相关控制位状态修改输出信号电平。在任何情况下, OCx 和 OCxN 输出都不能同时为有效电平,这关系到电机控制常用的 H 桥电路结构原因。

   F4 系列有一个断路通道,断路源可以是刹车输入引脚(TIMx_BKIN),也可以是一个时钟失败事件。时钟失败事件由复位时钟控制器中的时钟安全系统产生。系统复位后,断路功能默认被禁止, MOE 位为低。
  断路源可以是时钟故障事件,由内部复位时钟控制器中的时钟安全系统 (CSS) 生成,也可以是外部断路输入 IO,两者是或运算关系。
  系统复位启动都默认关闭断路功能,将断路和死区寄存器 (TIMx_BDTR) 的 BKE 为置 1,使能断路功能。可通过 TIMx_BDTR 寄存器的 BKP 位设置设置断路输入引脚的有效电平,设置为 1 时输入 BRK 为高电平有效,否则低电平有效。

  使能断路功能的方法:将 TIMx_BDTR 的位 BKE 置 1。断路输入引脚 TIMx_BKIN 的输入有效电平可通过 TIMx_BDTR 寄存器的位 BKP 设置。
  使能刹车功能后:由 TIMx_BDTR 的 MOE、 OSSI、 OSSR 位, TIMx_CR2 的 OISx、 OISxN位, TIMx_CCER 的 CCxE、 CCxNE 位控制 OCx 和 OCxN 输出状态。无论何时, OCx 和 OCxN输出都不能同时处在有效电平。
  发送断路时,将产生以下效果:
    TIMx_BDTR 寄存器中主输出模式使能 (MOE) 位被清零,OCx 和 OCxN 输出处于无效、空闲或复位状态(由 OSSI 位选择);
     OCx 和 OCxN 的状态:根据相关控制位状态控制输出通道引脚电平;当使能通道互补输出时,会根据情况自动控制输出通道电平;
    将 TIMx_SR 寄存器中的 BIF 位置 1,如果使能了 BIE 位,还会产生刹车中断;如果使能了 TDE 位,会产生DMA 请求。
    如果 TIMx_BDTR 寄存器中的自动输出使能 (AOE) 位置 1,则 MOE 位会在发生下一个 UEV事件时自动再次置 1。

  使用断路功能时,根据其它控制位( TIMx_BDTR 寄存器中的 MOE、 OSSI 和 OSSR 位以及TIMx_CR2 寄存器中的 OISx 和 OISxN 位)修改输出使能信号和无效电平。任何情况下,OCx 和 OCxN 输出都不能同时置为有效电平。更多详细信息,请参见第 382 页的表 73:具有断路功能的互补通道 OCx 和 OCxN 的输出控制位。
  断路源可以是断路输入引脚,也可以是时钟故障事件,后者由复位时钟控制器中的时钟安全系统 (CSS) 生成。有关时钟安全系统的详细信息,请参见第 6.2.7 节:时钟安全系统 (CSS)。
  退出复位状态后,断路功能处于禁止状态, MOE 位处于低电平。将 TIMx_BDTR 寄存器中的 BKE 位置 1,可使能断路功能。断路输入的极性可通过该寄存器中的 BKP 位来选择。 BKE 和 BKP 位可同时修改。对 BKE 和 BKP 位执行写操作时,写操作会在 1 个 APB时钟周期的延迟后生效。因此,执行写操作后,需要等待 1 个 APB 时钟周期,才能准确回读该位。
  由于 MOE 下降沿可能是异步信号,因此在实际信号(作用于输出)与同步控制位(位于TIMx_BDTR 寄存器中)之间插入了再同步电路,从而在异步信号与同步信号之间产生延迟。具体而言,如果在 MOE 处于低电平时向其写入 1,则必须首先插入延迟(空指令),才能准确进行读取。这是因为写入的是异步信号,而读取的却是同步信号。
  发生断路(断路输入上出现所选电平)时:
  ● MOE 位异步清零,使输出处于无效状态、空闲状态或复位状态(通过 OSSI 位进行选择)。即使 MCU 振荡器关闭,该功能仍然有效。
  ● MOE=0 时,将以 TIMx_CR2 寄存器 OISx 位中编程的电平驱动每个输出通道。如果OSSI=0,则定时器将释放使能输出,否则使能输出始终保持高电平。
  ● 使用互补输出时:
  — 输出首先置于复位状态或无效状态(取决于极性)。这是异步操作,因此即使没有为定时器提供时钟,该操作仍有效。
  — 如果定时器时钟仍存在,则将重新激活死区发生器,进而在死区后以 OISx 和 OISxN位中编程的电平驱动输出。即使在这种情况下,也不能同时将 OCx 和 OCxN 驱动至其有效电平。请注意, MOE 进行再同步,因此死区的持续时间会比通常情况长一些(约 2 个 ck_tim 时钟周期)。
  — 如果 OSSI=0,则定时器会释放使能输出,否则只要 CCxE 位或 CCxNE 位处于高电平,使能输出就会保持或变为高电平。
  ● 将断路状态标志(TIMx_SR 寄存器中的 BIF 位)置 1。如果 TIMx_DIER 寄存器中的 BIE位置 1,可产生中断。如果 TIMx_DIER 寄存器中的 BDE 位置 1,可发送 DMA 请求。
  ● 如果 TIMx_BDTR 寄存器中的 AOE 位置 1,则 MOE 位会在发生下一更新事件 (UEV)时自动再次置 1。这一特性有许多用处,比如,可用于实现调节器的功能。否则, MOE将始终保持低电平,直到再次向该位写入“1”。这种情况下,这一特性可用于确保安全。可以将断路输入连接到功率驱动器的警报、温度传感器或任何安全元件。
  注意: 断路输入为电平有效。因此,当断路输入有效电平时,不能将 MOE 位置 1(自动或通过软件)。同时,不能将状态标志 BIF 清零。
  断路可由 BRK 输入生成,该输入具有可编程极性,其使能位 BKE 位于 TIMx_BDTR 寄存器中。
  断路有以下两种生成方案:
  ● 使用 BRK 输入生成,该输入具有可编程极性,其使能位 BKE 位于 TIMx_BDTR 寄存器中。
  ● 由软件通过 TIMx_EGR 寄存器中的 BG 位生成。
  除断路输入和输出管理外,断路电路内部还实施了写保护,用以保护应用的安全。通过该功能,用户可冻结多个参数配置(死区持续时间、 OCx/OCxN 极性和禁止时的状态、 OCxM 配置、断路使能和极性)。可以通过 TIMx_BDTR 寄存器中的 LOCK 位,从 3 种保护级别中进行选择。请参见第 386 页的第 14.4.18 节: TIM1 和 TIM8 断路和死区寄存器 (TIMx_BDTR)。MCU 复位后只能对 LOCK 位执行一次写操作。

  图 108 所示为输出对断路响应行为的示例。

  (3)发生外部事件时清除 OCxREF 信号(通过外部信号(如EXTI)立即清除OCxREF,快速关断PWM)
  可通过给 ETRF 输入加高电平将一个给定通道的 OCxREF 信号拉低(相应的TIMx_CCMRx 寄存器中的 OcxCE 使能位被置为 1)。 OCxREF 信号将一直为低直到下一个更新事件 UEV 发生。此项功能只可在输出比较和 PWM 模式下使用, 在强置模式下不起作用。
  如图 3-14,定时器 TIMx 被置于 PWM 模式, 当 ETRF 输入变为高时,对应不同 OCxCE 的值, OCxREF 信号的动作。

  对于给定通道,在 ETRF 输入施加高电平(相应 TIMx_CCMRx 寄存器中的 OCxCE 使能位置“1”),可使 OCxREF 信号变为低电平。 OCxREF 信号将保持低电平,直到发生下一更新事件 (UEV)。
  此功能仅能用于输出比较模式和 PWM 模式,而不适用于强制输出模式。
  例如, ETR 信号可以连接到比较器的输出,用于控制电流。此时, ETR 必须如下配置:
  A. 必须关闭外部触发预分频器: TIMx_SMCR 寄存器中的 ETPS[1:0] 位置“00”。
  B. 必须禁止外部时钟模式 2: TIMx_SMCR 寄存器中的 ECE 位置“0”。
  C. 外部触发极性 (ETP) 和外部触发滤波器 (ETF) 可根据用户需要进行配置。
  图 109 对比了使能位 OCxCE 在不同值下的情况,显示了当 ETRF 输入变为高电平时 OCxREF信号的行为。在本例中,定时器 TIMx 编程为 PWM 模式。

  (4)TIMx 与外部触发同步
  TIMx 定时器可与外部触发以下列模式实现同步:复位模式、门控模式和触发模式。
  从模式:复位模式
  当触发输入信号产生变化时,计数器及其预分频器可重新初始化。此外,如果 TIMx_CR1 寄存器中的 URS 位处于低电平,则会生成更新事件 UEV。然后,所有预装载寄存器( TIMx_ARR 和 TIMx_CCRx)都将更新。
  在以下示例中, TI1 输入上出现上升沿时,递增计数器清零:
  ● 将通道 1 配置为检测 TI1 的上升沿。配置输入滤波时间(本例中不需要任何滤波,因此保持 IC1F=0000)。由于捕获预分频器不用于触发操作,因此无需对其进行配置。 CC1S 位只选择输入捕获源,即 TIMx_CCMR1 寄存器中的 CC1S = 01。在 TIMx_CCER 寄存器中写入 CC1P=0 和 CC1NP=’0’ ,验证极性(仅检测上升沿)。
  ● 在 TIMx_SMCR 寄存器中写入 SMS=100,将定时器配置为复位模式。在 TIMx_SMCR寄存器中写入 TS=101,选择 TI1 作为输入源。
  ● 在 TIMx_CR1 寄存器中写入 CEN=1,启动计数器。
  计数器使用内部时钟计数,然后正常运转,直到出现 TI1 上升沿。当 TI1 出现上升沿时,计数器清零,然后重新从 0 开始计数。同时,触发标志( TIMx_SR 寄存器中的 TIF 位)置 1,使能中断或 DMA 后,还可发送中断或 DMA 请求(取决于 TIMx_DIER 寄存器中的 TIE 和TDE 位)。
  下图显示了自动重载寄存器 TIMx_ARR=0x36 时的相关行为。 TI1 的上升沿与实际计数器复位之间的延迟是由于 TI1 输入的重新同步电路引起的。

  从模式:门控模式
  输入信号的电平可用来使能计数器。
  在以下示例中,递增计数器仅在 TI1 输入为低电平时计数:
  ● 将通道 1 配置为检测 TI1 上的低电平。配置输入滤波时间(本例中不需要任何滤波,因此保持 IC1F=0000)。由于捕获预分频器不用于触发操作,因此无需对其进行配置。CC1S 位只选择输入捕获源,即 TIMx_CCMR1 寄存器中的 CC1S=01。在 TIMx_CCER寄存器中写入 CC1P=1 和 CC1NP=“0”,以确定极性(仅检测低电平)。
  ● 在 TIMx_SMCR 寄存器中写入 SMS=101,将定时器配置为门控模式。在 TIMx_SMCR寄存器中写入 TS=101,选择 TI1 作为输入源。
  ● 在 TIMx_CR1 寄存器中写入 CEN=1,使能计数器(在门控模式下,如果 CEN=0,则无论触发输入电平如何,计数器都不启动)。
  只要 TI1 为低电平,计数器就开始根据内部时钟计数,直到 TI1 变为高电平时停止计数。计数器启动或停止时, TIMx_SR 寄存器中的 TIF 标志都会置 1。
  TI1 的上升沿与实际计数器停止之间的延迟是由于 TI1 输入的重新同步电路引起的。

  从模式:触发模式
  所选输入上发生某一事件时可以启动计数器。
  在以下示例中, TI2 输入上出现上升沿时,递增计数器启动:
  ● 将通道 2 配置为检测 TI2 上的上升沿。配置输入滤波时间(本例中不需要任何滤波,因此保持 IC2F=0000)。由于捕获预分频器不用于触发操作,因此无需对其进行配置。CC2S 位只选择输入捕获源,即 TIMx_CCMR1 寄存器中的 CC2S=01。在 TIMx_CCER寄存器中写入 CC2P=1 和 CC2NP=0,以确定极性(仅检测低电平)。
  ● 在 TIMx_SMCR 寄存器中写入 SMS=110,将定时器配置为触发模式。在 TIMx_SMCR寄存器中写入 TS=110,选择 TI2 作为输入源。
  当 TI2 出现上升沿时,计数器开始根据内部时钟计数,并且 TIF 标志置 1。
  TI2 的上升沿与实际计数器启动之间的延迟是由于 TI2 输入的重新同步电路引起的。

  从模式:外部时钟模式 2 + 触发模式
  外部时钟模式 2 可与另一种从模式(外部时钟模式 1 和编码器模式除外)结合使用。这种情况下, ETR 信号用作外部时钟输入,在复位模式、门控模式或触发模式下工作时,可选择另一个输入作为触发输入。不建议通过 TIMx_SMCR 寄存器中的 TS 位来选择 ETR 作为TRGI。
  在以下示例中,只要 TI1 出现上升沿,递增计数器即会在 ETR 信号的每个上升沿处递增:
  A. 通过对 TIMx_SMCR 寄存器进行如下编程,配置外部触发输入电路:
  — ETF = 0000:无滤波器
  — ETPS = 00:禁止预分频器
  — ETP = 0:检测 ETR 的上升沿,并写入 ECE=1,以使能外部时钟模式 2。
  B. 如下配置通道 1,以检测 TI 的上升沿:
  — IC1F=0000:无滤波器。
  — 由于捕获预分频器不用于触发操作,因此无需对其进行配置。
  — TIMx_CCMR1 寄存器中 CC1S=01,只选择输入捕获源。
  — TIMx_CCER 寄存器中 CC1P=0 且 CC1NP=“0”,以确定极性(仅检测上升沿)。
  C. 在 TIMx_SMCR 寄存器中写入 SMS=110,将定时器配置为触发模式。在 TIMx_SMCR寄存器中写入 TS=101,选择 TI1 作为输入源。
  TI1 出现上升沿时将使能计数器并且 TIF 标志置 1。然后计数器在 ETR 出现上升沿时计数。
  ETR 信号的上升沿与实际计数器复位之间的延迟是由于 ETRP 输入的重新同步电路引起的。

4、定时器初始化结构体详解

  HAL 库 函 数 对 定 时 器 外 设 建 立 了 多 个 初 始 化 结 构 体, 分 别 为 时 基 初 始 化 结 构 体TIM_Base_InitTypeDef、 输 出 比 较 初 始 化 结 构 体 TIM_OC_InitTypeDef、 输 入 捕 获 初 始化 结 构 体 TIM_IC_InitTypeDef、 单 脉 冲 初 始 化 结 构 体 TIM_OnePulse_InitTypeDef、 编码 器 模 式 配 置 初 始 化 结 构 体 TIM_Encoder_InitTypeDef、 断 路 和 死 区 初 始 化 结 构 体TIM_BreakDeadTimeConfigTypeDef。高级控制定时器可以用到所有初始化结构体,通用定时器不能使用 TIM_BreakDeadTimeConfigTypeDef 结构体,基本定时器只能使用时基结构体TIM_Base_InitTypeDef。初始化结构体成员用于设置定时器工作环境参数,并由定时器相应初始化配置函数调用,最终这些参数将会写入到定时器相应的寄存器中。
  初始化结构体和初始化库函数配合使用是 HAL 库精髓所在,理解了初始化结构体每个成员意义基本上就可以对该外设运用自如了。初始化结构体定义在 stm32f4xx_hal_tim.h 文件中,初始化库函数定义在 stm32f4xx_hal_tim.c 文件中,编程时我们可以结合这两个文件内注释使用。

  4.1、TIM_TimeBaseInitTypeDef
  时基结构体 TIM_TimeBaseInitTypeDef 用于定时器基础参数设置,与 TIM_TimeBaseInit 函数配合使用完成配置。

typedef struct {
  uint16_t Prescaler; // 预分频器
  uint16_t CounterMode; // 计数模式
  uint32_t Period; // 定时器周期
  uint16_t ClockDivision; // 时钟分频
  uint8_t RepetitionCounter; // 重复计算器
} TIM_Base_InitTypeDef;

  (1) Prescaler:定时器预分频器设置,时钟源经该预分频器才是定时器计数时钟 CK_CNT,它设定 PSC 寄存器的值。计算公式为:计数器时钟频率 (f:sub:CK_CNT) 等于 fCK_PSC / (PSC[15:0]+ 1),可实现 1 至 65536 分频。
  (2) CounterMode:定时器计数方式,可设置为向上计数、向下计数以及中心对齐。高级控制定时器允许选择任意一种。
  (3) Period:定时器周期,实际就是设定自动重载寄存器 ARR 的值, ARR 为要装载到实际自动重载寄存器(即影子寄存器)的值,可设置范围为 0 至 65535。
  (4) ClockDivision:时钟分频,设置定时器时钟 CK_INT 频率与死区发生器以及数字滤波器采样时钟频率分频比。可以选择 1、 2、 4 分频。基本定时器没有此功能,不用设置。
  (5) RepetitionCounter:重复计数器,只有 8 位,只存在于高级定时器。基本定时器没有此功能,不用设置。

  4.2、TIM_OC_InitTypeDef
  输出比较结构体 TIM_OC_InitTypeDef 用于输出比较模式,与 TIM_OCxInit 函数配合使用完成指定定时器输出通道初始化配置。高级控制定时器有四个定时器通道,使用时都必须单独设置。

typedef struct {
  uint32_t OCMode; // 比较输出模式
  uint32_t Pulse; // 脉冲宽度
  uint32_t OCPolarity; // 输出极性
  uint32_t OCNPolarity; // 互补输出极性
  uint32_t OCFastMode; // 比较输出模式快速使能
  uint32_t OCIdleState; // 空闲状态下比较输出状态
  uint32_t OCNIdleState; // 空闲状态下比较互补输出状态
} TIM_OCInitTypeDef;

  (1) OCMode:比较输出模式选择,总共有八种,常用的为 PWM1/PWM2。它设定 CCMRx 寄存器 OCxM[2:0] 位的值。
  (2) Pulse:比较输出脉冲宽度,实际设定比较寄存器 CCR 的值,决定脉冲宽度。可设置范围为0 至 65535。
  (3) OCPolarity:比较输出极性,可选 OCx 为高电平有效或低电平有效。它决定着定时器通道有效电平。它设定 CCER 寄存器的 CCxP 位的值。
  (4) OCNPolarity:比较互补输出极性,可选 OCxN 为高电平有效或低电平有效。它设定TIMx_CCER 寄存器的 CCxNP 位的值。
  (5) OCFastMode:比较输出模式快速使能。它设定 TIMx_CCMR 寄存器的, OCxFE 位的值可以快速使能或者禁能输出。
  (6) OCIdleState:空闲状态时通道输出电平设置,可选输出 1 或输出 0,即在空闲状态(BDTR_MOE 位为 0) 时,经过死区时间后定时器通道输出高电平或低电平。它设定 CR2寄存器的 OISx 位的值。
  (7) OCNIdleState:空闲状态时互补通道输出电平设置,可选输出 1 或输出 0,即在空闲状态(BDTR_MOE 位为 0) 时,经过死区时间后定时器互补通道输出高电平或低电平,设定值必须与 OCIdleState 相反。它设定是 CR2 寄存器的 OISxN 位的值。
  4.3、TIM_IC_InitTypeDef
  输入捕获结构体 TIM_IC_InitTypeDef 用于输入捕获模式,与 HAL_TIM_IC_ConfigChannel函 数 配 合 使 用 完 成 定 时 器 输 入 通 道 初 始 化 配 置。 如 果 使 用 PWM 输 入 模 式 需 要 与HAL_TIM_PWM_ConfigChannel 函数配合使用完成定时器输入通道初始化配置。

typedef struct {
  uint32_t ICPolarity; // 输入捕获触发选择
  uint32_t ICSelection; // 输入捕获选择
  uint32_t ICPrescaler; // 输入捕获预分频器
  uint32_t ICFilter; // 输入捕获滤波器
} TIM_IC_InitTypeDef;

  (1) ICPolarity:输入捕获边沿触发选择,可选上升沿触发、下降沿触发或边沿跳变触发。它设定 CCER 寄存器 CCxP 位和 CCxNP 位的值。
  (2) ICSelection: 输 入 通 道 选 择, 捕 获 通 道 ICx 的 信 号 可 来 自 三 个 输 入 通 道, 分别 为 TIM_ICSELECTION_DIRECTTI、 TIM_ICSELECTION_INDIRECTTI 或TIM_ICSELECTION_TRC,具体的区别见图 31‑16。它设定 CCRMx 寄存器的 CCxS[1:0] 位的值。

                        图 31‑15 输入通道与捕获通道 IC 的映射图
  (3) ICPrescaler:输入捕获通道预分频器,可设置 1、 2、 4、 8 分频,它设定 CCMRx 寄存器的ICxPSC[1:0] 位的值。如果需要捕获输入信号的每个有效边沿,则设置 1 分频即可。
  (4) ICFilter:输入捕获滤波器设置,可选设置 0x0 至 0x0F。它设定 CCMRx 寄存器 ICxF[3:0] 位的值。一般我们不使用滤波器,即设置为 0。
  4.4、TIM_BreakDeadTimeConfigTypeDef
  断路和死区结构体 TIM_BreakDeadTimeConfigTypeDef 用于断路和死区参数的设置,属于高级定时器专用,用于配置断路时通道输出状态,以及死区时间。它与 HAL_TIMEx_ConfigBreakDeadTime函数配置使用完成参数配置。这个结构体的成员只对应 BDTR 这个寄存器,有关成员的具体使用配置请参考手册 BDTR 寄存器的详细描述。

typedef struct {
  uint32_t OffStateRunMode; // 运行模式下的关闭状态选择
  uint32_t OffStateIDLEMode; // 空闲模式下的关闭状态选择
  uint32_t LockLevel; // 锁定配置
  uint32_t DeadTime; // 死区时间
  uint32_t BreakState; // 断路输入使能控制
  uint32_t BreakPolarity; // 断路输入极性
  uint32_t BreakFilter; // 断路输入滤波器
  uint32_t Break2State; // 断路 2 输入使能控制
  uint32_t Break2Polarity; // 断路 2 输入极性
  uint32_t Break2Filter; // 断路 2 输入滤波器
  uint32_t AutomaticOutput; // 自动输出使能
} TIM_BreakDeadTimeConfigTypeDef;

  (1) OffStateRunMode:运行模式下的关闭状态选择,它设定 BDTR 寄存器 OSSR 位的值。
  (2) OffStateIDLEMode:空闲模式下的关闭状态选择,它设定 BDTR 寄存器 OSSI 位的值。
  (3) LockLevel:锁定级别配置, BDTR 寄存器 LOCK[1:0] 位的值。
  (4) DeadTime:配置死区发生器,定义死区持续时间,可选设置范围为 0x0 至 0xFF。它设定BDTR 寄存器 DTG[7:0] 位的值。
  (5) BreakState:断路输入功能选择,可选使能或禁止。它设定 BDTR 寄存器 BKE 位的值。
  (6) BreakPolarity:断路输入通道 BRK 极性选择,可选高电平有效或低电平有效。它设定 BDTR寄存器 BKP 位的值。
  (7) BreakFilter:断路输入滤波器,定义 BRK 输入的采样频率和适用于 BRK 的数字滤波器带宽。它设定 BDTR 寄存器 BKF[3:0] 位的值。
  (8) Break2State:断路 2 输入功能选择,可选使能或禁止。它设定 BDTR 寄存器 BK2E 位的值。
  (9) Break2Polarity:断路 2 输入通道 BRK2 极性选择,可选高电平有效或低电平有效。它设定BDTR 寄存器 BK2P 位的值。
  (10) Break2Filter:断路 2 输入滤波器,定义 BRK2 输入的采样频率和适用于 BRK2 的数字滤波器带宽。它设定 BDTR 寄存器 BK2F[3:0] 位的值。
  (11) AutomaticOutput:自动输出使能,可选使能或禁止,它设定 BDTR 寄存器 AOE 位的值。

 

posted @ 2025-04-07 15:17  孤情剑客  阅读(997)  评论(0)    收藏  举报