[STM32H743]按键控制LED

正点原子开发板四个按键,两个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 */ }
原文地址:https://www.cnblogs.com/doitjust/p/14976847.html