使用STM32CubeMX配置工程+MDKARM编写代码实现LED灯的控制
如何使用STM32CubeMX配置工程实现LED灯的控制点灯是一个神秘、神奇而又神圣的事情,不管玩什么单片几把,第一件事情就是星星点灯。这就和不管学习什么编程语言,总是从“Hello Word!”开始一样。
硬件平台:正点原子STM32F407ZGT6探索者
一、LED
发光二极管,简称为LED,是一种常用的发光器件,通过电子与空穴复合释放能量发光。
从图上可以看出来,开发板采用的是灌电流的方法。
当引脚电平是低电平的时候,LED两侧形成电压差,可以发光。
当引脚电平是高电平的时候,LED两侧没有形成电压差,不发光。
低电平是灯亮,高电平是灯灭,负逻辑。
为什么要采取灌电流而不是拉电流?
单片机引脚的电流驱动能力有限。采用拉电流的方式也可以使LED亮,根据单片机的驱动能力和负载的参数来具体分析,如果驱动能力不足,采用拉电流的方式LED灯亮的效果则不如灌电流。
二、配置STM32CubeMX
点灯的操作,究其本质其实就是对IO口的一个输入输出操作。可以把这个看成一个开关,在C51里面是用0和1操作,代表引脚的通和断。
打开STM32CubeMX软件配置IO口
选择Pinout&Configuration
对右边的芯片引脚进行操作,在我用的板子上面LED灯位于PF9和PF10引脚上,对这两个引脚进行操作,左键单击对应的引脚。选择对应的工作方式,这里选择GPIO_Output(输出)。
然后对引脚定义标签(定义了标签以后,生成工程文件时候会将这个引脚宏定义,后面只需要对宏定义进行操作,而不必去细究底层)
我对这两个引脚定义了LED0和LED1的标签
然后是对引脚默认状态进行配置。
如果默认LED是关闭的。我们采取的灌电流的电路设计,所以默认要是高电平,这样单片机开机的时候LED灯是默认关闭的。
到这里,引脚配置就完成了。点击右上角的GENERATE就可以生成代码了。
三、引脚配置属性详解
虽然引脚已经配置完成了。但是对其他属性进行一波详细分析还是很有必要的。
这里共有5个可以设置的属性。类似于标准库当中,初始化IO口时要设置的结构体。
1.GPIO output level:可以设置GPIO初始的默认电平,有两个选项Low(第电平)和High(高电平)
2.GPIO mode:GPIO模式,设置推挽或者开漏。
推挽:输出高、驱动能力强。不可线与(会损坏器件)。
开漏:高电平没有驱动能力,需要借助外部上拉电阻才能真正输出高电平。可以实现线与。方便调节输出电平,适用于电平转换。
具体有关推挽或者开漏可以参考这些文章:
https://blog.csdn.net/qq_43732429/article/details/112755804
https://zhuanlan.zhihu.com/p/41942876
这里由于是控制LED,需要一定的输出能力,可以考虑推挽输出。
3.GPIO Pull-up/Pull-down:上拉或者下拉或者都没有。根据具体的电路情况决定。
提高电路稳定性,避免引起误动作。
提高输出管脚的带载能力。
4.Maximum output speed:最大IO输出速度:可选Low(慢)、Medium(中等)、High(高速)、Very High(超高速)。视具体情况选择IO速度。
5.User Label:引脚标签
四、MDK设置+代码编写
经过前面的一顿操作,STM32CubeMX为我们生成好了代码框架
要注意自己的代码一定要填写在
/* USER CODE BEGIN XXX*/
和
/* USER CODE END XXX*/
中间
按我个人的习惯,这会会去新建两个文件led.c和led.h但是由于考虑到这一点点小代码就单独写两个文件有点不合适,于是改成bit_oper.c和bit_oper.h后面把蜂鸣器等基础IO操作的功能往这里面写。
先是在工程目录下面新建一个文件夹,名字随便搞。
在这两个文件夹里面新建两个文件,bit_oprer.c和bit_oper.h
怎么建呢。。。有个方法是可以先新建两个记事本文件,然后重命名的时候把后缀改成.c和.h
然后回到MDK里面,在左侧的项目文件管理的地方也添加一个文件夹,名字和刚刚的文件夹一样(不一样也可以)。
添加文件后,要在MDK5的设置中添加这个编译路径
然后就可以开始写代码了。
双击打开bit_oper.c
#include "bit_oper.h"
然后在bit_oper.h处右键,打开.h文件
编写.h文件
#ifndef __BITOPER_H
#define __BITOPER_H
#include "main.h"
//LED0 control
//sink current 0-open,1-close
#define Led0_On HAL_GPIO_WritePin(LED0_GPIO_Port,LED0_Pin,GPIO_PIN_RESET)
#define Led0_Off HAL_GPIO_WritePin(LED0_GPIO_Port,LED0_Pin,GPIO_PIN_SET)
#define Led0_Toggle HAL_GPIO_TogglePin(LED0_GPIO_Port,LED0_Pin)
//LED1 control
#define Led1_On HAL_GPIO_WritePin(LED1_GPIO_Port,LED1_Pin,GPIO_PIN_RESET)
#define Led1_Off HAL_GPIO_WritePin(LED1_GPIO_Port,LED1_Pin,GPIO_PIN_SET)
#define Led1_Toggle HAL_GPIO_TogglePin(LED1_GPIO_Port,LED1_Pin)
#endif
这里用宏函数的方法,写了IO高低电平输出,IO电平翻转的函数。
HAL_GPIO_WritePin(IO端口,IO引脚,IO状态);是HAL库IO控制输出的函数
HAL_GPIO_TogglePin(IO端口,IO引脚);是HAL库的IO翻转的函数
STM32CubeMX在刚刚设置标签的时候就定义了对应的宏,所以在填入参数的时候就可以不用知道具体用了那个端口和哪个引脚。
只要输入对应的:标签_GPIO_Port,标签_GPIO_Pin就可以了。
配合MDK的代码补全功能,只需要输入标签就可以快速补全对应的宏
IO状态:分为GPIO_PIN_SET(高电平)、GPIO_PIN_RESET(低电平)
编写.c文件
#include "bit_oper.h"
void Led0_Light_N(uint16_t count,uint16_t time)//led0闪烁n次
{
for(int16_t i=0;i<count;i++)
{
Led0_On;
HAL_Delay(time);
Led0_Off;
HAL_Delay(time);
}
}
void Led1_Light_N(uint16_t count,uint16_t time)//led1闪烁n次
{
for(int16_t i=0;i<count;i++)
{
Led1_On;
HAL_Delay(time);
Led1_Off;
HAL_Delay(time);
}
}
稍微封装一下,实现一个闪烁的功能,led闪烁n次,入口参数是闪烁次数和闪烁时间(ms)
HAL_Delay();是HAL库提供的一个毫秒级别的延时函数。
接着回到.h文件把这两个函数声明一下。
void Led0_Light_N(uint16_t count,uint16_t time);
void Led1_Light_N(uint16_t count,uint16_t time);
回到main文件,打开main.h
把bit_oper.h引用一下
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "bit_oper.h"
/* USER CODE END Includes */
注意要将include添加到 USER BEGIN和END之间
前面将功能写了一下,具体实现要把函数放到main函数里面,或者放到while(1)循环里面。
这里为了测试功能暂时就不放while(1)里面。就放在外面只执行一次,
/* USER CODE BEGIN 2 */
Led0_Light_N(5,500);
Led1_Light_N(5,500);
/* USER CODE END 2 */
代码要放在 USER CODE BEGIN和END中间
这里实现的具体功能是LED0以500ms间隔闪烁5次,结束之后LED1以500ms间隔闪烁5次。
五、下载验证
代码写完了,就是下载验证。
在下载之前还要设置一下。我这里用的是ST-LINK,如果用J-LINK的朋友要改一下3左边的那个复选框。
到了这个位置,我突然想起了很久之前踩过的一个坑。
具体情况总结了一下写了一个帖子,如果有朋友也踩了这个坑可以看一下。
详细见:https://mp.csdn.net/mp_blog/creation/editor/122485658
回到STM32CubeMX
用4线调试的朋友这个一定要配置,不配置就GG了。如果踩了坑的朋友,可以尝试一下链接中的方法。
设置完点generate code,然后打开MDK5工程,下载程序
打开程序后,点击编译,然后下载验证功能实现。
到这里就结束了,感谢各位的浏览。
鄙人水平有限,很多地方写的感觉差强人意,如果有不对的地方欢迎指正。