一、硬件设计

按键KEY_UP连接带芯片的PA0引脚上,KEY_UP按键另一端是接在3.3V上,按下时输入到芯片管脚即为高电平。

按键KEY0、KEY1、KEY2分别连接在芯片的PE4、PE3、PE2引脚上

KEY0、KEY1、KEY2按键另一端是全部接在GND上,按下时输入到芯片管脚即为低电平

结论:只需轮询检测各个引脚的高低电平状态来判断按键是否有操作

KEY_UP – 下拉输入

        默认低电平 — 高电平 — 低电平

KEY0/1/2 – 上拉输入

        默认高电平 — 低电平 — 高电平

二、按键抖动

由于机械点的弹性作用,按键开关在闭合时不会马上稳定的接通,在断开时也不会一下子断开,因而在闭合和断开的瞬间均伴随着一连串的抖动。

按键消抖就是先读取按键的状态,如果得到按键按下之后,延时10ms,再次读取按键状态,如果按键还是按下状态,那么说明按键已经按下。其中延时10ms就是软件消抖处理。

三、函数实现

按键点灯

//key.h
#ifndef _KEY_H
#define _KEY_H

#include "stm32f10x.h"
#include "system.h"

#define KEY0_PIN GPIO_Pin_4 //key0引脚
#define KEY1_PIN GPIO_Pin_3 //key1
#define KEY2_PIN GPIO_Pin_2 //key2
#define KEYUP_PIN GPIO_Pin_0//keyup

#define KEY_PORT GPIOE//KEY0按键引脚属于E组
#define KEYUP_PORT GPIOA

#define KEY0 PEin(4)//KEY0 - GPIOE4 - 引脚高低电平由外设控制
#define KEY1 PEin(3)
#define KEY2 PEin(2)
#define KEYUP PAin(0)

#define KEY0_PRESS 1//KEY0按键的键值
#define KEY1_PRESS 2
#define KEY2_PRESS 3
#define KEYUP_PRESS 4 

extern void KEY_Init(void);//初始化函数
extern u8 KEY_Scan(void);//扫描,判断按键是否按下


#endif
//exti.c
#include "exti.h"
#include "led.h"
#include "beep.h"
#include "systick.h"
#include "key.h"

void My_Exti_Init(void){
	//定义EXTI结构体,用于配置EXTI控制器
	EXTI_InitTypeDef EXTI_Config;
	NVIC_InitTypeDef NVIC_Config;
	//使能AFIO时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
	//将KEY0按键的引脚GPIOE4映射到EXTI4中断线
	GPIO_EXTILineConfig(GPIO_PortSourceGPIOE,GPIO_PinSource4);
	GPIO_EXTILineConfig(GPIO_PortSourceGPIOE,GPIO_PinSource3);
	GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,GPIO_PinSource0);
	//配置EXTI工作参数
	EXTI_Config.EXTI_Line = EXTI_Line4|EXTI_Line3;
	EXTI_Config.EXTI_Mode = EXTI_Mode_Interrupt;
	EXTI_Config.EXTI_Trigger = EXTI_Trigger_Falling;
	EXTI_Config.EXTI_LineCmd = ENABLE;
	EXTI_Init(&EXTI_Config);
	
	EXTI_Config.EXTI_Line = EXTI_Line0;
	EXTI_Config.EXTI_Mode = EXTI_Mode_Interrupt;
	EXTI_Config.EXTI_Trigger = EXTI_Trigger_Rising;
	EXTI_Config.EXTI_LineCmd = ENABLE;
	EXTI_Init(&EXTI_Config);
	
	//配置NVIC工作参数
	NVIC_Config.NVIC_IRQChannel = EXTI4_IRQn;
	NVIC_Config.NVIC_IRQChannelPreemptionPriority = 2;
	NVIC_Config.NVIC_IRQChannelSubPriority = 0;
	NVIC_Config.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&NVIC_Config);
	
	NVIC_Config.NVIC_IRQChannel = EXTI3_IRQn;
	NVIC_Config.NVIC_IRQChannelPreemptionPriority = 2;
	NVIC_Config.NVIC_IRQChannelSubPriority = 1;
	NVIC_Config.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&NVIC_Config);
	
	NVIC_Config.NVIC_IRQChannel = EXTI0_IRQn;
	NVIC_Config.NVIC_IRQChannelPreemptionPriority = 2;
	NVIC_Config.NVIC_IRQChannelSubPriority = 2;
	NVIC_Config.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&NVIC_Config);
}

//自定义EXTI4中断处理函数 - 按键控制LED2开关
void EXTI4_IRQHandler(void){
	//判断是否由EXTI4触发中断
	if(EXTI_GetITStatus(EXTI_Line4) == SET){
		delay_ms(10);
		if(KEY0==0)
			LED2=!LED2;
	}
	//清除中断到来标志位,否则一直有中断
	EXTI_ClearITPendingBit(EXTI_Line4);
}

void EXTI3_IRQHandler(void){
		if(EXTI_GetITStatus(EXTI_Line3) == SET){
		delay_ms(10);
		if(KEY1==0)		
			BEEP_On();
	}
	//清除中断到来标志位,否则一直有中断
	EXTI_ClearITPendingBit(EXTI_Line3);
}

void EXTI0_IRQHandler(void){
		if(EXTI_GetITStatus(EXTI_Line0) == SET){
		delay_ms(10);
		if(KEYUP==1)
			BEEP_Off();
	}
	//清除中断到来标志位,否则一直有中断
	EXTI_ClearITPendingBit(EXTI_Line0);
}
#include "key.h"
#include "systick.h"

void KEY_Init(void){
	GPIO_InitTypeDef GPIO_Config;
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE,ENABLE);
	GPIO_Config.GPIO_Pin = KEY0_PIN|KEY1_PIN|KEY2_PIN;
	GPIO_Config.GPIO_Mode = GPIO_Mode_IPU;
	//GPIO_Config.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(KEY_PORT,&GPIO_Config);

	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	GPIO_Config.GPIO_Pin = KEYUP_PIN;
	GPIO_Config.GPIO_Mode = GPIO_Mode_IPD;
	GPIO_Init(KEYUP_PORT,&GPIO_Config);
} 
//定义按键扫描函数
u8 KEY_Scan(void){  
	//ispressed=0按键没按下
	//ispressed=1按键按下
	static u8 ispressed = 0;
	if(((KEY0==0)||(KEYUP==1)||(KEY1==0)||(KEY2==0))&&(ispressed==0)){
		delay_ms(10);//消除抖动  
		ispressed=1;
		if(KEY0==0)
			return KEY0_PRESS;//返回KEY0按键的键值1
		else if(KEY1==0)
			return KEY1_PRESS;
		else if(KEY2==0)
			return KEY2_PRESS;
		else if(KEYUP==1)
			return KEYUP_PRESS;
	}else if(KEY0==1||KEY1==1||KEY2==1||KEYUP==0){//表示按键松开
		ispressed=0;
	}
	return 0;
}

作者:春析

物联沃分享整理
物联沃-IOTWORD物联网 » STM32按键输入操作详解

发表回复