HAL库STM32常用外设教程(五)—— 定时器 输出比较



前言

1、STM32F407ZGT6
2、STM32CubeMx软件
3、keil5
内容简述:
通篇文章将涉及以下内容,如有错误,欢迎指出
1、通用定时器特性
2、通用定时器的结构和功能
3、定时器有关输出比较的HAL库驱动程序
(1)CubeMx配置
(2)TIM驱动程序
①输出频率、占空比相同,相位不同的PWM
②输出频率、占空比都不同的PWM


一、通用定时器特性概述

  通用定时器TIM2-TIM5以及TIM9-TIM14的功能如表1-1所示,它们的区别主要在于计数器的位数,捕获/比较通道的个数不同。
在这里插入图片描述

表1-1定时器基本特性

通用定时器具有以下特性:

  • 16位或32位自动重载计数器
  • 16位可编程预分频器,分频系数位1 - 65536,分频系数可在运行时修改。
  • 有1、2、4个独立通道 ,可用于
    (1)输入捕获
    (2)输出比较
    (3)PWM生成(边沿对齐或中心对齐)
    (4)单脉冲模式输出
  • 可使用外部信号控制定时器,可实现多个定时器互联的同步电路
  • 可发生如下事件时产生中断或DMA请求
    (1)更新——计数器上溢/下溢、计数器初始化(用过软件或内部/外部触发)
    (2)触发事件(计数器启动、停止、初始化或通过内部/外部触发计数)
    (3)输出比较
    (4)输入捕获
    注:在STM32F407的参考手册上,TIM2-TIM5可以使用外部时钟信号驱动计数器,而TIM9-TIM14只能使用内部时钟信号。

二、通用定时器框图

2.1 通用定时器框图

  通过学习通用定时器框图会有一个很好的整体掌握,同时对之后的编程也会有一个清晰的思路。
在这里插入图片描述

图2-1 通用定时器结构框图

① 时钟源
  通用定时器时钟可以选择下面四类时钟源之一:
1)内部时钟(CK_INT)
2)外部时钟模式 1:外部输入引脚(TIx)
3)外部时钟模式 2:外部触发输入(ETR)
4)内部触发输入(ITRx):使用一个定时器作为另一定时器的预分频器

注意:触发控制器输出时钟信号CK_PSC,若选择使用内部时钟,则CK_PSC就等同于CK_INT。

② 控制器
  控制器包括:从模式控制器、编码器接口和触发控制器(TRGO)。从模式控制器可以控制计数器复位、启动、递增/递减、计数。编码器接口针对编码器计数。触发控制器用来提供触发信号给别的外设,比如为其它定时器提供时钟或者为 DAC/ADC 的触发转换提供信号。

③ 时基单元
  时基单元包括:计数器寄存器(TIMx_CNT)、预分频器寄存器(TIMx_PSC)、自动重载寄存器
(TIMx_ARR)。这部分内容和基本定时器基本一样的,大家可以参考基本定时器里的介绍。
不同点:
Ⅰ、通用定时器的计数模式有三种: 递增计数模式、 递减计数模式和中心对齐模式。

  • 递增计数模式就是来了一个计数脉冲,计数器就加 1,直到计数器寄存器的值加到 ARR,加到ARR 时定时器溢出,由于是递增计数,故而称为定时器上溢,定时器溢出就会伴随着更新事件的发生,然后计数器又从自动重载寄存器影子寄存器的值开始继续递增计数,如此循环。
  • 递减计数模式就是来了一个计数脉冲,计数器就减 1,直到计数器寄存器的值减到 0,减到 0 时定时器溢出,由于是递减计数,故而称为定时器下溢,定时器溢出就会伴随着更新事件的发生。然后计数器又从自动重载寄存器影子寄存器的值开始继续递减计数,如此循环。
  • 中心对齐模式计数器先从 0 开始递增计数,直到计数器的值等于自动重载寄存器影子寄存器的值减 1 时,定时器上溢,同时生成更新事件,然后从自动重载寄存器影子寄存器的值开始递减计算,直到计数值等于 1 时,定时器下溢,同时生成更新事件,然后又从 0 开始递增计数,依此循环。每次定时器上溢或下溢都会生成更新事件。
    Ⅱ、TIM2 和 TIM5 的计数器是 32 位的。
    下面通过一张图展示定时器工作在不同计数模式下,更新事件发生的情况:
    ![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/bbe7a13b3e97414b876e06c0e742240a.png                  图2-2 更新事件发生条件
      上图中,纵轴表示计数器的计数值,横轴表示时间, ARR 表示自动重载寄存器的值,小红点就是更新事件发生的时间点。举个例子,递增计数模式下,当计数值等于 ARR 时,计数器的值被复位为 0,定时器溢出,并伴随着更新事件的发生,后面继续递增计数。
    ④ 输入捕获
      图 2-1中的第④部分是输入捕获,一般应用是要和第⑤部分一起完成测量功能。TIMx_CH1~ TIMx_CH4 表示定时器的 4 个通道,这 4 个通道都是可以独立工作的。 IO 端口通过复用功能与这些通道相连。配置好 IO 端口的复用功能后,将需要测量的信号输入到相应的IO 端口,输入捕获部分可以对输入的信号的上升沿,下降沿或者双边沿进行捕获。常见的测量有:测量输入信号的脉冲宽度、测量 PWM 输入信号的频率和占空比等。
    ⑤ 输入捕获和输出比较公用部分
      该部分需要结合第④部分或者第⑥部分共同完成相应功能。
    ⑥ 输出比较
      图2-1中的第⑥部分是输出比较,一般应用是要和第⑤部分一起完成定时器输出功能。TIMx_CH1~ TIMx_CH4 表示定时器的 4 个通道,这 4 个通道都是可以独立工作的。 IO 端口通过复用功能与这些通道相连。

2.2 捕获/比较通道

  通用定时器有1、2或4个捕获/比较通道,每个通道都是独立工作的。图2-1的定时器有2个捕获/比较通道:一个通道要么作为捕获输入通道,要么作为比较通道;每个通道有一个复用的引脚,如TIM9_CH1、TIM9_CH2复用引脚。
  捕获/比较通道由输入阶段、比较阶段和输出阶段组成。

  • 输入阶段。通道作为输入引脚,例如图2-1中④左侧的TIMx_CH1,从复用引脚输入时钟信号TI1,输入阶段可以对输入信号TI1进行滤波和边沿检测,在经过选择器和预分频器后得到时钟信号IC1PS。
  • 捕获/比较阶段。有一个具有预装载功能的捕获/比较寄存器(Capture/Compare Register),以及相关的影子寄存器,可以读写CCR。在捕获模式下,捕获实际发生在影子寄存器中,然后将影子寄存器的内容复制到CRR中。在比较模式下,CRR的内容将复制到影字寄存器中,然后将影子寄存器的内容与计数器值进行比较。
  • 输出阶段。输出阶段就是根据设置的工作模式和控制逻辑,控制输出引脚的电平。使用捕获/比较通道,通用定时器可以实现如下功能。
    ①输入捕获,可用于测量一个时钟信号的频率,脉冲宽度等。
    ②输出比较,将计数器CNT的值与CRR的值比较,控制输出引脚的电平。
    ③PWM生成,通过设置ARR和CRR的值,在计数器的值CNT变化过程中输出PWM波。PWM波的频率由ARR决定,占空比由CRR决定。
    ④单脉冲模式输出。

三、输出比较原理及相关HAL驱动

3.1 PWM原理回顾

先回顾一下前面文章《HAL库STM32常用外设教程(一)—— 定时器 输出PWM》中提到的PWM模式(图3-1):
在这里插入图片描述

图 3-1 PWM模式

在这里插入图片描述

图3-2 PWM频率计算

  其中当CNT计数值 = pulse(也就是CCR值)时,电平就会翻转,当CNT计数达到ARR后,再计数时CNT的值就会清0。总结来说,PWM模式下,PWM的频率由自动重装载值(ARR)和预分频值(PSC)共同决定,CCR决定的是PWM的占空比

3.2 输出比较原理概述

  那我们再来看输出比较模式的特点,单片机定时器的输出比较(output compare)原理是指定时器内部的计数器不断增加,当计数器的值(CNT)与预设的比较值(CCR)相等时,定时器会生成一个特定的输出信号。例如,可以设置定时器在计数器达到某个值时,自动改变输出引脚的电平状态,从而产生定时的脉冲信号。这种原理常用于产生精确的时间延迟、PWM信号或事件触发,以实现对硬件的控制和管理
注:
  ① 简单来说就是在输出比较这块电路会比较CNT和CCR的值。CNT计数自增,CCR是我们给定的一个值,当CNT大于CCR、小于CCR时,引脚就会输出高电平或者是低电平。

  ② 这个捕获/比较寄存器是输入捕获和输出比较共用的,当使用输入捕获时,它就是捕获寄存器,当时用输出比较时,它就是比较寄存器。

  下图3-3是输出比较比较模式的原理示意图。

在这里插入图片描述

图3-3 输出比较模式

  在CubeMx里面配置完输出比较模式后,PWM的周期也是固定的,是一个计数周期两倍,频率是周期的倒数,所以频率也是固定的,从图3.3可以看出占空比也是固定的,都是50%,因为 此时是CNT = CCR的时候进行翻转电平(Toggle on match 模式下),CNT是从0到65535之间不断变化(递增模式下计数计到最大值65535时,会重新从0开始计数)。CCR的值如果不变,那么CNT计数记到CCR的周期就是固定的
注:
  以STM32F407为例,假设ARR值设置的是65535,预分频器PSC值是168-1,TIM1的通道1输出,那么就可以计算出此时TIM1_CH1输出比较模式下的频率。

在这里插入图片描述
上述计算得出的就是图3-5和图3-6中PWM的频率,从图中给出的数据也可以看出频率等参数。
  那么此时CCR决定的是什么呢?
  设置CCR1和CCR2的值进行对比,通过图3.4可以看出,CCR值不同时 其占空比依旧是50%,周期也是计数周期的两倍,并没有变化,但是从红色的虚线可以看出PWM的相位发生了变化,所以,在输出比较中 每个通道的初相位可以通过各通道的CCRx来确定
  通过 图3-5 和 图3-6 的实际输出进一步观察,其中 图3-5 的CCR1 = 5,CCR2 = 30000,两个PWM的相位差约为四分之一的周期,将CCR2的值增大到65530,此时从图3-6可以看出相位差已将接近二分之一个周期。
在这里插入图片描述

图3-4 输出比较模式对比

在这里插入图片描述

图3-5 不同CCR下的PWM(1)

3.3 输出比较相关的驱动函数

  输出比较相关的HAL函数如表3-1所示,这里仅列出了相关函数名,简要说明其功能相关函数在stm32f4xx_hal_tim.h中。

表3-1 输出比较相关的HAL函数
函数名功能描述
HAL_TIM_OC_Init()输出比较初始化,需先执行HAL_TIM_Base_Init()进行定时器初始化
HAL_TIM_OC_ConfigChannel()输出比较通道配置
HAL_TIM_OC_Start()启动输出比较,需要先执行HAL_TIM_Base_start()启动定时器
HAL_TIM_OC_Stop()停止输出比较
HAL_TIM_OC_Start_IT()以中断方式启动输出比较,需要先执行HAL_TIM_Base_start_IT()启动定时器
HAL_TIM_OC_Stop_IT()停止输出比较
__HAL_TIM_GET_COMPARE()获取基础定时器的当前状态
__HAL_TIM_ENABLE_OCxPRELOAD()使能CCR的预装载功能,为CCR设置的新值下个UEV事件发生时才更新到CCR寄存器
__HAL_TIM_DISABLE_OCxPRELOAD()禁止CCR的预装载功能,为CCR设置d额新值立刻更新到CCR寄存器
__HAL_TIM_SET_COMPARE()设置比较寄存器CCR的值
__HAL_TIM_GET_COMPARE()读取比较寄存器CCR的值
HAL_TIM_OC_DelayElapsedCallback()产生比较事件的回调函数

四、输出相位不同的PWM

4.1 示例概述

  在STM32F407中,使用定时器TIM1的输出比较模式可以生成不同相位的PWM信号。通过配置TIM1的通道1和通道2,可以实现相位差的PWM输出。具体过程如下:首先,设置TIM1的计数频率和PWM频率,确保两个通道的频率一致。然后,配置通道1的比较值(CCR1),设定其高电平持续时间,从而确定占空比。接着,为通道2设置一个不同的比较值(CCR2),使其在时间上相对于通道1产生相位差。

4.2 STM32CubeMx配置

  定时器1的模式和参数设置结果如图4.1所示,进行如下配置:
(1)在模式设置中,设置Clock Source(时钟源)为 Internal Clock(内部时钟)
(2)设置 Channel1 工作模式为 Output Compare CH1,使用输出比较功能。
(3)设置 Channel2 工作模式为 Output Compare CH2,使用输出比较功能。
(4)在参数设设置中,将“Counter Settings”(预分频寄存器)设置为 168 - 1,所以计数器的时钟频率为 168M / ( 168 - 1 +1) = 1MHZ。
(5)设置“Counter Period”的值为 65535(最大),因为在输出比较模式中ARR的值没起作用,定义成最大的原因是不用频繁的更新CNT为0了。
(6)配置TIM1的通道1,设置"Mode"为Toggle on match,设置Pulse,就是CCR的值,这里通道1的CCR值设置为 5
(7)配置TIM1的通道2,设置"Mode"为Toggle on match,设置Pulse,就是CCR的值,这里通道2的CCR值设置为 30000
在这里插入图片描述

图4-1 定时器TIM1的模式和参数设置(1)

在这里插入图片描述

图4-2 定时器TIM1的模式和参数设置(2)

在这里插入图片描述

图4-3定时器TIM1的模式和参数设置(3)

  上面的配置就是TIM1输出比较的配置,为了更好的理解每个选项的含义,对其中的一部分主要选项进行讲解:
Counter Settings组用于设置定时器的基本参数,主要设置结果如下。

  • PSC(预分频器数值):这个值决定了定时器的时钟分频系数。它将定时器输入时钟的频率分频为更低的频率,以满足特定的计数需求。例如,如果定时器输入时钟频率为100 MHz,PSC设置为999,则定时器的实际时钟频率为100 kHz。

  • Counter Mode:这个设置确定定时器的计数模式,通常有向上计数、向下计数、或向上/向下计数模式。

  • ARR(自动重装载值):这是定时器的周期值,表示定时器从0计数到这个值后重新开始。在输出比较模式下,这个值通常决定了PWM信号的周期。

  • Internal Clock Division(CKD):这个选项用于配置时钟的分频系数。它决定了如何将输入时钟分频为定时器的时钟。在CubeMx中,通常有以下几种选项:
      No Division : 不分频,定时器时钟等于输入时钟。
      Division by 2 : 输入时钟除以2。
      Division by 4 : 输入时钟除以4。

  • Repetition Counter:这个选项表示重复计数器的值,用于设置定时器的重复计数模式。在定时器工作中,当计数器达到重复计数器的值时,会发生一个事件(通常是更新事件),并且计数器会重新开始计数。这个参数一般用于生成较长的计数周期或控制特定的计数触发条件。

  • auto-reload preload:这个选项决定是否启用自动重载寄存器(ARR)的预装载功能。预装载允许在更新事件时保护ARR的写入,确保更改在下一个周期生效。

Output Compare Channel 组是通道1和通道2的输出比较参数,配置如图4.2,各个参数的意义和设定值如下。

  • Mode:设置了输出比较通道的工作模式。以下是各个模式选项的含义:
      Frozen:在这种模式下,输出比较通道不会对任何事件做出反应。无论计数器与比较寄存器值是否匹配,输出引脚的状态都不会改变。这种模式通常用于计时目的,而不需要实际改变输出引脚的状态。
      Active Level on match:当计数器的值与比较寄存器值匹配时,通道输出引脚被置为高电平(逻辑“1”)。在这种模式下,计数器值与比较寄存器值匹配时会使输出引脚变为高电平。
      Inactive Level on match:当计数器的值与比较寄存器值匹配时,通道输出引脚被置为低电平(逻辑“0”)。在这种模式下,计数器值与比较寄存器值匹配时会使输出引脚变为低电平。
      Toggle on match:当计数器的值与比较寄存器值匹配时,通道输出引脚的状态会被翻转(即从高电平变为低电平,或从低电平变为高电平)。这种模式用于生成方波信号,频率由计数器周期和比较寄存器值决定。
      Forced Active:输出引脚被强制置为高电平(逻辑“1”),不管计数器值与比较寄存器值的匹配情况。这种模式用于需要持续高电平输出的情况。
      Forced Inactive:输出引脚被强制置为低电平(逻辑“0”),不管计数器值与比较寄存器值的匹配情况。这种模式用于需要持续低电平输出的情况。

  • Pulse:脉冲宽度,就是CCR的值

  • Output compare preload:设置CCR是否使用预装载功能。本示例不动态的修改CCR的值,设置为Enable和Disable无影响。

  • CH Polarity:通道极性。如果参数Mode设置为Active level on match 或Intactive level on match等与通道极性有关的模式,此参数就是输出的有效电平。本示例模式设置为匹配时输出翻转,此参数无关。

  • CH Idle State:用于配置输出比较通道在定时器未运行或未使能时的默认电平状态。它确保在计时器停止或不活动期间,输出引脚保持预设的电平,通常为低电平(Reset)或高电平(Set),以防止意外的电平浮动或错误信号干扰,从而提高系统的稳定性和可靠性。

4.3 代码设置

  根据上面的步骤配置好定时器TIM1后,生成并打开工程,根据下面的步骤打开TIM1的输出比较功能。
  实现本示例的功能代码上需要添加的内容是相对较少的,只需要通过HAL_TIM_OC_Start 函数启动指定 定时器通道的输出比较功能 即可,该函数原型是:

HAL_StatusTypeDef HAL_TIM_OC_Start(TIM_HandleTypeDef *htim, uint32_t Channel);
  • TIM_HandleTypeDef htim: 指向定时器句柄的指针,包含了定时器的配置信息和状态信息。
  • uint32_t Channel: 指定定时器的通道。

在这里插入图片描述

	HAL_TIM_OC_Start(&htim1,TIM_CHANNEL_1);  /* 启动TIM1通道1的输出比较 */
	HAL_TIM_OC_Start(&htim1,TIM_CHANNEL_2);  /* 启动TIM1通道2的输出比较 */

4.4 示例结果

  在CubeMx里面配置好两个输出通道后,会发现其中TIM1CH1通道对应的是PE9引脚,TIM1CH2通道对应的是PE11引脚,将这两个引脚分别用两路示波器进行测试,如下图所示,其中的对应关系是
  黄线 —— PE9 ——TIM1 CH1
  绿线 —— PE11 ——TIM1 CH2
  从波形的示意图中可以看出,两个PWM波形的周期和频率是一样的,但是它们的相位是不相同的,关于波形频率等内容的计算可以参考上面列出的公式。
在这里插入图片描述

在这里插入图片描述

五、输出频率不同的PWM

5.1 示例框架及原理概述

  PWM模式下同一定时器不同通道能够输出占空比不同,频率相同的PWM,输出比较模式下 同一定时器不同通道可以输出占空比不同,频率不同的PWM。在本示例程序设置的整体思路如下:
  输出比较模式在CNT与CCR不断做比较的过程中,若CNT等于CCR,产生的则是电平翻转,并且会产生中断,通过调用 中断回调函数HAL_TIM_OC_DelayElapsedCallback,在中断回调函数里面对定时器的比较值进行修改,就能够实现多路不同频率信号的输出

例如,我们进行如下操作:

  • 定义OC_Channel1_Duty作为TIM1通道1的占空比,将OC_Channel1_Duty的值设置为 70%。
  • 定义OC_Channel1_Pulse作为周期计数数目,OC_Channel1_Pulse y的值设置为 1000。
  • 取ARR为最大值 65535(在输出比较模式中ARR没起作用,CNT从ARR值溢出后,会重新从0开始计时,所以就ARR设置成最大后CNT就不用经常更新了)。
  • 系统时钟为 168MHz,预分频系数PSC设置为168-1(和示例1的值一样),则分频后的时钟频率为1MHz,那么当计 pulse 个数目,也就是 1000 个数时,所用的时间为1ms,占空比为70%,即所需高电平时间为0.7ms。

注:示例2是在回调函数里面自己重新配置的输出比较翻转方式,所以和示例1的周期计算略有差别,应当注意此细节变化。

  当第一次CNT等于CCR时,进入中断回调函数HAL_TIM_OC_DelayElapsedCallback(),让CCR加上(pulse - pulse * duty),即0.3ms后再次进行反转电平,此时PWM持续了0.3ms的低电平;

  当第二次CNT等于CCR是,进入中断回调函数,让CCR加上(pulse*duty),即0.7ms后再进行反转电平,此时PWM持续了0.7ms的高电平;这样即可完成输出比较PWM的配置。

5.2 STM32CubeMx配置

 在示例示例1中的配置下STM32CubeMx需要进行两处修改。
(1)在TIM1的“ NVIC Setting”配置里面 打开定时器1中断设置,如图4.4。
在这里插入图片描述

图5-1 定时器TIM1的中断设置

(2)TIM中的两个通道的pulse数值可以设置为0,如图4.5所示,因为在程序中对Pulse的又进行了赋值,此处需要提到程序中用到的一个__HAL_TIM_SET_COMPARE()(设置比较寄存器CCR的值),该函数的第三个参数就是设置的Pulse的值,就是在该函数的参数中对其进行了赋值。(也可以保持示例1的数值不变)

在这里插入图片描述

图5-2 定时器TIM的pulse设置

5.3 代码设置

根据上面的步骤配置好定时器TIM1后,生成并打开工程,根据下面的步骤进行输出PWM。
(1)先定义变量,分别是定时器TIM1通道2的占空比和脉冲宽度(也就是ARR的值)、定时器TIM1通道2的的占空比和脉冲宽度。
在这里插入图片描述

	uint32_t OC_Channel1_Pulse = 1000;      /* TIM1通道1的脉冲宽度 */
	uint32_t OC_Channel1_Duty = 70;			/* TIM1通道1的占空比 */
	uint32_t OC_Channel2_Pulse = 1200;	    /* TIM1通道2的脉冲宽度 */
	uint32_t OC_Channel2_Duty = 50;			/* TIM1通道2的占空比 */

(2)启动了 TIM1 的通道1和通道 2 的输出比较功能,并使能与之相关的中断,使得通道1和通道 2 在 计数器值CNT 与 比较值CCR 匹配时能够触发中断。

在这里插入图片描述

	HAL_TIM_OC_Start_IT(&htim1,TIM_CHANNEL_1);  /* 以中断方式启动TIM1通道1的输出比较 */
	HAL_TIM_OC_Start_IT(&htim1,TIM_CHANNEL_2);  /* 以中断方式启动TIM1通道2的输出比较 */

(3)在HAL_TIM_OC_DelayElapsedCallback回调函数里面进行改变PWM的占空比,这一部分是相对重要的,也是较难理解的。
在这里插入图片描述

void HAL_TIM_OC_DelayElapsedCallback(TIM_HandleTypeDef *htim)
{
	uint32_t OC_Count = 0;
	OC_Count = __HAL_TIM_GET_COUNTER(htim);	/* 读取定时器的当前计数值,就是读取TIM1_CNT寄存器的值 */
	if(htim->Instance == TIM1){			    /* 判断是否是定时器1 */
		if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_1){	              /* 判断是否是通道1 */
			if(GPIO_PIN_RESET == HAL_GPIO_ReadPin(GPIOE,GPIO_PIN_9)){ /* 判断此时的电平是否为低电平 */
				__HAL_TIM_SET_COMPARE(&htim1,TIM_CHANNEL_1,OC_Count + OC_Channel1_Pulse - OC_Channel1_Duty * OC_Channel1_Pulse/100);/* 设置比较寄存器CCR的值--0.3ms的低电平 */
			}else{
				__HAL_TIM_SET_COMPARE(&htim1,TIM_CHANNEL_1,OC_Count + OC_Channel1_Duty * OC_Channel1_Pulse/100);/* 设置比较寄存器CCR的值--0.7ms的高电平 */
			}
		}else if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_2){ /* 判断是否是通道2 */
			if(GPIO_PIN_RESET == HAL_GPIO_ReadPin(GPIOE,GPIO_PIN_11)){
				__HAL_TIM_SET_COMPARE(&htim1,TIM_CHANNEL_2,OC_Count + OC_Channel2_Pulse - OC_Channel2_Duty * OC_Channel2_Pulse/100);
			}else{
				__HAL_TIM_SET_COMPARE(&htim1,TIM_CHANNEL_2,OC_Count + OC_Channel2_Duty * OC_Channel2_Pulse/100);
			}
		}
	}
}

  先通俗的以定时器通道1为例讲解一下其思路,当输出比较的CCR和CNT相同时,产生中断,进入中断回调函数HAL_TIM_OC_DelayElapsedCallback,在回调函数里面先判断是不是定时器TIM1,再判断是不是TIM1的通道1,然后判断此时的电平是什么,结合电平状态和__HAL_TIM_SET_COMPARE函数去设置占空比。
  按照上面的参数,举个例子去理解一下这段代码实现的功能:
关于通道1的相关参数:

OC_Channel1_Pulse = 1000 (TIM1通道1重装载寄存器值)
OC_Channel1_Duty = 70 (TIM1通道1正占空比)
OC_Count1= 0 (TIM1通道1比较寄存器值)

关于通道2的相关参数:

OC_Channel2_Pulse = 1200 (TIM1通道2重装载寄存器值)
OC_Channel2_Duty = 50 (TIM1通道2正占空比)
OC_Count2 =0 (TIM1通道2比较寄存器值)

当GPIO状态为低电平时,通道1(CCR1)的值:
在这里插入图片描述
当GPIO状态为高电平时,通道1(CCR1)的值:
在这里插入图片描述

当GPIO状态为低电平时,通道2(CCR2)的值:
在这里插入图片描述
当GPIO状态为高电平时,通道2(CCR2)的值:
在这里插入图片描述

5.4 示例结果

  从上面的计算可以得出,TIM1CH1最终产生的PWM应该是正占空比为70%,负占空比占30%的一个波形。TIM1CH2最终产生的PWM应该是正占空比为50%,负占空比占50%的一个波形。
  结合每个通道在程序中设置的脉冲宽度(也就是ARR的值)可以得出,TIM1CH1(ARR = 1000)的频率应该是1KHz,那么周期应该是1ms,正周期占空比为0.7ms,负周期占空比为0.3ms。TIM1CH2(ARR = 1200)的频率约为833.3Hz,那么周期应该是1.2ms,正周期占空比为0.6ms,负周期占空比为0.6ms,可以结合下图进行参考。

请添加图片描述


参考书籍和文章:
《STM32Cube高效开发教程(基础篇)》王维波
《STM32F4xx中文参考手册》
《STM32F407 探索者开发指南》
《stm32输出比较模式与PWM模式总结》
《STM32-HAL库08-TIM的输出比较模式(输出PWM的另一种方式)》
《STM32 定时器输出比较模式和PWM输出模式的区别》


  勇敢是当你还未开始就已经知道自己会输,可你依然要去做,而且无论如何都要把它坚持到底,你很少能赢,但有时也会。

——《杀死一只知更鸟》

### 回答1: 野火HAL库是针对STM32微控制器系列开发的一种软件库。HAL是Hardware Abstraction Layer的缩写,意味着硬件抽象层。它提供了一组封装好的函数和宏,使开发者可以更方便地使用STM32微控制器的功能和资源。 野火HAL库可以在STM32微控制器上进行低级编程,例如GPIO、UART、SPI、I2C等外设的控制。它提供了一种简化和标准化的开发方式,使开发者能够使用相同的库函数来控制不同的STM32微控制器型号和系列。 野火HAL库的特性和优势包括: 1. 封装了底层寄存器和硬件细节,提供了易于理解的高级函数接口,简化了开发流程。 2. 提供了标准的函数和宏,节约了开发时间,提高了开发效率。 3. 支持多种外设的控制,覆盖了常见的功能需求。 4. 库函数经过严格的测试和验证,具有较高的稳定性和可靠性。 5. 支持多种开发环境,包括Keil、IAR等,适应不同的开发需求。 使用野火HAL库进行开发时,开发者可以通过调用库函数轻松地进行外设的初始化和配置。例如,使用库函数可以方便地设置GPIO口的输入输出模式、中断触发方式等。另外,库函数还提供了许多其他功能,例如定时器的配置、PWM的生成、ADC的采样等。 总之,野火HAL库是一种方便、快速、可靠的STM32微控制器开发工具,对于初学者和有限的开发时间的人来说非常有用。它提供了一种高级的抽象,使开发者可以更关注功能的实现,而不必过多关注底层的细节和寄存器操作。 ### 回答2: 野火HAL库是一种适用于STM32系列微控制器的软件包,它为开发者提供了一种简化和加速开发过程的方法。 首先,野火HAL库提供了一套丰富的函数和方法,用于深入控制STM32微控制器的各个模块和外设。这些函数和方法可以帮助开发者轻松地配置和操作GPIO、定时器、串口等硬件资源,从而实现各种功能。通过使用野火HAL库,开发者可以更快速地理解和掌握STM32的硬件资源,减少开发时间和精力。 其次,野火HAL库提供了一些现成的模块和组件,可以帮助开发者快速实现一些常见的功能。例如,野火HAL库提供了用于控制LCD、触摸屏和按键等外设的函数,以及一些常见的通信协议(如SPI、I2C和CAN)的函数。通过使用这些现成的模块和组件,开发者可以极大地简化开发过程,节省开发时间。 此外,野火HAL库还提供了一些示例代码和案例,供开发者参考和学习。这些示例代码和案例涵盖了各种应用场景,如LED闪烁、温度测量和电机控制等。通过参考这些示例代码和案例,开发者可以深入了解如何使用野火HAL库,并借鉴其中的实现方法和思路。 综上所述,野火HAL库是一款功能强大的STM32开发工具,它简化了开发者对硬件资源的操作和配置,提供了现成的模块和组件,同时还提供了示例代码和案例供参考。通过野火HAL库,开发者可以更快速、高效地进行STM32微控制器的开发工作。 ### 回答3: 野火HAL库是适用于STM32系列微控制器的一套软件库,用于简化开发人员在这些微控制器上实现应用程序的过程。HAL是全称为Hardware Abstraction Layer,意为硬件抽象层,它提供了一组函数接口,用于访问芯片上的硬件资源,如GPIO、UART、SPI等。 在使用野火HAL库之前,我们首先需要了解STM32系列微控制器的基本原理和架构,并熟悉C语言编程。野火HAL库采用了面向对象的设计思想,将芯片的硬件资源封装成对象,并提供了一些常用的操作方法,使得开发人员可以更加方便地访问和控制这些硬件资源。 使用野火HAL库可以大幅度地提高开发效率,因为它在底层的驱动层已经帮我们处理了大部分繁琐的硬件操作细节。例如,我们想要控制一个LED灯的开关状态,只需要调用库函数即可,而不需要自己编写驱动代码。 野火HAL库提供了丰富的示例代码和开发手册,其中包含了大量的使用说明和例程,使得开发者可以快速上手。除了基本的硬件驱动外,野火HAL库还提供了很多常用的功能模块,如定时器、中断控制、电源管理等,可以满足不同应用场景的需求。 总之,野火HAL库是一套适用于STM32微控制器的软件库,它提供了简化的硬件访问接口和功能模块,可以帮助开发者更加方便地进行应用程序开发。无论是初学者还是有经验的开发者,都可以通过学习和使用这个库来快速实现自己的想法。
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值