一、定时器介绍

(一)STM32 定时器概述

  1. STM32 系列芯片有多种定时器,包括基本定时器(TIM6 和 TIM7)、通用定时器(TIM2 – TIM5)和高级定时器(TIM1 和 TIM8)。这些定时器可以用于多种功能,如定时中断、输入捕获、输出比较和 PWM(脉冲宽度调制)生成等。
  2. 定时器的核心是一个 16 位或 32 位的计数器,它根据预分频器(PSC)的值对内部时钟(一般由系统时钟提供)进行分频后计数。例如,系统时钟频率为 72MHz,预分频器设置为 71,那么计数器的计数频率就是 72MHz/(71 + 1)=1MHz,即每 1 微秒计数器加 1。

(二)基本定时器(TIM6 和 TIM7)

  1. 功能特点:基本定时器主要用于简单的定时功能,产生定时中断。它相对比较简单,只有一个 16 位的自动重装载计数器和一个 16 位的预分频器。
  2. 应用场景:例如,在一个简单的定时任务系统中,使用 TIM6 定时器来产生 1ms 的定时中断,以更新系统中的时间戳或者周期性地执行一些后台任务,如检查传感器状态等。配置步骤大致如下:
  • 首先,开启定时器时钟,通过 RCC(复位和时钟控制)寄存器来实现。
  • 然后,设置预分频器的值,确定计数频率。
  • 接着,设置自动重装载寄存器的值,确定定时周期。例如,要产生 1ms 的定时中断,在计数频率为 1MHz 的情况下,自动重装载寄存器的值应设置为 1000。
  • 最后,配置定时器中断并使能定时器。
  • (三)通用定时器(TIM2 – TIM5)

    1. 功能特点:通用定时器在基本定时器的基础上增加了更多功能。它们具有输入捕获和输出比较功能。输入捕获可以用于测量外部信号的脉冲宽度、周期等参数。输出比较可以用于在计数器达到特定值时改变输出电平,从而生成 PWM 信号等。
    2. 应用场景:在电机控制领域,利用通用定时器的输出比较功能来生成 PWM 信号控制电机转速。以控制直流电机为例,通过改变 PWM 信号的占空比来调节电机两端的平均电压,从而控制电机的转速。在信号测量方面,输入捕获功能可用于测量外部脉冲信号的频率。假设要测量一个方波信号的频率,将该信号接入通用定时器的输入捕获引脚,通过记录两次上升沿(或下降沿)之间的计数器值和计数频率,就可以计算出信号的频率。

    (四)高级定时器(TIM1 和 TIM8)

    1. 功能特点:高级定时器在通用定时器的基础上增加了一些高级特性,如死区时间插入、互补输出等。死区时间插入主要用于防止在电机控制等应用中,上下桥臂同时导通而造成短路。互补输出可以用于驱动三相电机等复杂的负载。
    2. 应用场景:在三相交流电机的变频调速控制中,高级定时器的互补输出和死区时间插入功能就显得尤为重要。通过生成具有合适死区时间的三相 PWM 信号来控制电机的三相绕组,实现电机的平稳调速和高效运行。

     

    二、PWM介绍

    (一)定义

  • PWM 即脉冲宽度调制(Pulse – Width Modulation),是一种对模拟信号电平进行数字编码的方法。它通过调节脉冲信号的占空比(Duty Cycle)来控制输出信号的平均功率或平均电压等,占空比是指脉冲信号中高电平持续时间与整个周期的比值。例如,一个周期为 10ms 的脉冲信号,高电平持续时间为 6ms,那么占空比就是 6ms/10ms = 60%。
  • (二)基本原理

  • PWM 的基本原理是基于数字信号控制模拟设备。以控制直流电机转速为例,在固定的周期内,通过改变高电平(也可以是低电平)的持续时间来改变输出信号的平均功率。当占空比为 0% 时,电机两端平均电压为 0,电机不转;当占空比为 100% 时,电机两端电压最高,电机转速最快。其本质是通过一系列宽度不同的脉冲信号来等效模拟一个连续变化的模拟信号。
  • (三)优点及应用范围

    1、优点:

  • 数字实现简单:可以很容易地用数字电路或微控制器(如 STM32)实现,无需复杂的数模转换电路。
  • 抗干扰能力强:因为是数字信号,所以相比模拟信号,它对噪声等干扰的抵抗能力更强。
  • 功率损耗低:在一些应用中,通过合理的占空比控制,可以有效降低功率损耗。
  • 2、应用范围:

  • 电机控制:广泛应用于直流电机、步进电机和交流电机的调速控制。例如,在电动玩具车中,使用 PWM 控制直流电机来实现不同的车速。
  • 灯光控制:用于调节 LED 灯的亮度。比如在智能照明系统中,通过改变 PWM 信号的占空比来控制 LED 灯的亮度,实现不同的光照场景。
  • 电源管理:在开关电源中,通过 PWM 控制功率开关管的导通和关断,实现对输出电压的稳定控制。
  • 3、主要参数

  • 周期(T):是指 PWM 信号重复一次所需要的时间,单位通常为秒(s)、毫秒(ms)或微秒(us)。例如,一个 PWM 信号的周期为 20ms。
  • 频率(f):是周期的倒数,即,单位为赫兹(Hz)。例如,周期为 20ms 的 PWM 信号,其频率为。
  • 占空比(D):如前面所定义,是高电平(或低电平)持续时间与周期的比值,范围通常是 0 – 1 或 0% – 100%。例如,高电平持续时间为 5ms,周期为 10ms 的 PWM 信号,占空比为 50%。
  • (四)PWM 的产生

  • 在微控制器中,PWM 通常由定时器模块产生。定时器内部有一个计数器,通过配置定时器的预分频器、自动重装载寄存器等来确定计数频率和周期。以 STM32 为例,当计数器的值与比较寄存器的值相等时,可以改变输出电平,从而产生 PWM 信号。
  • (五)PWM 工作原理

  • 当定时器开始工作时,计数器按照一定的频率进行计数。假设一个 PWM 周期为 10 个计数单位,比较寄存器的值设置为 3。当计数器从 0 开始计数,在计数到 3 之前,输出为高电平;当计数器大于等于 3 时,输出为低电平,直到计数器重新从 0 开始计数,这样就产生了一个占空比为 3/10 的 PWM 信号。
  • (六)PWM 输出的模式区别

  • 边沿对齐模式:在这种模式下,PWM 信号的上升沿或下降沿是对齐的。例如,在向上计数的边沿对齐模式中,计数器从 0 开始向上计数,当计数到比较寄存器的值时,输出电平改变,直到计数器达到周期值,然后重新从 0 开始计数。
  • 中心对齐模式:PWM 信号的脉冲中心是对齐的。在这种模式下,计数器先向上计数,当计数到周期的一半时,开始向下计数。在向上和向下计数过程中,根据比较寄存器的值改变输出电平,产生的 PWM 信号在脉冲中心位置是对称的。
  • (七)PWM 的计数模式

  • 向上计数模式:计数器从 0 开始,每次计数脉冲到来时,计数器的值加 1,直到计数器的值达到自动重装载寄存器的值,然后计数器重新从 0 开始计数。这种模式常用于产生边沿对齐的 PWM 信号。
  • 向下计数模式:计数器从自动重装载寄存器的值开始,每次计数脉冲到来时,计数器的值减 1,直到计数器的值为 0,然后重新从自动重装载寄存器的值开始计数。
  • 向上 – 向下计数模式:计数器先从 0 开始向上计数,当计数到自动重装载寄存器的值时,开始向下计数,直到计数器的值为 0,然后又重新向上计数。这种模式常用于产生中心对齐的 PWM 信号。
  • (八)PWM 相关配置寄存器

    1、捕获 / 比较模式寄存器(TIMx_CCMR1):

  • 这个寄存器用于设置捕获 / 比较通道的模式。在 PWM 产生过程中,用于确定是 PWM 模式 1 还是 PWM 模式 2 等。例如,在 STM32 中,通过设置不同的位来选择是输出到对应的引脚还是用于其他捕获 / 比较功能。它还可以设置输出极性,即高电平有效还是低电平有效。如果设置为高电平有效,当满足比较条件时,输出引脚输出高电平;如果设置为低电平有效,输出引脚输出低电平。
  • 2、捕获 / 比较使能寄存器(TIMx_CCER):

  • 用于启用或禁用捕获 / 比较通道。在 PWM 应用中,通过设置相应的位来使能 PWM 信号输出到指定的引脚。例如,当设置某个位为 1 时,对应的捕获 / 比较通道就可以将 PWM 信号输出到外部引脚。
  • 3、捕获 / 比较寄存器(TIMx_CCR1):

  • 这个寄存器的值是非常关键的,它用于和计数器的值进行比较,以决定 PWM 信号的占空比。在产生 PWM 信号时,根据计数器的值和 CCR1 寄存器的值的比较结果来改变输出电平。例如,在向上计数的 PWM 模式中,当计数器的值小于 CCR1 寄存器的值时,输出高电平;当计数器的值大于等于 CCR1 寄存器的值时,输出低电平。
  •  

    三、定时器项目配置

    (一)使用Stm32 Cube Mx创建项目

    (1)新建工程

    (2)芯片选择

    (3)配置SYS

    选择调试接口,点System Cor,选择SYS。,在右侧弹出的菜单栏中选Serial Wire。

    (4)配置RCC

    点System Cor,选择RCC,在右侧弹出的菜单栏中选Crystal/Ceramic Resonator

    (5)定义IO口输出

    选择PA1作为LED灯的输出,将其选为GPIO-OUT

    (6)配置定时器2和定时器3

    这里我们使用定时器2和定时器3来实现定时的功能。如图所示,依次点击位置1,选中定时器2;位置2,配置定时器2的时钟源为内部时钟;位置3,分频系数为71,向上计数模式,计数周期为5000,使能自动重载模式。

    TIM2:

    TIM3:

    (7)配置中断

    如下图所示,开启定时器2和定时器3的中断。

    (8)配置USART

    选择Connectivity,点开USART1,Mode选择异步通信Asynchronous 

    (9)配置时钟

    (10)项目配置

    然后创建工程项目。

    (二)keil代码的编译

    (1)定时器

    	HAL_TIM_Base_Start_IT(&htim2);
    	HAL_TIM_Base_Start_IT(&htim3);
    

    该函数表示启动相应的定时器,“h”表示HAL库,“tim2”表示定时器2。所以这行代码的意思就是启动定时器2和定时器3。

    (2)串口通信

    	uint8_t hello[20]="hello windows!\r\n";
    

    (3)定时器中断回调函数

    void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
    {
    	static uint32_t time_cnt =0;
    	static uint32_t time_cnt3 =0;
    	if(htim->Instance == TIM2)
    	{
    		if(++time_cnt >= 400)
    		{
    			time_cnt =0;
    			HAL_GPIO_TogglePin(GPIOA,GPIO_PIN_1);
    		}
    	}
    	if(htim->Instance == TIM3)
    	{
    		if(++time_cnt3 >= 1000)
    		{
    			time_cnt3 =0;
        HAL_UART_Transmit(&huart1,hello,20,100000);
    		}
    			
    	}
    }
    

    该函数为定时器的中断回调函数,当产生定时中断的时候,会自动调用这个函数。在函数内部定义了定时器的一个静态变量:time_cnt与定时器3 的time_cnt3。
    例如time_cnt,当它大于等于100的时候,才会执行if里面的代码。也就是说需要发生400次中断,才会让LED的状态翻转。前面已经算过了,一次定时中断的时间是0.005秒,所以400次中断的时间是0.005400=2秒。也就是说每隔2秒,LED的状态翻转一次。

    (三)成果展示

    (1)任务一:实际成果演示

    (2)任务二:串口输出

    四、PWM输出完成呼吸灯

    (一)Stm32 Cube Mx创建项目工程

    (1)新建项目项

    (2)选择芯片

    (3)配置RCC

    点System Cor,选择RCC,在右侧弹出的菜单栏中选Crystal/Ceramic Resonator

    (4)配置SYS

    选择调试接口,点System Cor,选择SYS。,在右侧弹出的菜单栏中选Serial Wire。

    (5)配置定时器3和定时器4

    这里我们选择定时器3和定时器4来实现定时的功位置3,分频系数为71,向上计数模式,计数周期为500,使能自动重载模式。通道1选择:PWM Generation CH1(PWM输出通道1)
    设置分频系数为71,计数周期为500,其它默认。
    设置占空比初始值为10。

    定时器4

    我们也选择PWM Generation CH1(PWM输出通道1),计数周期根据自己需要进行设置

    (6)时钟配置

    (7)项目设置

    (8)创建工程项目

    (二)keil代码编译

     (1)设置占空比

    打开工程,主要修改main.c文件。首先定义一个变量,用来存储占空比:初值设为10。

    uint16_t duty_num3 = 10;
    uint16_t duty_num4 = 10;
    

    (2)开启PWM信道

  • 开始TIM3的通道3,输出PWM。
  • 开始TIM4的通道4,输出PWM。
  • 	HAL_TIM_PWM_Start(&htim3,TIM_CHANNEL_1);
    	HAL_TIM_PWM_Start(&htim4,TIM_CHANNEL_1);
    

    (3)调用代码

    这里我们设置为每隔50毫秒,占空比加10,如果超过500(也就是PWM周期),自动变成0。(即灯会从亮倒暗,逐渐变化)

      while (1)
      {
        /* USER CODE END WHILE */
     HAL_Delay(50);
    		duty_num3 = duty_num3 + 10;
    			duty_num4 = duty_num4 + 10;
    		if(duty_num3 > 500)
    		{
    			duty_num3 = 0;
    		}
    		__HAL_TIM_SetCompare(&htim3,TIM_CHANNEL_1,duty_num3);
    			if(duty_num4 > 500)
    		{
    			duty_num4 = 0;
    		}
    		__HAL_TIM_SetCompare(&htim4,TIM_CHANNEL_1,duty_num4);
        /* USER CODE BEGIN 3 */
      }
      /* USER CODE END 3 */
    }
    

    (三)成果展示

    (1)实际成果展示

                                                           

    (2)PWM输出波形

    五、总结与体会

            定时器在 STM32 中犹如一个精准的时钟管理者。它基于内部时钟源,通过设置预分频器和自动重装载寄存器的值来确定计数频率和周期。例如,对于一个系统时钟为 72MHz 的 STM32 芯片,若要设置一个合适的计数频率以实现 5 秒和 2 秒的定时,需要精心计算预分频器的值。以 5 秒定时器为例,若选择合适的预分频使计数频率为 1Hz(即每秒计数一次),那么自动重装载寄存器的值设置为 5 即可实现 5 秒的定时。这一过程让我对定时器的计数机制和时间控制原理有了透彻的理解,不再局限于以往简单的循环延时或 delay 函数那种粗略的时间控制方式。

           通过本次实验,在 STM32 定时器的应用方面取得了显著的进步。不仅掌握了定时器的多种配置方式和应用场景,如多任务并发控制和 PWM 信号生成,还提高了自己的硬件调试能力和问题解决能力。在未来的学习和实践中,可以进一步探索定时器在更复杂系统中的应用,如电机控制中的精确调速、多传感器数据采集的定时触发等。同时,也意识到在嵌入式开发中,深入理解硬件原理和软件算法的结合是构建高效、稳定系统的关键所在。这次实验为我今后深入学习嵌入式系统开发奠定了坚实的基础,也激发了我进一步探索 STM32 更多功能和应用的热情。

    作者:森林里的林

    物联沃分享整理
    物联沃-IOTWORD物联网 » STM32-定时器与PWM

    发表回复