stm32f4矩阵按键代码
#include "key.h"
#include "delay.h"
#include "sys.h"
unsigned char Y1,Y2,Y3,Y4;
void Key_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);//使能GPIOB时钟
GPIO_InitStructure.GPIO_Pin = X1_GPIO_PIN | X2_GPIO_PIN | X3_GPIO_PIN | X4_GPIO_PIN | Y1_GPIO_PIN | Y2_GPIO_PIN | Y3_GPIO_PIN | Y4_GPIO_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;//普通输出模式
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100MHz
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉
GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化GPIO
GPIO_ResetBits(GPIOB,X1_GPIO_PIN | X2_GPIO_PIN | X3_GPIO_PIN | X4_GPIO_PIN | Y1_GPIO_PIN | Y2_GPIO_PIN | Y3_GPIO_PIN | Y4_GPIO_PIN);//GPIOF9,F10设置高,灯灭
}
int Key_Scan(void)
{
u8 KeyVal = KEY_ERR;
static u8 key_down = 0;
GPIO_SetBits(X1_GPIO_PORT,X1_GPIO_PIN); //先让X1输出高
GPIO_SetBits(X2_GPIO_PORT,X2_GPIO_PIN); //先让X2输出高
GPIO_SetBits(X3_GPIO_PORT,X3_GPIO_PIN); //先让X3输出高
GPIO_SetBits(X4_GPIO_PORT,X4_GPIO_PIN); //先让X4输出高
if ((GPIO_ReadInputDataBit(Y1_GPIO_PORT,Y1_GPIO_PIN)==1) || (GPIO_ReadInputDataBit(Y1_GPIO_PORT,Y2_GPIO_PIN)==1) || (GPIO_ReadInputDataBit(Y1_GPIO_PORT,Y3_GPIO_PIN)==1) || (GPIO_ReadInputDataBit(Y1_GPIO_PORT,Y4_GPIO_PIN)==1))
{
delay_ms(10);//去抖动
if ((GPIO_ReadInputDataBit(Y1_GPIO_PORT,Y1_GPIO_PIN)==1) || (GPIO_ReadInputDataBit(Y1_GPIO_PORT,Y2_GPIO_PIN)==1) || (GPIO_ReadInputDataBit(Y1_GPIO_PORT,Y3_GPIO_PIN)==1) || (GPIO_ReadInputDataBit(Y1_GPIO_PORT,Y4_GPIO_PIN)==1))
{
if (key_down == 0)
{
key_down = 1; //重复按标志位
GPIO_SetBits(X1_GPIO_PORT,X1_GPIO_PIN);
GPIO_ResetBits(X2_GPIO_PORT,X2_GPIO_PIN);
GPIO_ResetBits(X3_GPIO_PORT,X3_GPIO_PIN);
GPIO_ResetBits(X4_GPIO_PORT,X4_GPIO_PIN);
Y1=GPIO_ReadInputDataBit(Y1_GPIO_PORT,Y1_GPIO_PIN);
Y2=GPIO_ReadInputDataBit(Y2_GPIO_PORT,Y2_GPIO_PIN);
Y3=GPIO_ReadInputDataBit(Y3_GPIO_PORT,Y3_GPIO_PIN);
Y4=GPIO_ReadInputDataBit(Y4_GPIO_PORT,Y4_GPIO_PIN);
if(Y1==1&&Y2==0&&Y3==0&&Y4==0)
KeyVal=4;
if(Y1==0&&Y2==1&&Y3==0&&Y4==0)
KeyVal=8;
if(Y1==0&&Y2==0&&Y3==1&&Y4==0)
KeyVal=12;
if(Y1==0&&Y2==0&&Y3==0&&Y4==1)
KeyVal=16;
/**************************************************/
GPIO_ResetBits(X1_GPIO_PORT,X1_GPIO_PIN);
GPIO_SetBits(X2_GPIO_PORT,X2_GPIO_PIN);
GPIO_ResetBits(X3_GPIO_PORT,X3_GPIO_PIN);
GPIO_ResetBits(X4_GPIO_PORT,X4_GPIO_PIN);
Y1=GPIO_ReadInputDataBit(Y1_GPIO_PORT,Y1_GPIO_PIN);
Y2=GPIO_ReadInputDataBit(Y2_GPIO_PORT,Y2_GPIO_PIN);
Y3=GPIO_ReadInputDataBit(Y3_GPIO_PORT,Y3_GPIO_PIN);
Y4=GPIO_ReadInputDataBit(Y4_GPIO_PORT,Y4_GPIO_PIN);
if(Y1==1&&Y2==0&&Y3==0&&Y4==0)
KeyVal=3;
if(Y1==0&&Y2==1&&Y3==0&&Y4==0)
KeyVal=7;
if(Y1==0&&Y2==0&&Y3==1&&Y4==0)
KeyVal=11;
if(Y1==0&&Y2==0&&Y3==0&&Y4==1)
KeyVal=15;
/**************************************************/
GPIO_ResetBits(X1_GPIO_PORT,X1_GPIO_PIN);
GPIO_ResetBits(X2_GPIO_PORT,X2_GPIO_PIN);
GPIO_SetBits(X3_GPIO_PORT,X3_GPIO_PIN);
GPIO_ResetBits(X4_GPIO_PORT,X4_GPIO_PIN);
Y1=GPIO_ReadInputDataBit(Y1_GPIO_PORT,Y1_GPIO_PIN);
Y2=GPIO_ReadInputDataBit(Y2_GPIO_PORT,Y2_GPIO_PIN);
Y3=GPIO_ReadInputDataBit(Y3_GPIO_PORT,Y3_GPIO_PIN);
Y4=GPIO_ReadInputDataBit(Y4_GPIO_PORT,Y4_GPIO_PIN);
if(Y1==1&&Y2==0&&Y3==0&&Y4==0)
KeyVal=2;
if(Y1==0&&Y2==1&&Y3==0&&Y4==0)
KeyVal=6;
if(Y1==0&&Y2==0&&Y3==1&&Y4==0)
KeyVal=10;
if(Y1==0&&Y2==0&&Y3==0&&Y4==1)
KeyVal=14;
/**************************************************/
GPIO_ResetBits(X1_GPIO_PORT,X1_GPIO_PIN);
GPIO_ResetBits(X2_GPIO_PORT,X2_GPIO_PIN);
GPIO_ResetBits(X3_GPIO_PORT,X3_GPIO_PIN);
GPIO_SetBits(X4_GPIO_PORT,X4_GPIO_PIN);
Y1=GPIO_ReadInputDataBit(Y1_GPIO_PORT,Y1_GPIO_PIN);
Y2=GPIO_ReadInputDataBit(Y2_GPIO_PORT,Y2_GPIO_PIN);
Y3=GPIO_ReadInputDataBit(Y3_GPIO_PORT,Y3_GPIO_PIN);
Y4=GPIO_ReadInputDataBit(Y4_GPIO_PORT,Y4_GPIO_PIN);
if(Y1==1&&Y2==0&&Y3==0&&Y4==0)
KeyVal=1;
if(Y1==0&&Y2==1&&Y3==0&&Y4==0)
KeyVal=5;
if(Y1==0&&Y2==0&&Y3==0&&Y4==1)
KeyVal=13;
if(Y1==0&&Y2==0&&Y3==1&&Y4==0)
KeyVal=9;
}
}
}
else
{
key_down = 0; //没有检测到有按键按下,则让连按标志位归0
}
return KeyVal;
}
void Key_Test(void)
{
int num;
num = Key_Scan();
switch(num)
{
case KEY_ERR:break;
case 0: printf("0\r\n"); break;
case 1: printf("1\r\n"); break;
case 2: printf("2\r\n"); break;
case 3: printf("3\r\n"); break;
case 4: printf("4\r\n"); break;
case 5: printf("5\r\n"); break;
case 6: printf("6\r\n"); break;
case 7: printf("7\r\n"); break;
case 8: printf("8\r\n"); break;
case 9: printf("9\r\n"); break;
case 10: printf("10\r\n"); break;
case 11: printf("11\r\n"); break;
case 12: printf("12\r\n"); break;
case 13: printf("13\r\n"); break;
case 14: printf("14\r\n"); break;
case 15: printf("15\r\n"); break;
}
}
#ifndef _KEY_H
#define _KEY_H
#include "usart.h"
#include "sys.h"
#define uint unsigned int
#define uchar unsigned char
//8个引脚 4个为行 4个为列
//行输出端口定义
#define X1_GPIO_PORT GPIOB
#define X2_GPIO_PORT GPIOB
#define X3_GPIO_PORT GPIOB
#define X4_GPIO_PORT GPIOB
//列输入端口定义
#define Y1_GPIO_PORT GPIOB
#define Y2_GPIO_PORT GPIOB
#define Y3_GPIO_PORT GPIOB
#define Y4_GPIO_PORT GPIOB
//行输出引脚定义
#define X1_GPIO_PIN GPIO_Pin_5
#define X2_GPIO_PIN GPIO_Pin_6
#define X3_GPIO_PIN GPIO_Pin_7
#define X4_GPIO_PIN GPIO_Pin_8
//列输入引脚定义
#define Y1_GPIO_PIN GPIO_Pin_11
#define Y2_GPIO_PIN GPIO_Pin_12
#define Y3_GPIO_PIN GPIO_Pin_13
#define Y4_GPIO_PIN GPIO_Pin_14
//行输出时钟定义
#define X1_RCC RCC_APB2Periph_GPIOB
#define X2_RCC RCC_APB2Periph_GPIOB
#define X3_RCC RCC_APB2Periph_GPIOB
#define X4_RCC RCC_APB2Periph_GPIOB
//列输入时钟定义
#define Y1_RCC RCC_APB2Periph_GPIOB
#define Y2_RCC RCC_APB2Periph_GPIOB
#define Y3_RCC RCC_APB2Periph_GPIOB
#define Y4_RCC RCC_APB2Periph_GPIOB
//移植代码只需要修改上面的端口和引脚和时钟即可,下面的代码不用修改。
//矩阵键盘所用的8个引脚可连续可不连续,看实际需要和个人爱好自己定义。
#define KEY_ERR 255
void Key_Init(void);
int Key_Scan(void);
void Key_Test(void) ;
#endif