10-CubeMx+Keil+Proteus仿真STM32 - PWM

本文例子参考《STM32单片机开发实例——基于Proteus虚拟仿真与HAL/LL库》
源代码:https://github.com/LanLinnet/STM32F103R6

项目要求

实现呼吸灯的效果:D1为长亮LED,D2为呼吸灯,通过PWM的方式实现D2亮→灭→亮→灭……的渐变效果,一次变化周期为1秒。

硬件设计

  1. 第一节的基础上,在Proteus中添加电路如下图所示。其中我们还添加了一个示波器OSCILLOSCOPE。

  2. PWM(Pulse Width Modulation, 脉冲宽度调制)技术就是对固定周期脉冲波形的高电平宽度进行调节,在一个脉冲周期内高电平持续时间所占的比例我们称之为占空比。高电平不同,脉冲信号波形的平均电压不同,脉冲信号波形的平均电压与占空比D、电平电压U之间的关系为:\(\overline U=DU\)。PWM可以用于直流电动机调速、开关电源、LED亮度调节等领域。在这里我们就是利用PWM对LED灯的亮度进行调节,从而实现呼吸灯的效果。

  3. 时钟频率采用默认的8MHz,我们不妨设置PSC为79,ARR为99,那么此时可以计算出TIM3的计数脉冲周期为\(T_{CNT}\)为10\(\mu s\),定时器一次溢出时间\(T_{OUT}\)为1ms。
    还需要计算PWM信号的占空比:如图所示,定时器从0开始向上计数到ARR的值,溢出后自动复位开始新一轮计数。我们只需要设定CCRx寄存器的值,当定时器计数值在0-CCRx时,PWM信号输出有效电平,当定时器计数值在CCRx-ARR之间时翻转电平……周而复始,那么CCRx的值就决定了PWM信号的占空比。

  4. 打开CubeMX,建立工程,我们在本项目中采用定时器3。普通定时器TIM3的4路PWM输出通道TIM3_CH1~TIM3_CH4分别对应PC6-PC9引脚,我们将PC6配置为GPIO_Output,用于驱动长亮LED,将PC7配置为TIM3_CH2,使能TIM3-CH2的PWM信号输出功能,由PC7驱动呼吸灯。

    随后对定时器进行设置:点击“Categories”中的“Timer”列表,选中“TIM3”。在“TIM3 Mode and Configuration”窗口中设置“Clock Source”为Internal Clock,Channel2设置为PWM Generation CH2,设置“PSC”为79,“Counter Period”为99

    随后进行通道2的PWM信号生成设置“PWM Generation Channel 2”:设置Mode为PWM mode 1(即当当前计数值<CRRx时输出有效电平),设置“CH Polarity”为Low(即有效电平为低电平)。

    接下来点击“Clock Configuration”进入时钟配置界面,这里我们采用默认设定的8MHz。

  5. 点击“Generator Code”生成Keil工程。

软件编写

  1. 本次我们需要实现PWM输出实现呼吸灯效果,需要用到PWM相关函数,其API文档如下:
    HAL_TIM_PWM_Start 定时器运行并输出PWM函数

    宏定义__HAL_TIM_SET_COMPARE 给定时器设定通道x的捕获比较寄存器(CRRx)的值,该宏定义可以在“stm32f1xx_hal_tim.h”文件中找到

  2. 点击“Open Project”在Keil中打开工程,双击“main.c”文件。

  3. 首先我们需要在main函数中初始化并运行定时器3 通道2 PWM函数的输出。
    我们首先在main.c文件的main函数中初始化定时器。

    /* USER CODE BEGIN 2 */
    HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_2);  //定时器2运行并在通道2输出PWM函数
    /* USER CODE END 2 */
    

    然后,在while(1)中插入代码如下,不断设定PWM输出的占空比,从而实现呼吸灯的效果

    /* USER CODE BEGIN WHILE */
    while (1)
    {
      uint8_t i;  //循环变量
      for(i=0; i<=100; i+=4)  //一次循环时间  100/4*20ms = 500ms  渐弱
      {
        __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_2, i);  //赋予定时器TIM3的CRR2寄存器的值为i
        HAL_Delay(20);
      }
      for(i=100; i>=0; i-=4)  //一次循环时间  100/4*20ms = 500ms  渐强
      {
        __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_2, i);  //赋予定时器TIM3的CRR2寄存器的值为i
        HAL_Delay(20);
      }
    /* USER CODE END WHILE */
    
    /* USER CODE BEGIN 3 */
    }
    /* USER CODE END 3 */
    

联合调试

  1. 点击运行,生成HEX文件。
  2. 在Proteus中加载相应HEX文件,点击运行,LED灯1长亮,LED灯2呈现呼吸灯灯状态。观察示波器,可以看到通道B波形的占空比不断改变,且占空比不同的时候,LED灯2的亮度也不同。
    占空比为0,LED灯2不亮

    占空比较小,LED灯2亮度低

    占空比较大,LED灯2亮度高
posted @ 2022-05-12 10:48  Sheepeach  阅读(2468)  评论(0编辑  收藏  举报