10-CubeMx+Keil+Proteus仿真STM32 - PWM
本文例子参考《STM32单片机开发实例——基于Proteus虚拟仿真与HAL/LL库》
源代码:https://github.com/LanLinnet/STM32F103R6
项目要求
实现呼吸灯的效果:D1为长亮LED,D2为呼吸灯,通过PWM的方式实现D2亮→灭→亮→灭……的渐变效果,一次变化周期为1秒。
硬件设计
-
在第一节的基础上,在Proteus中添加电路如下图所示。其中我们还添加了一个示波器OSCILLOSCOPE。
-
PWM(Pulse Width Modulation, 脉冲宽度调制)技术就是对固定周期脉冲波形的高电平宽度进行调节,在一个脉冲周期内高电平持续时间所占的比例我们称之为占空比。高电平不同,脉冲信号波形的平均电压不同,脉冲信号波形的平均电压与占空比D、电平电压U之间的关系为:\(\overline U=DU\)。PWM可以用于直流电动机调速、开关电源、LED亮度调节等领域。在这里我们就是利用PWM对LED灯的亮度进行调节,从而实现呼吸灯的效果。
-
时钟频率采用默认的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信号的占空比。
-
打开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。
-
点击“Generator Code”生成Keil工程。
软件编写
-
本次我们需要实现PWM输出实现呼吸灯效果,需要用到PWM相关函数,其API文档如下:
HAL_TIM_PWM_Start 定时器运行并输出PWM函数
宏定义__HAL_TIM_SET_COMPARE 给定时器设定通道x的捕获比较寄存器(CRRx)的值
,该宏定义可以在“stm32f1xx_hal_tim.h”文件中找到
-
点击“Open Project”在Keil中打开工程,双击“main.c”文件。
-
首先我们需要在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 */
联合调试
- 点击运行,生成HEX文件。
- 在Proteus中加载相应HEX文件,点击运行,LED灯1长亮,LED灯2呈现呼吸灯灯状态。观察示波器,可以看到通道B波形的占空比不断改变,且占空比不同的时候,LED灯2的亮度也不同。
占空比为0,LED灯2不亮
占空比较小,LED灯2亮度低
占空比较大,LED灯2亮度高