4X4矩阵键盘扫描:
1. 4根行线的GIO均设为Output,根列线的GIO均设为Input;
2. 4根行线的GIO分别置为0111、1011、1101、1110,读逐一读取列线GIO的值,可确定是哪一个按键。
电路图例如以下:
注意:
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 ",keyValue); switch(keyValue) { case 0x0E: { if(!press1) { press1 = 1; printf("KEY 1 "); } } break; case 0x0D: { if(!press2) { press2 = 1; printf("KEY 2 "); } } break; case 0x0B: { if(!press3) { press3 = 1; printf("KEY 3 "); } } break; case 0x07: { if(!press4) { press4 = 1; printf("KEY 4 "); } } 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 ",keyValue); switch(keyValue) { case 0x0E: { if(!press5) { press5 = 1; printf("KEY 5 "); } } break; case 0x0D: { if(!press6) { press6 = 1; printf("KEY 6 "); } } break; case 0x0B: { if(!press7) { press7 = 1; printf("KEY 7 "); } } break; case 0x07: { if(!press8) { press8 = 1; printf("KEY 8 "); } } 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 ",keyValue); switch(keyValue) { case 0x0E: { if(!press9) { press9 = 1; printf("KEY 9 "); } } break; case 0x0D: { if(!press10) { press10 = 1; printf("KEY 10 "); } } break; case 0x0B: { if(!press11) { press11 = 1; printf("KEY 11 "); } } break; case 0x07: { if(!press12) { press12 = 1; printf("KEY 12 "); } } 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 ",keyValue); switch(keyValue) { case 0x0E: { if(!press13) { press13 = 1; printf("KEY 13 "); } } break; case 0x0D: { if(!press14) { press14 = 1; printf("KEY 14 "); } } break; case 0x0B: { if(!press15) { press15 = 1; printf("KEY 15 "); } } break; case 0x07: { if(!press16) { press16 = 1; printf("KEY 16 "); } } 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 "); } 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。