按键头文件:
uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
#ifndef __anjian_H
#define __anjian_H
#include <system.h>
void anjian_Init(void);
#define KEY_UP_Pin GPIO_Pin_0 //定义引接
#define KEY_DOWN_Pin GPIO_Pin_3
#define KEY_LEFT_Pin GPIO_Pin_4
#define KEY_RIGHT_Pin GPIO_Pin_2
#define KEY_Port (GPIOE) //定义接口
#define KEY_UP_Port (GPIOA)
#define KEY_UP PAin(0) //位带操作读IO
#define KEY_DOWN PEin(3)
#define KEY_LEFT PEin(4)
#define KEY_RIGHT PEin(2)
#define UP 0
#define DOWN 1
#define LEFT 2
#define RIGHT 3
/*
#define readKeyUp GPIO_ReadInputDataBit(KEY_UP_Port, KEY_UP_Pin)//读IO库函数
#define readKeyDown GPIO_ReadInputDataBit(KEY_Port, KEY_DOWN_Pin)
#define readKeyLeft GPIO_ReadInputDataBit(KEY_Port, KEY_LEFT_Pin)
#define readKeyRight GPIO_ReadInputDataBit(KEY_Port, KEY_RIGHT_Pin)
*/
#endif
按键源文件:
```c
#include "anjian.h"
void anjian_Init()
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOE,ENABLE); //时钟使能
GPIO_InitStructure.GPIO_Pin = KEY_UP_Pin;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;
GPIO_Init(KEY_UP_Port,&GPIO_InitStructure); //KEY_UP_Pin
GPIO_InitStructure.GPIO_Pin = KEY_DOWN_Pin|KEY_LEFT_Pin|KEY_RIGHT_Pin;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(KEY_Port,&GPIO_InitStructure); //KEY_Pin
}
主函数:
#include "led.h"
#include "stm32f4xx.h"
#include "system.h"
#include "sysTick.h"
#include "anjian.h"
//mode = 0单次扫描
//mode = 1连续扫描
u8 keyscan(u8 mode)
{
static u8 key = 1;
if(mode == 0){
key = 1;
}
if(key == 1 && (KEY_UP == 1 || KEY_LEFT == 0 || KEY_DOWN == 0|| KEY_RIGHT == 0)){
myDelay_ms(10);
key = 0;
if(KEY_UP == 1){
return UP;
}else if(KEY_LEFT == 0){
return LEFT;
}else if(KEY_DOWN == 0){
return DOWN;
}else if(KEY_RIGHT == 0){
return RIGHT;
}
}else if(KEY_UP == 0 && KEY_LEFT == 1 && KEY_DOWN == 1 && KEY_RIGHT == 1){
key = 1;
}
return 0;
}
int main()
{
u8 i;
u8 key;
led_Init();
SysTick_Init(168);
anjian_Init();
// LED1 = 0;
// LED2 = 0;
while(1){
key = keyscan(0);
switch(key){
// case UP:
// for(i=0;i<5;i++){
// LED1 = 0;
// LED2 = 1;
// myDelay_ms(500);
// LED1 = 1;
// LED2 = 0;
// myDelay_ms(500);
// }
//
// break;
case DOWN:
LED2 = 0;
break;
case LEFT:
LED2 = 0;
break;
case RIGHT:
LED1 = 1;
LED2 = 1;
break;
}
}
}
按键连续扫描与单次扫描:
当选择为单次扫描的mode= 0模式的时候,key一直是1,当进入按键按下时,第一个if会将可以置0,只有按键松开时的第二个if才会将key置1,因此当按键按下去之后必须要松开按键之后key才会恢复为1,才有进去按键扫描的条件。相当于使用静态key=1来将第一个if钳住;
当选择连续扫描的mode= 1模式时每次进入扫描函数时key的值都是1,不收静态变量控制。
//mode = 0单次扫描
//mode = 1连续扫描
u8 keyscan(u8 mode)
{
static u8 key = 1;
if(mode == 0){
key = 1;
}
if(key == 1 && (KEY_UP == 1 || KEY_LEFT == 0 || KEY_DOWN == 0|| KEY_RIGHT == 0)){
myDelay_ms(10);
key = 0;
if(KEY_UP == 1){
return UP;
}else if(KEY_LEFT == 0){
return LEFT;
}else if(KEY_DOWN == 0){
return DOWN;
}else if(KEY_RIGHT == 0){
return RIGHT;
}
}else if(KEY_UP == 0 && KEY_LEFT == 1 && KEY_DOWN == 1 && KEY_RIGHT == 1){
key = 1;
}
return 0;
}