STM32按键设计一之扫描

按键扫描原理

  • 按键扫描即扫描IO口电平状态,来判断按键是否按下。当按键按下时,IO口电平发生改变。
  • 由于按键在按下过程中,按键内部簧片接触过程中会出现很短暂的电平不稳定状态,一般需要去抖。方式有两种,第一种物理去抖,第二种软件去抖。本篇采用软件去抖,即5~10ms的延时。

扫描程序

  • 在key.h中进行引脚宏定义
/* key0 define */
#define KEY0                            PEin(4)
#define KEY0_GPIO_Pin                   GPIO_Pin_4
#define KEY0_GPIO_Port                  GPIOE
#define KEY0_RCC_APB2Periph_CLK         RCC_APB2Periph_GPIOE

/* key1 define */
#define KEY1                            PEin(3)
#define KEY1_GPIO_Pin                   GPIO_Pin_3
#define KEY1_GPIO_Port                  GPIOE
#define KEY1_RCC_APB2Periph_CLK         RCC_APB2Periph_GPIOE

/* key_up define */
#define WK_UP                           PAin(0)
#define KEY_UP_GPIO_Pin                 GPIO_Pin_0
#define KEY_UP_GPIO_Port                GPIOA
#define KEY_UP_RCC_APB2Periph_CLK       RCC_APB2Periph_GPIOA
  • 定义枚举值,用于扫描返回值
typedef enum _KEY_STA_t KEY_STA_t;
enum _KEY_STA_t
{
    KEY0_PRESS = 1,
    KEY1_PRESS,
    WK_UP_PRESS
};
  • 在key.c中进行按键的IO口定义
/**
 * @name: KEY_GPIO_Init
 * @description: KEY 初始化 
 * @param {*}
 * @return {*}
 */
void KEY_GPIO_Init(void)
{
    GPIO_InitTypeDef GPIO_InitStruct;

    RCC_APB2PeriphClockCmd(KEY0_RCC_APB2Periph_CLK | KEY_UP_RCC_APB2Periph_CLK, ENABLE);

    GPIO_InitStruct.GPIO_Pin = KEY0_GPIO_Pin;
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU;
    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_2MHz;
    GPIO_Init(KEY0_GPIO_Port, &GPIO_InitStruct);

    GPIO_InitStruct.GPIO_Pin = KEY1_GPIO_Pin;
    GPIO_Init(KEY1_GPIO_Port, &GPIO_InitStruct);

    GPIO_InitStruct.GPIO_Pin = KEY_UP_GPIO_Pin;
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPD;
    GPIO_Init(KEY_UP_GPIO_Port, &GPIO_InitStruct);
}
  • 按键扫描函数定义
/**
 * @name: KEY_Scan
 * @description: 按键扫描
 * @param {u8} mode mode=0 表示开启连按; mode=1 表示不能连按;
 * @return {*}
 */
u8 KEY_Scan(u8 mode)
{
    static u8 key_up = 1;
    if(mode) key_up = 1;
    if(KEY0 == 1 && KEY1 == 1 && WK_UP == 0)
    {
        key_up = 1;
    }
    if(key_up && (KEY0 == 0  || KEY1 == 0 || WK_UP == 1))
    {
        delay_ms(10);
        if(KEY0 == 0 || KEY1 == 0 || WK_UP == 1)
        {
            key_up = 0;
            if(KEY0 == 0) return KEY0_PRESS;
            if(KEY1 == 0) return KEY1_PRESS;
            if(WK_UP == 1) return WK_UP_PRESS;
        }
    }
    return 0;
}

按键扫描运行

  • 在main.c中调用
int main(void)
{
	uint8_t key_sta = 0;
	uint32_t t = 0;

	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	initSysTick();
	Usart1_Init(115200);
	LED1_Init();
	LED2_Init();
	KEY_GPIO_Init();

	printf("Init Hardware OK ... \n");

	for(;;)
	{
		t++;
		if(t >= 2000)
			t = 0;

		/* 按键开关程序 */
		key_sta = KEY_Scan(0);
		if(key_sta == KEY0_PRESS)
		{
			LED1_Open();
			printf("key0 press! \n");
		}
		if(key_sta == KEY1_PRESS)
		{
			LED1_Close();
			printf("key1 press! \n");
		}

		/* 系统正常指示灯 */
		if(0 == t % 100)	
		{
			LED2_Toggle();
		}
	}
}
  • 程序运行结果,串口中的显示
    在这里插入图片描述


喜欢请点个赞哦,谢谢!欢迎指正

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值