支持抬起识别。可以修改支持短按按下识别,短按抬起识别,长按按下识别,长按抬起识别。
支持任何微处理器(MCU、ARM等)
先看电路图:
以下是源码:
void MatrixKeyScan(unsigned char ucKeyValue[4][4])
{
static unsigned char ucKeyState[4][4] = {KEY_STATE_0, KEY_STATE_0, KEY_STATE_0, KEY_STATE_0};
static unsigned char ucKeyTime[4][4] = {0, 0, 0, 0};
unsigned char ucKeyPress[4], i = 0, j = 0;
for(j = 0; j < 4; j++)
{
LineOutCtrl(j, SET);
for(i = 0; i < 4; i++)
{
ColumnScan(i, ucKeyPress);
//printf("\r\n %d %d %d", j, i, ucKeyPress[i]);
switch (ucKeyState[j][i])
{
case KEY_STATE_0:
if (!ucKeyPress[i])
{
ucKeyState[j][i] = KEY_STATE_1;
}
break;
case KEY_STATE_1:
if (!ucKeyPress[i])
{
ucKeyTime[j][i] = 0;
ucKeyState[j][i] = KEY_STATE_2;
}
else
{
ucKeyState[j][i] = KEY_STATE_0;
}
break;
case KEY_STATE_2:
if(ucKeyPress[i])
{
ucKeyState[j][i] = KEY_STATE_0;
}
else
{
ucKeyTime[j][i]++;
if(ucKeyTime[j][i] == 1)
{
ucKeyState[j][i] = KEY_STATE_3;
}
}
break;
case KEY_STATE_3:
if (ucKeyPress[i])
{
ucKeyValue[j][i] = (i + j * 4 + 1);
ucKeyState[j][i] = KEY_STATE_0;
}
else
{
}
break;
default:
break;
}
}
LineOutCtrl(j, RESET);
}
}
void ColumnScan(U8 Index, U8 *KeyPress)
{
switch(Index)
{
case 0:
if(GPIO_ReadInputDataBit(KEYIN1_PORT, KEYIN1_PIN) == RESET)
KeyPress[Index] = 0;//按下
else
KeyPress[Index] = 1;//抬起
break;
case 1:
if(GPIO_ReadInputDataBit(KEYIN2_PORT, KEYIN2_PIN) == RESET)
KeyPress[Index] = 0;
else
KeyPress[Index] = 1;
break;
case 2:
if(GPIO_ReadInputDataBit(KEYIN3_PORT, KEYIN3_PIN) == RESET)
KeyPress[Index] = 0;
else
KeyPress[Index] = 1;
break;
case 3:
if(GPIO_ReadInputDataBit(KEYIN4_PORT, KEYIN4_PIN) == RESET)
KeyPress[Index] = 0;
else
KeyPress[Index] = 1;
break;
default:
break;
}
//printf("\r\n %d %d", Index, KeyPress[Index]);
}
void LineOutCtrl(U8 Index, U8 en)
{
switch(Index)
{
case 0:
if(!en)
GPIO_SetBits(KEYOUT1_PORT, KEYOUT1_PIN);
else
GPIO_ResetBits(KEYOUT1_PORT, KEYOUT1_PIN);
break;
case 1:
if(!en)
GPIO_SetBits(KEYOUT2_PORT, KEYOUT2_PIN);
else
GPIO_ResetBits(KEYOUT2_PORT, KEYOUT2_PIN);
break;
case 2:
if(!en)
GPIO_SetBits(KEYOUT3_PORT, KEYOUT3_PIN);
else
GPIO_ResetBits(KEYOUT3_PORT, KEYOUT3_PIN);
break;
case 3:
if(!en)
GPIO_SetBits(KEYOUT4_PORT, KEYOUT4_PIN);
else
GPIO_ResetBits(KEYOUT4_PORT, KEYOUT4_PIN);
break;
default:
break;
}
}
#define KEYOUT1_PORT GPIOA
#define KEYOUT1_PIN GPIO_Pin_0
#define KEYOUT2_PORT GPIOA
#define KEYOUT2_PIN GPIO_Pin_1
#define KEYOUT3_PORT GPIOA
#define KEYOUT3_PIN GPIO_Pin_2
#define KEYOUT4_PORT GPIOA
#define KEYOUT4_PIN GPIO_Pin_3
#define KEYIN1_PORT GPIOA
#define KEYIN1_PIN GPIO_Pin_4
#define KEYIN2_PORT GPIOA
#define KEYIN2_PIN GPIO_Pin_5
#define KEYIN3_PORT GPIOA
#define KEYIN3_PIN GPIO_Pin_6
#define KEYIN4_PORT GPIOA
#define KEYIN4_PIN GPIO_Pin_7
#define KEY_STATE_0 0
#define KEY_STATE_1 1
#define KEY_STATE_2 2
#define KEY_STATE_3 3
#define KEY_STATE_4 4
#define N_KEY 0xFE
void Task_10ms(void)
{
static U8 ucCount = 0;
U8 ucKeyValue[4][4] = {
{N_KEY, N_KEY, N_KEY, N_KEY},
{N_KEY, N_KEY, N_KEY, N_KEY},
{N_KEY, N_KEY, N_KEY, N_KEY},
{N_KEY, N_KEY, N_KEY, N_KEY}
}, i = 0, j = 0;
MatrixKeyScan(ucKeyValue);
for(j = 0; j < 4; j++)
{
for(i = 0; i < 4; i++)
{
if(ucKeyValue[j][i] != N_KEY)
{
printf("\r\n ucKeyValue 测试计数:%d %d",ucCount++, ucKeyValue[j][i]);
}
}
}
}