目录
前言
上文我们实现了LED程序设计,本节进行KEY按键的程序设计,并结合上一节已经实现的LED程序设计进行KEY按键的测试。
1. 电路原理
通过查阅CT117E-M4产品手册的电路原理图,可以看到按键电路图,四个按键的引脚分别为PB1、PB0、PA0、PB2,当按键未按下时,引脚为高电平,当按键按下时,引脚为低电平。
2. 使用CubeMX进行源工程的配置
打开之前Source工程的.ioc文件,在Pinout View将PB1、PB0、PA0、PB2都设置为GPIO_Input。
随后点击GENERATE CODE来生成源工程代码。
3. 代码编程
3.1 预备工作
接下来我们分别在Test工程里创建Test\Test_Project\Src\BSP\KEY\bsp_key.c和Test\Test_Project\Inc\BSP\KEY\bsp_key.h文件,这就是我们后面要编写的中间层代码文件。打开Test_Project工程,进行文件Group的添加。
随后在bsp_key.c中依赖bsp_key.h文件
#include "KEY\bsp_key.h"
编译后可以看到在BSP文件夹下的效果。
3.2 bsp_key头文件编写
在bsp_key.h进行main.h的依赖以及按键初始化、按键扫描等函数的定义
#include "main.h"
void KEY_LED_Init(void);
unsigned char Key_Scan(void);
3.3 bsp_key源文件编写
3.3.1 按键初始化实现
在bsp_key.c的实现按键初始化、按键扫描等函数。我们粘贴Source工程的gpio.c的代码,实现按键的初始化。
void KEY_LED_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
/* GPIO Ports Clock Enable */
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_GPIOF_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
__HAL_RCC_GPIOD_CLK_ENABLE();
/*Configure GPIO pin : PA0 */
GPIO_InitStruct.Pin = GPIO_PIN_0;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/*Configure GPIO pins : PB0 PB1 PB2 */
GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
}
3.3.2 按键扫描实现
我们从电路图可以知道,若按键按下,则会接地,GPIO引脚就会为低电平,那么我们就通过判断引脚为低电平来扫描哪个按键被按下。
unsigned char Key_Scan(void)
{
unsigned char ucKey_Val = 0;
if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_0) == GPIO_PIN_RESET)
ucKey_Val = 1;
if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_1) == GPIO_PIN_RESET)
ucKey_Val = 2;
if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_2) == GPIO_PIN_RESET)
ucKey_Val = 3;
if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0) == GPIO_PIN_RESET)
ucKey_Val = 4;
return ucKey_Val;
}
3.4 main函数编写
3.4.1 定义用户变量
//变量声明
__IO uint32_t uwTick_Key_Set_Point;//按键减速
__IO uint32_t uwTick_Led_Set_Point;//LED减速
uint8_t ucKey_Val;//按键值
uint8_t ucKey_Down;//按键按下的键值
uint8_t ucKey_Up;//按键抬起的键值
uint8_t ucKey_Old;//上一次按键的值
uint8_t ucLed;//Led的值
3.4.2 定义函数
//***子函数声明区
void Led_Proc(void);
void Key_Proc(void);
实现Led_Proc(void),其中uwTick_Led_Set_Point为减速值,保证Led_Proc运行频率为10Hz。
void Led_Proc()
{
if((uwTick - uwTick_Led_Set_Point)<100)return;//减速处理
uwTick_Led_Set_Point = uwTick;
LED_Disp(ucLed);
}
实现Key_Proc(void),其中uwTick_Key_Set_Point为减速值,保证Key_Proc运行频率为10Hz。当按键4按下,ucLed = 0x88,当按键3按下,ucLed = 0x00。
void Key_Proc()
{
if((uwTick-uwTick_Key_Set_Point)<100)return;
uwTick_Key_Set_Point = uwTick;
ucKey_Val = Key_Scan();//4
ucKey_Down = ucKey_Val & (ucKey_Old ^ ucKey_Val);//4
ucKey_Up = ~ucKey_Val & (ucKey_Old ^ ucKey_Val);
ucKey_Old = ucKey_Val;
if(ucKey_Down == 4)
{
ucLed = 0x88;
}
if(ucKey_Down == 3)
{
ucLed = 0x00;
}
}
3.4.3 实现main函数
int main(void)
{
HAL_Init();
SystemClock_Config();
LED_Init();
Key_Init();
while (1)
{
Key_Proc();
Led_Proc();
}
}
4. 代码测试
4.1 测试按键4
按键4按下后,LD4、LD8亮起。
4.2 测试按键3
按键3按下后,LD全灭。