默认已经使用STM32cubeMX定义引脚并生成初始化代码
新建KEY_LED文件夹,在下面新建keyled.c和keyled.h文件
首先在keyled.h中定义LED操作的宏函数
引入函数:在stm32f4xx_hal_gpio.h中找到HAL_GPIO_ReadPin()和HAL_GPIO_TogglePin()函数,复制到keyled.h中,并替换void->#define
然后替换函数:用LED_R_Toggle()替换GPIO_TogglePin()函数,用LED_R_ON()替换HAL_GPIO_ReadPin()函数,用LED_R_OFF()替换HAL_GPIO_ReadPin()函数
接着替换函数参数:先定义函数 "main.h",然后在"main.h"中找到参数如下图,替换GPIO和Pin。用GPIO_PIN_SET,替换GPIO_PinState
最后加入宏编译指令#ifdef
Alt+↑将文本上移一行
Alt+/ 自动补全文件
Ctrl+F替换函数
#include "main.h"
#ifdef LED_R_Pin
#define LED_R_Toggle() HAL_GPIO_TogglePin(LED_R_GPIO_Port , LED_R_Pin);
#define LED_R_ON() HAL_GPIO_ WritePin(LED_R_GPIO_Port, LED_R_Pin, GPIO_PIN_SET);
#define LED_R_OFF() HAL_GPIO_ WritePin(LED_R_GPIO_Port, LED_R_Pin, GPIO_PIN_RESET);
#endif
#ifdef LED_G_Pin
#define LED_G_Toggle() HAL_GPIO_TogglePin(LED_G_GPIO_Port , LED_G_Pin);
#define LED_G_ON() HAL_GPIO_ WritePin(LED_G_GPIO_Port, LED_G_Pin, GPIO_PIN_SET);
#define LED_G_OFF() HAL_GPIO_ WritePin(LED_G_GPIO_Port, LED_G_Pin, GPIO_PIN_RESET);
#endif
#ifdef LED_B_Pin
#define LED_B_Toggle() HAL_GPIO_TogglePin(LED_B_GPIO_Port , LED_B_Pin);
#define LED_B_ON() HAL_GPIO_ WritePin(LED_B_GPIO_Port, LED_B_Pin, GPIO_PIN_SET);
#define LED_B_OFF() HAL_GPIO_ WritePin(LED_B_GPIO_Port, LED_B_Pin, GPIO_PIN_RESET);
#endif
在keyled.c中编写函数检测KEY是否按下
定义函数ScanPressedKey,while(1)死循环
引入HAL_GPIO_ReadPin(参数和LED 一样修改)读取引脚值,与GPIO_PIN_RESET相等
修改按键被按下的返回值,在keyled.h中定义为枚举类型
在hal.h中借用HAL_GetTick()函数获取系统滴答信号的计数值
在每一个while 循环的开始和结束调用函数,记录初始的信号值,和执行到最后的信号值,大于定义的时间就会认为按键已经弹起,跳出循环。
为减少毛刺,增加延迟。
最后将编写的函数添加到.h文件中
.h文件增加的代码
typedef enum
{
KEY_0=0,
KEY_1=1,
KEY_NONE,
}KEYS;
#define KEY_WAIT_ALWAYS 0
KEYS ScanPressedKey(uint32_t timeout);
.c文件的所有代码
#include "keyled.h"
KEYS ScanPressedKey(uint32_t timeout)//如果有某个函数的引脚被拉低,确实可以向这里返回0或者1
{
uint32_t tickstart=HAL_GetTick();
const uint32_t btnDelay=20;
while(1)
{
#ifdef KEY1_Pin
if(HAL_GPIO_ReadPin(KEY1_GPIO_Port, KEY1_Pin)==GPIO_PIN_RESET)
{
HAL_Delay(btnDelay);
if(HAL_GPIO_ReadPin(KEY1_GPIO_Port, KEY1_Pin)==GPIO_PIN_RESET)
return KEY_0;
}
#endif
#ifdef KEY2_Pin
if(HAL_GPIO_ReadPin(KEY2_GPIO_Port, KEY2_Pin)==GPIO_PIN_RESET)
{
HAL_Delay(btnDelay);
if(HAL_GPIO_ReadPin(KEY2_GPIO_Port, KEY2_Pin)==GPIO_PIN_RESET)
return KEY_1;
}
#endif
if(timeout!=KEY_WAIT_ALWAYS)
{
if((HAL_GetTick()-tickstart)>timeout)
break;
}
}
return KEY_NONE;
}
将KEY-LED添加到项目添加到项目的头文件搜索路径和源程序搜索路径
project->properties->C/C++General->Paths and Symbols
include->ADD输入KEY_LED
Source Location->ADD Folder选择KEY_LED文件夹
到此实现了MCU系统和外设的初始化
将在main.c的沙箱中编写代码
#include "keyled.h"
while (1)
{
KEYS curKey = ScanPressedKey(KEY_WAIT_ALWAYS);
switch(curKey)
{
case KEY_0:
LED_R_Toggle();
break;
case KEY_1:
LED_G_Toggle();
break;
default:
break;
}
HAL_Delay(200);
实现用户要求:按键1反转LED_R,按键2反转LED_G