战舰开发板V4——按键输入

战舰开发板V4——按键输入

image-20260730191128890

image-20260730195246471

#include "Key.h"
#include "Delay.h"

/**
 * @brief  按键初始化函数
 * @param  无
 * @retval 无
 */
void Key_Init(void)
{
	GPIO_InitTypeDef GPIO_Init_Struct;
	KEY0_GPIO_CLK_ENABLE();                            /* KEY0时钟使能 */
	KEY1_GPIO_CLK_ENABLE();                            /* KEY1时钟使能 */	
	KEY2_GPIO_CLK_ENABLE();                            /* KEY2时钟使能 */	
	WKUP_GPIO_CLK_ENABLE();                            /* WKUP时钟使能 */
                                                     
	GPIO_Init_Struct.Pin = KEY0_GPIO_PIN;              /* KEY0引脚 */
	GPIO_Init_Struct.Mode = GPIO_MODE_INPUT;           /* 输入 */
	GPIO_Init_Struct.Pull = GPIO_PULLUP;               /* 上拉 */
	GPIO_Init_Struct.Speed = GPIO_SPEED_FREQ_HIGH;     /* 高速 */
	HAL_GPIO_Init(KEY0_GPIO_PORT, &GPIO_Init_Struct);  /* KEY0引脚模式设置,上拉输入 */
	
	GPIO_Init_Struct.Pin = KEY1_GPIO_PIN;              /* KEY1引脚 */
	GPIO_Init_Struct.Mode = GPIO_MODE_INPUT;           /* 输入 */
	GPIO_Init_Struct.Pull = GPIO_PULLUP;               /* 上拉 */
	GPIO_Init_Struct.Speed = GPIO_SPEED_FREQ_HIGH;     /* 高速 */
	HAL_GPIO_Init(KEY1_GPIO_PORT, &GPIO_Init_Struct);  /* KEY1引脚模式设置,上拉输入 */
	
	GPIO_Init_Struct.Pin = KEY2_GPIO_PIN;              /* KEY2引脚 */
	GPIO_Init_Struct.Mode = GPIO_MODE_INPUT;           /* 输入 */
	GPIO_Init_Struct.Pull = GPIO_PULLUP;               /* 上拉 */
	GPIO_Init_Struct.Speed = GPIO_SPEED_FREQ_HIGH;     /* 高速 */
	HAL_GPIO_Init(KEY2_GPIO_PORT, &GPIO_Init_Struct);  /* KEY2引脚模式设置,上拉输入 */
	
	GPIO_Init_Struct.Pin = WKUP_GPIO_PIN;              /* WKUP引脚 */
	GPIO_Init_Struct.Mode = GPIO_MODE_INPUT;           /* 输入 */
	GPIO_Init_Struct.Pull = GPIO_PULLDOWN;             /* 下拉 */
	GPIO_Init_Struct.Speed = GPIO_SPEED_FREQ_HIGH;     /* 高速 */
	HAL_GPIO_Init(WKUP_GPIO_PORT, &GPIO_Init_Struct);  /* WKUP引脚模式设置,下拉输入 */
}

/**
 * @brief  按键扫描函数
 * @note   该函数有响应优先级(同时按下多个按键):WK_UP > KEY2 > KEY1 > KEY0 !!
 * @param  mode:0 / 1,具体含义如下:
 *	 @arg  0,不支持连续按(当按键按下不放时,只有第一次调用会返回值,
 *         必须松开以后,再次按下才会返回其他键值)
 *   @arg  1,支持连续按(当按键按下不放时,每次调用该函数都会返回键值)
 * @retval 键值,定义如下:
 *         KEY0_PRES, 1, KEY0按下
 *         KEY1_PRES, 2, KEY1按下
 *         KEY2_PRES, 3, KEY2按下
 *         WKUP_PRES, 4, WKUP按下
 */
uint8_t Key_Scan(uint8_t mode)
{
	static uint8_t Key_Up = 1;                                      /* 按键按松开标志 */
	uint8_t KeyVal = 0;
	
	if(mode)  Key_Up = 1;                                           /* 支持连按 */
	
	if(Key_Up && (KEY0 == 0 || KEY1 == 0 || KEY2 == 0 || WK_UP == 1)/* 按键松开标志为1,且有任意一个按键按下了  */
	{
		delay_ms(10);                                               /* 去抖动 */
		Key_Up = 0;
		
		if(KEY0 == 0)  KeyVal = KEY0_PRES;
		if(KEY1 == 0)  KeyVal = KEY1_PRES;	
		if(KEY2 == 0)  KeyVal = KEY2_PRES;
		if(WK_UP == 1) KeyVal = WKUP_PRES;
	}
	else if(KEY0 == 1 && KEY1 == 1 && KEY2 == 1 && WK_UP == 0)      /* 没有任何按键按下, 标记按键松开 */
	{
		Key_Up = 1;
	}
	
	return KeyVal;                                                  /* 返回键值 */
	
}

#ifndef __KEY_H
#define __KEY_H

#include "main.h"

/* 定义 引脚 */

#define KEY0_GPIO_PORT               GPIOE
#define KEY0_GPIO_PIN                GPIO_PIN_4
#define KEY0_GPIO_CLK_ENABLE()       do{ __HAL_RCC_GPIOE_CLK_ENABLE(); }while(0)   /* PE口时钟使能 */

#define KEY1_GPIO_PORT               GPIOE
#define KEY1_GPIO_PIN                GPIO_PIN_3
#define KEY1_GPIO_CLK_ENABLE()       do{ __HAL_RCC_GPIOE_CLK_ENABLE(); }while(0)   /* PE口时钟使能 */

#define KEY2_GPIO_PORT               GPIOE
#define KEY2_GPIO_PIN                GPIO_PIN_2
#define KEY2_GPIO_CLK_ENABLE()       do{ __HAL_RCC_GPIOE_CLK_ENABLE(); }while(0)   /* PE口时钟使能 */

#define WKUP_GPIO_PORT               GPIOA
#define WKUP_GPIO_PIN                GPIO_PIN_0
#define WKUP_GPIO_CLK_ENABLE()       do{ __HAL_RCC_GPIOA_CLK_ENABLE(); }while(0)   /* PA口时钟使能 */



#define KEY0          HAL_GPIO_ReadPin(KEY0_GPIO_PORT, KEY0_GPIO_PIN)   /* 读取KEY0引脚 */
#define KEY1          HAL_GPIO_ReadPin(KEY1_GPIO_PORT, KEY1_GPIO_PIN)   /* 读取KEY1引脚 */
#define KEY2          HAL_GPIO_ReadPin(KEY2_GPIO_PORT, KEY2_GPIO_PIN)   /* 读取KEY2引脚 */
#define WK_UP         HAL_GPIO_ReadPin(WKUP_GPIO_PORT, WKUP_GPIO_PIN)   /* 读取WKUP引脚 */


#define KEY0_PRES     1          /* KEY0按下 */
#define KEY1_PRES     2          /* KEY1按下 */
#define KEY2_PRES     3          /* KEY2按下 */
#define WKUP_PRES     4          /* KEY_UP按下(即WK_UP) */

void Key_Init(void);             /* 按键初始化函数 */
uint8_t Key_Scan(uint8_t mode);  /* 按键扫描函数 */


#endif

/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)   //无限主循环,程序主体在这里循环执行
{
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
    //循环内部,所有业务逻辑写这里
    Key = Key_Scan(0);                /* 得到键值 */
    if(Key)
    {
        switch(Key)
        {
            case WKUP_PRES:           /* 控制蜂鸣器 */
                BEEP_TOGGLE();        /* BEEP 状态取反 */
                break;
            case KEY2_PRES:           /* 控制LED0(RED)翻转 */
                LED0_TOGGLE();        /* LED0 状态取反 */
                break;
            case KEY1_PRES:           /* 控制LED1(GREEN)翻转 */
                LED1_TOGGLE();        /* LED1 状态取反 */
                break;
            case KEY0_PRES:           /* 同时控制LED0,LED1翻转 */
                LED0_TOGGLE();        /* LED0 状态取反 */
                LED1_TOGGLE();        /* LED1 状态取反 */
                break;
            default: break;
        }	
    }	
    else
    {
        delay_ms(10);
    }
}
posted @ 2026-07-30 22:26  Q&25  阅读(2)  评论(0)    收藏  举报