目录
1. 实验任务
利用STM32CubeMX,创建MDK工程,实现按键控制LED。学习在STM32CubeMX框架下自建硬件驱动文件的方法。
2. 硬件原理
1) 指示灯 DS0、 DS1分别连接到PA8和PD2.
2) 3个按键: KEY0、 KEY1 和 KEY_UP,分别连接到PA13、PA15、PA0。
3. 利用STM32CubeMX创建MDK工程
选择File下的New Project:
选择芯片类型(本文为stm32f103RBt6),选择下边的item,然后Start Project:
点击左侧的System Core下的SYS,将Debug设置为Serial Wire:
配置时钟:将RCC下的HSE设置为Crystal/Ceramic Resonator
结合开发版的硬件电路,进行GPIO设置
选择GPIO,依次将PA8、PD2设置为GPIO_Output,3个按键对应的IO口设置为输入,KEY0、 KEY1 和 KEY_UP,分别连接到PA13、PA15、PA0。
KEY0(PA13)和KEY1(PA15)是低电平有效的,而WK_UP(PA0)是高电平有效的,需要将PA13、PA15、PA0设置为GPIO_Input,在STM32内部设置上下拉:
个IO口设置后的参见见上图。
结合开发版的硬件电路,选择Clock Configuration,做如下配置:
项目配置:
在Project Manager下的Project中设置工程名称和工程路径,并选择编译软件。取消勾选Use lastest available version,选择其他版本:
代码生成设置:
在Code Generate中选择第二个,然后Generate Code,即生成代码:
可以打开MDK工程编辑了。
4.在MDK中自建驱动库的工程设置
点击上图中的Open Floder,打开工程文件夹。在工程文件夹内部新建“BSP” 文件夹:
在BSP文件夹内建立新文件夹,命名为“Key”:
在MDK-ARM中,点击File\New… 依次新建两个空白文件:
分别将其命名为key.c和key.h,将其保存在“... \04KeyBeep\BSP\Key”内:
点击菜单栏中的“Project\Manage\ Project Items…”,或者点击工具栏中的品字形按钮(见下图中的①),在Groups选项中创建驱动文件的工作目录,取名为“BSP”,见下图:
提示:课程中后续的用户自建驱动库均保存在本文件夹,以后的范例不会如此详细阐述,相关内容请到本节参考。
添加文件步骤见下图:
添加文件后效果图:
执行完上述步骤后,在左侧的Project项目框中,可以看到BSP项目和Key.c文件:
Include目录设置:
点击工具栏中的魔法棒按钮,选择C++选项,在
在打开的对话框中添加BSP文件夹,步骤见下图:
完成后的效果如下:
连续点击OK,回到主界面。
5.代码编辑
5.1 键盘处理程序:
5.1.1 key.c程序
由于按键初始化程序已经由STM32CubeMX生成,因此可以直接编写功能代码,在key.c文件中输入如下程序:
#include "key.h"
uint8_t KEY_Scan(uint8_t mode)
{
static uint8_t key_up=1; //按键松开标志
if(mode==1)key_up=1; //支持连按
if(key_up&&(KEY0==0||KEY1==0||WK_UP==1))
{
HAL_Delay(10);
key_up=0;
if(KEY0==0) return KEY0_PRES;
else if(KEY1==0) return KEY1_PRES;
else if(WK_UP==1) return WKUP_PRES;
}
else if
(KEY0==1&&KEY1==1&&WK_UP==0)key_up=1;
return 0; //无按键按下
}
代码说明:
KEY_Scan函数用来扫描这3个IO口是否有按键按下。通过设置mode参数,该函数支持两种扫描方式:
(1)当mode为0的时候,KEY_Scan函数将不支持连续按,扫描某个按键,该按键按下之后必须要松开,才能第二次触发,否则程序不会再响应该按键。方式可以防止按一次键多次触发,但是不能实现长按功能。
(2)当mode为1的时候,KEY_Scan函数支持连续按,如果某个按键一直按下,则会一直返回该按键的键值,实现长按检测。
特别说明:
该函数的按键扫描是有优先级的,最优先的是KEY0,然后是KEY1,最后是WK_UP按键。该函数有返回值,有按键按下是返回非0值,没有按键按下或者按键不正确时,返回0。
5.1.2 key.h程序
在key.h文件中输入如下程序:
#ifndef __KEY_H
#define __KEY_H
#include "main.h"
//宏定义
#define KEY0 HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_13) //KEY0 按键 PA13
#define KEY1 HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_15) //KEY1 按键 PA15
#define WK_UP HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0) //WKUP 按键 PA0
#define KEY0_PRES 1
#define KEY1_PRES 2
#define WKUP_PRES 3
uint8_t KEY_Scan(uint8_t mode);
#endif
5.2 main函数修改
打开Keil文件后,点击Application,在 main.c 文件里的 while(1) 循环内的
/* USER CODE BEGIN Includes */
和
/* USER CODE END Includes */
之间添加以下代码:
注意:添加头文件时,一定要输入路径!
在 main.c 文件里的 while(1) 循环内的
/* USER CODE BEGIN 3 */
和
/* USER CODE END 3 */
之间添加以下代码:
编译工程,直到输出0个错误:
再次提示:
由于MDK5.37版本以后,不在默认安装AC5,由最新版的STM32CubeMX生成的MDK代码,默认编译器是采用的Version 5。因此,如果您使用的5.37以上版本的MDK,请将编译器设置为Version 6,方法如下:
如果你需要AC5编译器,请参考如下博文安装设置:
Keil MDK5.37以上版本自行添加AC5(ARMCC)编译器的方法_armcc下载:
https://blog.youkuaiyun.com/qcmyqcmy/article/details/125814461
6.调试与验证
如果您需要虚拟仿真调试,请参考专栏如下博文的5.1节:
基础篇003. 使用STM32CubeMX创建MDK工程,实现流水灯的仿真与下载验证:
https://blog.youkuaiyun.com/qcmyqcmy/article/details/129159801
如果您需要在Proteus中仿真调试,请参考本专栏的博文:
基础篇004. 采用Proteus + STM32CubeMX + MDK-ARM学习流水灯:
https://blog.youkuaiyun.com/qcmyqcmy/article/details/129250108
将程序下载到开发板进行验证:
7.总结