目录
3.4 时钟树设置(Clock Configuration)
前言
文章为记录个人学习HAL库的成果,使用的芯片型号为:STM32F103C8T6,使用辅助软件:CubeMx,学习的视频来源于B站up主成电应电科协,主讲老师为漆强,视频的BV号为:BV1y7411m7gg
一、PWM是什么?
PWM是Pulse Width Modulation的缩写,中文意思是脉冲宽度调制,简称脉宽调制。PWM就是一个调节脉宽的东西,调节脉宽就可以控制电压。脉宽所控制电压的原理是:一个周期内高电平所占该周期的比值,就比如如果输入电压为5V,高电平在一个周期内所持续的时间为20%,这时候输出电压就等效为:5V*20%=1V,这个例子中20%的由来为:(一个周期内)高电平持续时间/一个周期的时间,这个式子对最终输出电压有明显的影响,其有特殊的意义,因此这个式子(高电平持续时间/一个周期的时间)就被命名为占空比。调节脉冲宽度,也就是调节占空比,可以达到的效果是改变输出的电压。
二、呼吸灯实现的原理
PWM实现LED呼吸灯亮度调节的原理是基于LED灯对电流的瞬时响应以及人眼的视觉暂留效应。
1. LED灯的快速响应
LED灯作为半导体器件,对电流的变化响应非常快。当PWM信号为高电平时(二极管导通,有电流流过),LED灯获得足够的电流以发光;当PWM信号为低电平时(二极管截至,无电流流过),LED灯几乎没有电流通过,因此不发光。由于LED的响应时间非常短,它几乎可以立即响应电流的变化。
2. 人眼的视觉暂留效应
人眼在观察快速变化的图像时,具有一种称为“视觉暂留”的生理现象。即当光信号快速闪烁时,人眼并不会立即感知到这种闪烁,而是会将多个短暂的光信号在视觉上进行平均或融合,从而感知到一个平均的亮度水平。
结合以上两点,当PWM信号的占空比(即高电平时间与整个周期时间的比例)发生变化时,虽然LED灯实际上是在不断地开关(即发光和不发光之间快速切换),但由于人眼的视觉暂留效应,我们感知到的是一个平均的亮度。占空比越高,LED灯在一个周期内发光的时间越长,因此平均亮度越高;占空比越低,平均亮度越低。
注:电流的大小控制LED灯的亮度。对非线性元件二极管(LED为发光二极管)来说,调节占空比,即控制高电平和低电平的持续时间可以控制二极管的导通和截至的时间,导通时有电流流过,截至时无电流流过。PWM调节输出电压的例子类似,调节占空比也可以使得电流流过的大小变化:假设输出电流为5A,占空比为20%,此时等效输出电流为:5A*20%=1A。因此调节占空比越大,LED灯越亮。
三、参数设置
1. 实现的要求
在STM32F103C8T6单片机的A0引脚上实现LED的双向呼吸灯(灯的亮度变化:暗 -> 亮 -> 暗),设置PWM周期为20ms,占空比从0%开始,步进为20%。递增到100%后,再逐级减为0%,并重复整个过程。
2. 设计思路
占空比从0%开始,因此写入捕获/比较寄存器CCR的初值为0,然后再while循环中调用宏函数__HAL_TIM_SET_COMPARE修改CCR的内容,从0开始,逐渐增加到200(根据公式Duty=(CCR)/(ARR+1)可以得出CCR为200),步进值为40。
3. CubeMx配置
3.1 选择芯片型号
打开CubeMx软件:
在搜索框中输入芯片型号“STM32F103C8”,并选择该型号:
3.2 System Core配置
点击“SYS”,将Debug选择为“Serial Wire”,其余地方保持默认设置即可,不用更改。
点击“RCC”,将“High Speed Clock(HSE)”选择为“Crystal/Ceramic Resonator”,其余地方保持默认设置即可,不用更改。
3.3 Timer配置
利用定时器的通道一实现PWM功能,在Timers中点击“TIM2”,选择时钟资源“Clock Source”为内部时钟“Internal Clock”
选择通道1
根据公式可知:当我们想要以20ms改变PWM时,我们可以取PSC为7199,取ARR为199
由此就可以得到20ms的定时时间。因此,在PSC中填入7199,在ARR中填入199(捕获比较寄存器CCR的初始值为0,因此不用更改)
使能定时器2,点击“NVIC Settings”,勾选“Enabled”
3.4 时钟树设置(Clock Configuration)
点击“Clock Configuration”,将框中的“8”修改为“72”,然后按下回车键,
在弹出来的框中选择“OK”
3.5 Project Manager设置
输入项目名称“PWM”,将“EWARM”改为“MDK-ARM”
版本更改为V5
点击“Code Generator”,勾选第二个框,然后点击“GENERATE CODE”生成代码
点击“Open Project”打开keil5
4. 代码编写
4.1 打开main文件
打开“PWM”文件夹,再打开其子文件夹“Application/User”,双击“main.c”,开始编写程序
4.2 将程序设置为自启动模式
点击菜单栏中的“魔术棒”
点击“Debug”,然后再点击“Settings”
点击“Flash Download”,勾选选项“Reset and Run”,再点击“确定”
4.3 代码部分
在“ /* USER CODE BEGIN PTD */ ”和 “ /* USER CODE END PTD */ ”之间添加代码“typedef unsigned char u8;”,将“unsigned char”修改为“u8”,用于方便后续书写。(不修改也行,如果不修改的话要把本文代码中的“u8”写成“unsigned char”)
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
typedef unsigned char u8;
/* USER CODE END PTD */
以数组的形式定义控制LED灯亮度的变量,使LED亮度变化为:暗 -> 亮 -> 暗;再定义用于锁定数组序列号的变量标志。在“ /* USER CODE BEGIN PV */ ”和“ /* USER CODE END PV */ ”之间添加“u8 DutyStep[] = {0,40,80,120,160,200,160,80,40,0},DutyStep_Index;”
/* USER CODE BEGIN PV */
u8 DutyStep[] = {0,40,80,120,160,200,160,80,40,0},DutyStep_Index;
/* USER CODE END PV */
开启定时器2的通道1输出PWM信号,在“ /* USER CODE BEGIN 2 */ ”和“ /* USER CODE END 2 */ ”之间添加“HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_1);”
/* USER CODE BEGIN 2 */
HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_1);
/* USER CODE END 2 */
每隔200ms(HAL_Delay)修改一次占空比,在“ /* USER CODE BEGIN 3 */ ”和“ /* USER CODE END 3 */ ”间添加代码。
/* USER CODE BEGIN 3 */
for(DutyStep_Index = 0;DutyStep_Index <= 9;DutyStep_Index++)
{
__HAL_TIM_SET_COMPARE(&htim2,TIM_CHANNEL_1,DutyStep[DutyStep_Index]);
HAL_Delay(200);
}
/* USER CODE END 3 */
总结
以上就是PWM控制LED双向呼吸灯的程序,通过学习,我学会了定时器的配置,理解了STM32和51单片机的相似点和不同点,STM32的HAL库可以用CubeMx进行初始化参数的配置,配置完后将会自动帮你生成代码,很方便,CubeMx有单片机的框图,可以知道哪些引脚被使用、用于什么功能,更直观。
参考文献
成电应电科协. (2020, March 24). 【STM32教程】入门教程(基于HAL库+CubeMX+MDK-ARM) [Video]. Retrieved from https://www.bilibili.com/video/BV1y7411m7gg?p=74
breeze0321. (2022, April 4). STM32F103c8t6 - CubeMX 快速实现时钟配置 - 最大72M时钟的设定及实验测试. CSDN博客. <https://blog.csdn.net/weixin_43604457/article/details/123262730>