正点原子开发板四个按键,两个LED
原理图
完成功能:
WKUP按下,LED0和LED1互斥点亮;
KEY2按下,LED0翻转;
KEY1按下,LED1翻转;
KEY0按下,LED0和LED1都翻转;
bsp_key.c
1 #include "bsp_key.h" 2 3 4 /*************************************************************************************************************** 5 * 函数名称: KEY_GPIO_Init 6 * 函数功能: 按键引脚初始化 7 * 函数参数: GPIOx [in] GPIO端口 8 GPIO_Pin [in] GPIO引脚 9 * 函数返回: 0 成功 10 ***************************************************************************************************************/ 11 void KEY_GPIO_Init(void) 12 { 13 GPIO_InitTypeDef KEY_GPIO_Init; 14 15 __HAL_RCC_GPIOA_CLK_ENABLE(); //开启GPIOA时钟 16 __HAL_RCC_GPIOC_CLK_ENABLE(); //开启GPIOC时钟 17 __HAL_RCC_GPIOH_CLK_ENABLE(); //开始GPIOH时钟 18 19 KEY_GPIO_Init.Pin = GPIO_PIN_0 ; 20 KEY_GPIO_Init.Mode = GPIO_MODE_INPUT; 21 KEY_GPIO_Init.Pull = GPIO_PULLDOWN; 22 KEY_GPIO_Init.Speed = GPIO_SPEED_FREQ_LOW; 23 HAL_GPIO_Init(GPIOA, &KEY_GPIO_Init); 24 25 KEY_GPIO_Init.Pin = GPIO_PIN_13 ; 26 KEY_GPIO_Init.Pull = GPIO_PULLUP; 27 HAL_GPIO_Init(GPIOC, &KEY_GPIO_Init); 28 29 KEY_GPIO_Init.Pin = GPIO_PIN_2 | GPIO_PIN_3 ; 30 KEY_GPIO_Init.Pull = GPIO_PULLUP; 31 HAL_GPIO_Init(GPIOH, &KEY_GPIO_Init); 32 33 } 34 35 36 /*************************************************************************************************************** 37 * 函数名称: KEY_Scan 38 * 函数功能: 按键处理函数(阻塞) 39 * 函数参数: GPIOx [in] GPIO端口 40 GPIO_Pin [in] GPIO引脚 41 * 函数返回: 0 成功 42 ***************************************************************************************************************/ 43 unsigned char KEY_Scan(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin) 44 { 45 /* 判断按键是否按下 */ 46 if(GPIO_PIN_RESET == HAL_GPIO_ReadPin(GPIOx, GPIO_Pin)) 47 { 48 /*按键被按下*/ 49 while(GPIO_PIN_RESET == HAL_GPIO_ReadPin(GPIOx, GPIO_Pin)); 50 return 0; 51 }else if(GPIO_PIN_SET == HAL_GPIO_ReadPin(GPIOx, GPIO_Pin)) 52 { 53 while(GPIO_PIN_SET == HAL_GPIO_ReadPin(GPIOx, GPIO_Pin)); 54 return 1; 55 } 56 return 2; 57 } 58 59 /*************************************************************************************************************** 60 * 函数名称: KEY_Scan2 61 * 函数功能: 按键处理函数(非阻塞) 62 * 函数参数: mode [in] 模式 63 0-不支持连续按 必须松开后才可以进行第二次触发 64 1-支持连续按 若某按键一直按下,则每次扫描都会返回这个按键值 65 * 函数返回: 0-无按键按下 66 非0-按下的按键标志 67 68 * 函数备注: 响应优先级:KEY0>KEY1>KEY2>WK_UP 69 ***************************************************************************************************************/ 70 unsigned char KEY_Scan2(unsigned char mode) 71 { 72 static unsigned char key_up = 1; //按键松开标志 73 if(mode == 1) key_up = 1; //支持连续按 74 75 if(key_up && (KEY0==0 || KEY1==0 || KEY2 == 0 || WK_UP==1)) //按键松开时,检测到四个按键有按下 76 { 77 HAL_Delay(10); 78 key_up = 0; //更新按键状态标志为按下 79 80 //检测按键返回按键状态 81 if(KEY0==0) 82 return KEY0_PRES; 83 else if(KEY1==0) 84 return KEY1_PRES; 85 else if(KEY2==0) 86 return KEY2_PRES; 87 else if(WK_UP==1) 88 return WK_UP_PRES; 89 }else if(KEY0==1 && KEY1==1 && KEY2==1 && WK_UP==0) //扫描按键都松开时,更新按键状态标志为松开 90 { 91 key_up = 1; 92 } 93 return 0; 94 95 }
bsp_key.h
1 #ifndef __BSP_KEY_H 2 #define __BSP_KEY_H 3 4 #include "stm32h7xx_hal.h" 5 6 /* 读取各按键的电平 */ 7 #define KEY0 HAL_GPIO_ReadPin(GPIOH,GPIO_PIN_3) 8 #define KEY1 HAL_GPIO_ReadPin(GPIOH,GPIO_PIN_2) 9 #define KEY2 HAL_GPIO_ReadPin(GPIOC,GPIO_PIN_13) 10 #define WK_UP HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0) 11 12 /*按键按下后的返回值*/ 13 enum KEY_PRESS 14 { 15 KEY0_PRES = 1, 16 KEY1_PRES, 17 KEY2_PRES, 18 WK_UP_PRES 19 }; 20 21 /*************************************************************************************************************** 22 * 函数名称: KEY_GPIO_Init 23 * 函数功能: 按键引脚初始化 24 * 函数参数: GPIOx [in] GPIO端口 25 GPIO_Pin [in] GPIO引脚 26 * 函数返回: 0 成功 27 ***************************************************************************************************************/ 28 void KEY_GPIO_Init(void); 29 30 /*************************************************************************************************************** 31 * 函数名称: KEY_Scan 32 * 函数功能: 按键处理函数(阻塞) 33 * 函数参数: GPIOx [in] GPIO端口 34 GPIO_Pin [in] GPIO引脚 35 * 函数返回: 0 成功 36 ***************************************************************************************************************/ 37 unsigned char KEY_Scan(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin); 38 39 /*************************************************************************************************************** 40 * 函数名称: KEY_Scan2 41 * 函数功能: 按键处理函数(非阻塞) 42 * 函数参数: mode [in] 模式 43 0-不支持连续按 必须松开后才可以进行第二次触发 44 1-支持连续按 若某按键一直按下,则每次扫描都会返回这个按键值 45 * 函数返回: 0-无按键按下 46 非0-按下的按键标志 47 48 * 函数备注: 响应优先级:KEY0>KEY1>KEY2>WK_UP 49 ***************************************************************************************************************/ 50 unsigned char KEY_Scan2(unsigned char mode); 51 52 #endif
main.c
#include "main.h" #include "gpio.h" /* Private includes ----------------------------------------------------------*/ /* USER CODE BEGIN Includes */ #include "bsp_led.h" #include "bsp_key.h" /* USER CODE END Includes */ /* Private variables ---------------------------------------------------------*/ /* USER CODE BEGIN PV */ unsigned char ledsta[2]={1,1};//LED0和LED1的当前状态 /* USER CODE END PV */ int main(void) { //......
/* USER CODE BEGIN 2 */ LED_GPIO_Init(); KEY_GPIO_Init(); /* USER CODE END 2 */ /* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1) { /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ switch(KEY_Scan2(0)) { case WK_UP_PRES: //互斥点亮 ledsta[0] = !ledsta[0]; ledsta[1] = !ledsta[0]; break; case KEY2_PRES: //LED0翻转 ledsta[0] = !ledsta[0]; break; case KEY1_PRES: //LED1翻转 ledsta[1] = !ledsta[1]; break; case KEY0_PRES: //LED0和LED1都翻转 ledsta[0] = !ledsta[0]; ledsta[1] = !ledsta[1]; break; } LED0(ledsta[0]); //控制LED0 LED1(ledsta[1]); //控制LED1 } /* USER CODE END 3 */ }