STM32CubeIDE基础学习-LED闪烁实验
文章目录
- STM32CubeIDE基础学习-LED闪烁实验
- 前言
- 第1章 硬件介绍
- 第2章 新建工程
- 2.1 基础工程配置部分
- 2.2 工程外设配置部分
- 2.3 生成工程代码部分
- 2.4 输出HEX文件、编译下载
- 第3章 代码编写
- 3.1 方式1:IO翻转
- 3.2 方式2:调用函数
- 3.3 方式3:宏定义
- 第4章 实验现象
- 总结
前言
前面的文章已经介绍过STM32CubeIDE软件的基础功能使用以及新建工程的基本步骤流程了,本文章将重新从头演示一遍新建项目的整个过程步骤,从新建到实现LED的闪烁功能。
后面的文章将不会再新建工程了,后面的工程会直接用前面的工程作为模板进行添加使用。
STM32CubeIDE软件基础知识学习回顾
实验目的:
学习配置GPIO作为输出功能使用,从而实现控制LED每隔500ms交替闪烁功能。
第1章 硬件介绍
本实验使用的开发板是STM32F103C8T6主控芯片,核心原理图如下:
时钟来源使用的是外部高速8M晶振作为高速时钟。
LED灯的连接原理图如下图所示:
由上图硬件连接原理图可知,LED的阴极接到主控芯片的PA8引脚上,根据二极管的导通原理可知,只要端口输出低电平就可以驱动LED发光。
本实验只使用到LED实现闪烁的功能,配置GPIO为输出即可。
第2章 新建工程
2.1 基础工程配置部分
第一步:双击打开软件,进入主界面后点击Strat new STM32 project新建工程文件如下图所示:
或者按照下图的步骤点击新建工程:
第二步:接着会进入下图的芯片选择界面,这个实验使用的是STM32F103C8T6芯片,按照标号步骤进行选择即可,前面也介绍过这个芯片收藏的技巧了,现在直接点击左上角的星星,选择STM32F103C8T6芯片完成后点击Next:
第三步:点击Next后,进入下面的界面进行设置工程名称和路径,注意名字和路径都不能存在中文字符,如下图所示:
设置好后点击Next进入选择固件版本界面,默认是最新版本的,需要根据自己安装的固件包版本进行选择对应版本的芯片固件包,如果选择的和下载的不是相同的版本,则后面使用可能会存在问题的。选择完成然后点击Finish完成,如下图所示:
接着就可以进入外设功能配置界面了,如下图所示:
到此,前面部分的基础工程创建步骤就完成了,接下来就可以进行配置相关外设功能了。
2.2 工程外设配置部分
第一步:配置GPIO。
跟着标号顺序依次选择,如果找不到芯片需要的引脚,可以在右下角④处输入引脚名称进行搜索,可以看到上面芯片对应的引脚会出现黑色在闪烁的,然后点击该引脚进行选择需要配置的功能即可。
鼠标左键点击该引脚,选择对应需要配置的功能,这个LED闪烁实验使用的是选择输出功能就行。
当选择了这个芯片引脚的功能时,后面发现选错了,不需要它了而需要取消选择,那么可以再次点击该芯片所选择的功能,这样就可以取消选择了。
选择完成后提示如下图所示:
接着配置GPIO引脚工作模式,根据查看LED的硬件连接原理图可知,LED的正电极是接到3.3V的,另外一个负电极是接到芯片引脚上的,根据发光二极管的导通原理,则该芯片引脚给低电平就可以点亮LED了,如果上电不要点亮LED,则需要把该引脚状态初始化为高电平,配置如下图所示:
端口功能配置如下:
1、由于初始上电要LED熄灭,则需要配置初始化状态为高电平状态。
2、模式配置为推挽输出。
3、输出保持设置不用上下拉即可,也可以设置输出上拉,这里输出设置这个上下拉作用不是很大。
4、输出速度选择中速或低速都行,对于这个LED闪烁要求不是很大。
5、User Label建议定义一个自己喜欢见名知意的名字,方便写后续程序时查看和方便使用。
第二步:配置RCC时钟。
开发板使用的是外部高速时钟晶振的输入方式,如下图所示:
接着配置时钟树如下图,外部8M时钟输入,可以根据时钟的倍频因子和分频因子进行配置,如果觉得麻烦,可以直接在HCLK处输入需要的系统最高主频72M,直接点击键盘回车就行,软件就会自动进行配置的了。
按回车键后可以看到提示整个配置过程的提示进度条,耐心等待完成即可。
完成后具体时钟配置路线如下图所示:
如果是自己手动配置的,若出现红色的提示,则说明这个时钟不在规定范围内而警告的,则需要检查具体参数配置是否存在设置错了导致的。
第三步:配置调试接口。
Debug处选择Serial Wire,用的是串行两线SWD模式而不是JTAG模式,选择SWD模式可以节省IO的资源占用。如下图所示:
第四步:配置输出文件。
建议勾选工程生成输出独立的.c / .h文件,方便管理代码。如下图④处所示:
最后,主控芯片被配置的引脚功能如下图所示:
到此,整个工程需要配置的外设功能就全部配置完成了,接下来就可以生成代码工程进行代码编写了。
2.3 生成工程代码部分
可以按快捷键ALT+K,或者点击下面这个图标按钮生成代码工程,如下图所示:
点击后会提示下面图片提示信息,这个是需要打开整个视图显示的,显示左边的工程栏,如果需要显示,则选择Yes。
打开代码工程后最终会显示下图这样的代码:
接着就可以在上面添加自己需要实现的LED闪烁的功能代码了。
2.4 输出HEX文件、编译下载
进入代码工程后,先不要急着编写功能代码,可以先点击编译一下整个工程,查看工程代码是否会报错,如果没有报错就说明该工程是没有问题的,则可以进行代码编写了。不然如果在一开始的工程都有问题报错的话,后面写了比较多的代码就很难定位找问题了。
正常编译后,可以发现这个软件新建工程默认是没有输出HEX烧写文件的,那么就需要设置一下生成输出才行。操作步骤如下图所示:
按照标号步骤依次点击选择勾选生成HEX即可,如下图所示:
完成后点击Apply和Apply and Close,再一次编译就可以看见输出该HEX文件了。
工程文件夹输出后路径如下图所示:
工程输出后如下图所示:
工程第一次点击下载代码时可能会提示需要确认配置工程名和下载器的,如下图所示:
这里默认选择ST-LINK GDB server即可,下面接口选择SWD接口。
完成点击Apply,最后点击OK即可看到程序开始下载了,右下角可以看到具体下载进度条。
第3章 代码编写
HAL库能让LED闪烁的方法有很多,下面将列举常见的三种方法进行演示。
当初始生成代码时可以看到mian文件里面有一个代码框架,去掉注释如下所示:
#include "main.h"
#include "gpio.h"
void SystemClock_Config(void);
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
while (1)
{
}
}
时钟系统配置和GPIO初始化都是前面在STM32CubeMX里面配置生成的,可以进入函数里面看具体的定义是否和前面配置的一致。
main.c文件里面的系统时钟初始化配置代码如下图所示:
main.h文件里面还定义了由用户标签相关命名的宏定义,如下图所示:
注意:本人一般习惯使用全部采用大写方式的宏定义,这里是代码自动生成的,后面的代码将不会使用这里的宏,而是自己重新定义的宏。具体根据个人喜欢情况来使用,可以选择使用这里的,就不用在自己定义这么麻烦了。
GPIO初始化配置如下图所示:
端口初始化输出高电平、推挽输出、无上下拉、中速、用户标签是LED。与STM32CubeMX的配置一一对应,如下图所示:
后面的外设初始化代码都会存放在 MX_GPIO_Init() 函数里面的,直接到这里就可以看到所以引脚定义了。
所有引脚的宏定义就对应在main.h文件里面了。
3.1 方式1:IO翻转
这个IO翻转的方式非常简单,直接调用HAL库提供的端口翻转函数即可,如下图所示:
代码片示例如下:
HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_8); /* LED翻转 */
HAL_Delay(500); /* 延时500ms */
//前面生成代码时,是自动生成了一个用户标签的名字,可以直接使用,如下:
HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin); /* LED翻转 */
HAL_Delay(500); /* 延时500ms */
//在这里就可以体现出前面设置的User Label用户标签的好处作用了。
HAL_Delay这个延时函数是HAL库提供写好的,不用自己写了,当然,写一个属于自己的延时函数也是可以的。
3.2 方式2:调用函数
调用写端口函数,使用GPIOx_BSRR寄存器来操作引脚。调用如下图所示:
代码片示例如下:
HAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, GPIO_PIN_SET); /* 设置端口输出高电平 */
HAL_Delay(500); /* 延时500ms */
HAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, GPIO_PIN_RESET); /* 设置端口输出低电平 */
HAL_Delay(500); /* 延时500ms */
3.3 方式3:宏定义
采用宏定义的方式可以让代码移植起来、修改起来更方便、可观性更强。
简单的宏定义方式如下图所示:
这种宏定义的方式也就是间接的调用了HAL_GPIO_WritePin函数,只是做了相应的处理而已。
直接在define处进行宏定义即可,下次直接调用LED()就可以了,而不需要再次写HAL_GPIO_WritePin()这么长的函数及里面的参数了,免去了每次都传入参数这么麻烦的步骤。
这样写,只要给LED()传入参数是0或1就可以对应操作该端口的低 / 高电平了,使用起来非常的方便。
这里主要操作的是C语言里面的三目运算符和do…while()语句,熟练掌握这些就自然明白该段程序的执行过程了。
main函数的调用如下图所示:
代码片示例如下:
LED(1); /* 设置端口输出高电平,关闭LED */
HAL_Delay(500); /* 延时500ms */
LED(0); /* 设置端口输出高电平,打开LED */
HAL_Delay(500); /* 延时500ms */
到此,采用宏定义的方式代码就完成了,下载之后就可以看到LED闪烁了。
附加部分:
简单的方式成功实现之后,为了更好的管理代码,可以单独创建LED文件来存放这些功能代码了,前面的文章介绍了创建文件的方法步骤,这里就快速创建了,创建完成后如下图所示:
头文件:
把宏定义都剪切到头文件这里来,如下图所示:
main文件while里面的内容还是一样,没有变化,不用处理,但要注意包含头文件路径。如下图所示:
led.c文件里面暂时可以没有内容。
此时发现led.h文件里面的宏定义看起来还不是特别好,代码移植或者修改起来还是比较麻烦,需要修改的地方比较多,那么还可以进一步优化,让需要修改的代码尽量减少,添加完宏定义代码如下图所示:
注意:这里宏定义的名字根据个人的习惯喜欢来写就行,没有规定写什么内容,可以自己定义,也可以直接使用main.h里面的宏定义,也是可以的,我是为了操作习惯而统一写成大写的方式。
为了方便测试LED的功能,此时我在led.c文件里面可以添加了一个函数内容,单独写一个测试LED闪烁的函数。如下图所示:
由于用到了这些库函数,所以需要在这里或者led.h文件中把main.h引入到文件中才行,不然编译会报错提示找不到路径。
main里面调用如下图所示:
下载代码后,可以看下LED的执行现象。
第4章 实验现象
下载代码后,就可以看到板子的LED每隔500毫秒在交替闪烁了。
总结
以上就是常见的让LED闪烁的功能代码编写方式了,刚开始学习一般都是用前两个方式实现,后面的宏定义方式就比较常用于项目了,操作起来非常的方便。