上一篇文章我们主要介绍了如何从STM32CubeMX中新建STM32CubeIDE的工程。今天我们将写下第一行点亮LED的代码,这几乎是每个入门嵌入式的人要实现的第一个功能。

一、LED如何才能点亮

首先我们要先了解如何才能点亮一个LED,LED又称为发光二极管,符号通常如下图所示,当给它正向电压(正极接高电平,负极接低电平)时,电流从正极流向负极,LED就会发光。

Image

现在我们拿出之前准备的RGB LED模块,可以看到GND就是这颗LED的负极。

这是颗RGB的LED,里面是有红(R)绿(G)蓝(B)三个小LED的,本应该有三个GND引脚的,但是这个模块将三个GND连在了一起,一般称这种方法为共阴极连接。

另外的三个引脚R、G、B就分别代表了红色、绿色、蓝色LED的正极。比如R连接到3.3V电源的正极,GND连接到负极,就可以点亮红色的LED。

Image

二、直接点亮LED

我们这里先直接给这个模块通电点亮LED,从而对于点亮LED有个直观的感受。3.3V电压就从我们之前准备的USB-UART模块中来取,如下图,可以看到最上面的引脚就是标有3.3V。

Image

取两根杜邦线,将USB-UART模块的3V3和RGB LED的模块和R相连,GND和GND相连,然后将USB连接到电脑的USB上,我们就可以看到红色的LED被点亮了。如下图所示,我是用白线连接USB-UART模块的3V3和RGB LED的模块的R,黑线连接的两个模块的GND。

Image

Image

Image

至此,我们已经完整的了解了如何点亮一个LED。当然同样的方法,3V3连接G会点亮绿灯,连接B会点亮蓝灯。

三、使用MCU点亮LED

我们现在知道了,GND连接到负极,然后在RGB LED模块的R、G、B引脚给一个3V3的电压就可以点亮LED。那我们现在使用MCU来点亮LED。如下图,是我们之前准备的MCU最小系统板。

Image

中间那颗黑色的芯片就是型号为STM32F030F4P6的MCU,我们可以看到它一共有20个引脚伸出来,并且连接到了外部的插针上。

为了方便识别MCU的引脚,会给每个引脚都编上号,就是我们看到的板子上的白色丝印标注的PA0、PA1……这些编号。这里我们直接选择PA0作为控制是否输出3.3V电压的引脚。

PA0这个引脚可以配置为GPIO(General-Purpose Input/Output,通用输入输出)功能。这里我们就是用它的输出(Output)功能,通过此此功能可以控制PA0来输出3.3V或者输出0V,当我们用程序控制这个PA0引脚输出3.3V的时候与其相连的LED就自然被点亮了,反之LED就会熄灭。

3.1 配置PA0引脚为GPIO的Output功能

打开我们上一篇文章建立的RGB_Led工程,找到RGB_Led的工程目录,双击.project打开,如下图

Image

弹出的STM32CubeIDE Launcher窗口直接点击Launch按钮即可。

Image

展开左侧的Project Explorer窗口中的工程,找到RGB_Led.ioc,直接双击打开,就会打开STM32CubeMX如下图所示

Image

打开后在Pinout & Configuration选项卡中,如下图所示,我们可以在画面中间看到MCU的示意图,如下图所示

Image

我们在PA0这个引脚的位置单击,会出现一个弹窗,从这个弹窗我们就可以知道这个引脚有好多功能,我们选择GPIO_Output这个功能。如下图所示

Image

选择后我们看到界面展现如下图的样子,PA0已经被配成了GPIO_Output功能。

Image

此时直接点击右上角的GNERATE CODE按钮,生成代码,如下图所示

Image

代码生成完成后,会出现生成代码成功的弹窗,如下图

Image

因为我们是先打开工程,然后进入到STM32CubeMX的,所以这里直接点击Close按钮即可,此时将PA0引脚配置成GPIO_Output的代码就已经生成了。

3.2 通过HAL_GPIO_WritePin函数控制PA0引脚输出的电压

我们在Project Explorer窗口中找到main.c文件,双击打开,其位于RGB_Led/Core/Src下,如下图所示

Image

在中间的代码编辑器中找到int main(void)这个函数(Function),如下图所示

Image

这里提到了函数,我们简单说一下这个概念。函数一词是在晚清时期随着西方科学的引入,由function翻译而来。我们最初接触这个词,应该都是在上学学习数学时,所以默认了函数好像就是数学中的函数。现在学习编程语言,又出现了函数这个词,因此经常会想到拿编程的函数和数学的函数做对比。

数学的函数和编程的函数在英文中都是function,但是function本身是一个含义比较广泛的词,除了数学中的“函数关系”,还有“功能、作用”的含义。

数学中的函数,更关注输入和输出之间的对应关系,比如输入一个x,通过某种规则计算得到一个y。

而编程中的函数,更偏向于function中“功能”的含义,可以理解成为了完成某种运算或者某种操作而组合在一起的一段代码。

所以简单理解,编程中的函数就像一个个实现具体功能的小模块,每个函数负责完成一件事情。

当程序越来越复杂时,我们就可以通过函数把一个大问题拆分成很多小问题,让整个程序更加清晰,也更加容易维护。

接下来我们直接插入一行控制PA0口输出高电平的代码:

HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_SET);

括号中的GPIOA代表了PA口,GPIO_PIN_0代表的PA口的0号引脚,GPIO_PIN_SET代表将PA0输出高电平,在我们的开发板中,高电平对应约3.3V。

插入的位置如下图所示,位于main函数的/* USER CODE BEGIN 2 */与/* USER CODE END 2 */之间。

Image

3.3 编译代码

上一篇文章中已经介绍了如何编译,我们直接点击小锤子图标,如下图

Image

在Console窗口中展示了编译结果,如下图

Image

0 errors,0 warnings,编译通过。

小结

到这里,我们已经完成了控制LED的软件部分,也成功生成了可以运行在MCU中的程序。

不过现在这个程序还停留在电脑中,STM32芯片并不知道我们写了这段代码。

那么如何把程序下载到芯片里?如何观察程序一步一步运行?

下一篇文章,我们继续认识嵌入式开发中非常重要的工具——调试器(Debugger)。

Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐