4X4矩阵键盘扫描:

1. 4根行线的GIO均设为Output,根列线的GIO均设为Input;

2. 4根行线的GIO分别置为0111、1011、1101、1110,读逐一读取列线GIO的值,可确定是哪一个按键。

电路图例如以下:

4X4矩阵键盘扫描程序-LMLPHP

注意:

1. 图中用作输入的GIO,一定要有一个上拉电阻。

2. 芯片中的每个引脚是否用作了GPIO口来用。需配置芯片的寄存器,使引脚当作GPIO口来使用,才会有效。

測试代码例如以下:

#define KEY_GIO_ROW_1	37
#define KEY_GIO_ROW_2 33
#define KEY_GIO_ROW_3 32
#define KEY_GIO_ROW_4 35
#define KEY_GIO_COL_1 22
#define KEY_GIO_COL_2 23
#define KEY_GIO_COL_3 24
#define KEY_GIO_COL_4 36
int scanKey()
{
int keyValue = 0;
int col1Value=0,col2Value=0,col3Value=0,col4Value=0,row1Value=0,row2Value=0,row3Value=0,row4Value=0;
static int press1=0,press2=0,press3=0,press4=0;
static int press5=0,press6=0,press7=0,press8=0;
static int press9=0,press10=0,press11=0,press12=0;
static int press13=0,press14=0,press15=0,press16=0; dm365SetGPIO(KEY_GIO_ROW_1, 0);
dm365SetGPIO(KEY_GIO_ROW_2, 1);
dm365SetGPIO(KEY_GIO_ROW_3, 1);
dm365SetGPIO(KEY_GIO_ROW_4, 1);
col1Value = dm365GetGPIO(KEY_GIO_COL_1);
col2Value = dm365GetGPIO(KEY_GIO_COL_2);
col3Value = dm365GetGPIO(KEY_GIO_COL_3);
col4Value = dm365GetGPIO(KEY_GIO_COL_4);
keyValue = col1Value | (col2Value << 1) | (col3Value << 2) | (col4Value << 3);
// printf("=1==keyValue = %x\n",keyValue);
switch(keyValue)
{
case 0x0E:
{
if(!press1)
{
press1 = 1;
printf("KEY 1\n");
}
}
break;
case 0x0D:
{
if(!press2)
{
press2 = 1;
printf("KEY 2\n");
}
}
break;
case 0x0B:
{
if(!press3)
{
press3 = 1;
printf("KEY 3\n");
}
}
break;
case 0x07:
{
if(!press4)
{
press4 = 1;
printf("KEY 4\n");
}
}
break;
default:
{
press1 = 0;
press2 = 0;
press3 = 0;
press4 = 0;
}
break;
} dm365SetGPIO(KEY_GIO_ROW_1, 1);
dm365SetGPIO(KEY_GIO_ROW_2, 0);
dm365SetGPIO(KEY_GIO_ROW_3, 1);
dm365SetGPIO(KEY_GIO_ROW_4, 1);
col1Value = dm365GetGPIO(KEY_GIO_COL_1);
col2Value = dm365GetGPIO(KEY_GIO_COL_2);
col3Value = dm365GetGPIO(KEY_GIO_COL_3);
col4Value = dm365GetGPIO(KEY_GIO_COL_4);
keyValue = col1Value | (col2Value << 1) | (col3Value << 2) | (col4Value << 3);
// printf("=2==keyValue = %x\n",keyValue);
switch(keyValue)
{
case 0x0E:
{
if(!press5)
{
press5 = 1;
printf("KEY 5\n");
}
}
break;
case 0x0D:
{
if(!press6)
{
press6 = 1;
printf("KEY 6\n");
}
}
break;
case 0x0B:
{
if(!press7)
{
press7 = 1;
printf("KEY 7\n");
}
}
break;
case 0x07:
{
if(!press8)
{
press8 = 1;
printf("KEY 8\n");
}
}
break;
default:
{
press5 = 0;
press6 = 0;
press7 = 0;
press8 = 0;
}
break;
} dm365SetGPIO(KEY_GIO_ROW_1, 1);
dm365SetGPIO(KEY_GIO_ROW_2, 1);
dm365SetGPIO(KEY_GIO_ROW_3, 0);
dm365SetGPIO(KEY_GIO_ROW_4, 1);
col1Value = dm365GetGPIO(KEY_GIO_COL_1);
col2Value = dm365GetGPIO(KEY_GIO_COL_2);
col3Value = dm365GetGPIO(KEY_GIO_COL_3);
col4Value = dm365GetGPIO(KEY_GIO_COL_4);
keyValue = col1Value | (col2Value << 1) | (col3Value << 2) | (col4Value << 3);
// printf("=3==keyValue = %x\n",keyValue);
switch(keyValue)
{
case 0x0E:
{
if(!press9)
{
press9 = 1;
printf("KEY 9\n");
}
}
break;
case 0x0D:
{
if(!press10)
{
press10 = 1;
printf("KEY 10\n");
}
}
break;
case 0x0B:
{
if(!press11)
{
press11 = 1;
printf("KEY 11\n");
}
}
break;
case 0x07:
{
if(!press12)
{
press12 = 1;
printf("KEY 12\n");
}
}
break;
default:
{
press9 = 0;
press10 = 0;
press11 = 0;
press12 = 0;
}
break;
} dm365SetGPIO(KEY_GIO_ROW_1, 1);
dm365SetGPIO(KEY_GIO_ROW_2, 1);
dm365SetGPIO(KEY_GIO_ROW_3, 1);
dm365SetGPIO(KEY_GIO_ROW_4, 0);
col1Value = dm365GetGPIO(KEY_GIO_COL_1);
col2Value = dm365GetGPIO(KEY_GIO_COL_2);
col3Value = dm365GetGPIO(KEY_GIO_COL_3);
col4Value = dm365GetGPIO(KEY_GIO_COL_4);
keyValue = col1Value | (col2Value << 1) | (col3Value << 2) | (col4Value << 3);
// printf("=4==keyValue = %x\n",keyValue);
switch(keyValue)
{
case 0x0E:
{
if(!press13)
{
press13 = 1;
printf("KEY 13\n");
}
}
break;
case 0x0D:
{
if(!press14)
{
press14 = 1;
printf("KEY 14\n");
}
}
break;
case 0x0B:
{
if(!press15)
{
press15 = 1;
printf("KEY 15\n");
}
}
break;
case 0x07:
{
if(!press16)
{
press16 = 1;
printf("KEY 16\n");
}
}
break;
default:
{
press13 = 0;
press14 = 0;
press15 = 0;
press16 = 0;
}
break;
} return keyValue;
}
void *KeyMngThread()
{
int resetValue = 1;
int resetCout = 0;
int alarmInValue = 1;
int alarmInCout = 0;
while(1)
{
resetValue = dm365GetGPIO(GIO_RESET);
if(0 == resetValue)
{
resetCout++;
}
else if(1 == resetValue)
{
resetCout = 0;
}
if(resetCout == 30)
{
resetCout = 0;
system("rm -f /mnt/nand/sysenv.cfg");
system("/bin/sync");
// System("reboot");
system("/tmp/shutdown -r now \n");
}
alarmInValue = dm365GetGPIO(GIO_ALARM_IN);
if(0 == alarmInValue)
{
dm365SetGPIO(GIO_LED,0); //control led off .
}
else if(1 == alarmInValue)
{
dm365SetGPIO(GIO_LED,1); //control led on .
} scanKey(); usleep(100000);
} }

代码中dm365SetGPIO( )里将GPIO默认设置为Output,

dm365GetGPIO( )中将GPIO默认设置为Input,

通过字符设备驱动实现应用层操作底层GPIO。

04-29 04:49