I wrote a program for a matrix keyboard, but it doesn't work very well.
Schematic diagram:
Code:
//Initialize PA8 and PD2 as output ports and enable the clocks of these two ports
//LED IO initialization
void KEY_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOE, ENABLE); //Enable PB, PE port clock
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD; //Open drain output
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //IO port speed is 50MHz
GPIO_Init(GPIOE, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //Floating input
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //IO port speed is 50MHz
GPIO_Init(GPIOE, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //Floating input
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //IO port speed is 50MHz
GPIO_Init(GPIOB, &GPIO_InitStructure);
}
unsigned char GetKey(void)
{
unsigned char keyvalue = 0;
uint16_t hangvalue=0;
GPIO_ResetBits(GPIOE,GPIO_Pin_6 | GPIO_Pin_5 | GPIO_Pin_4 | GPIO_Pin_3); //PE.6, 5, 4, 3 output low
hangvalue=(GPIO_ReadInputData(GPIOE)&0x07)+((GPIO_ReadInputData(GPIOB)&0x0380)>>4);
if (hangvalue != 0x3f) // If the value is not 0x3f, it means a key is pressed
{
delay_ms(20); //delay to eliminate jitter
hangvalue=(GPIO_ReadInputData(GPIOE)&0x07)+((GPIO_ReadInputData(GPIOB)&0x0380)>>4);
if (hangvalue != 0x3f) // If the value is not 0x3f, it means a key is pressed
{
GPIO_ResetBits(GPIOE,GPIO_Pin_6); //PE.6 output low
GPIO_SetBits(GPIOE,GPIO_Pin_5 | GPIO_Pin_4 | GPIO_Pin_3);
hangvalue=(GPIO_ReadInputData(GPIOE)&0x07)+((GPIO_ReadInputData(GPIOB)&0x0300)>>5);
//hangvalue=(GPIO_ReadInputData(GPIOE)&0x07)+((GPIO_ReadInputData(GPIOB)&0x0380)>>4);
switch (hangvalue)
{
case 0x0F:
keyvalue=4;
break;
case 0x17:
keyvalue=5;
break;
case 0x1b:
keyvalue=1;
break;
case 0x1d:
keyvalue=2;
break;
case 0x1e:
keyvalue=3;
break;
default: break;
}
if(keyvalue==0)
{
GPIO_ResetBits(GPIOE, GPIO_Pin_5 );
GPIO_SetBits(GPIOE,GPIO_Pin_6 | GPIO_Pin_4 | GPIO_Pin_3);
hangvalue=(GPIO_ReadInputData(GPIOE)&0x07)+((GPIO_ReadInputData(GPIOB)&0x0300)>>5);
switch (hangvalue)
{
case 0x0F:
keyvalue=9;
break;
case 0x17:
keyvalue=10;
break;
case 0x1b:
keyvalue=6;
break;
case 0x1d:
keyvalue=7;
break;
case 0x1e:
keyvalue=8;
break;
default: break;
}
}
if(keyvalue==0)
{
GPIO_ResetBits(GPIOE, GPIO_Pin_4 );
GPIO_SetBits(GPIOE,GPIO_Pin_6 | GPIO_Pin_3 | GPIO_Pin_5);
hangvalue=(GPIO_ReadInputData(GPIOE)&0x07)+((GPIO_ReadInputData(GPIOB)&0x0380)>>4);
// Calculate the row number in the first round
switch (hangvalue)
{
case 0x1F:
keyvalue=14;
break;
case 0x2F:
keyvalue=15;
break;
case 0x37:
keyvalue=16;
break;
case 0x3B:
keyvalue=11;
break;
case 0x3D:
keyvalue=12;
break;
case 0x3E:
keyvalue=13;
break;
default: break;
}
}
if(keyvalue==0)
{
GPIO_SetBits(GPIOE,GPIO_Pin_6 | GPIO_Pin_4 | GPIO_Pin_5);
GPIO_ResetBits(GPIOE, GPIO_Pin_3 );
hangvalue=(GPIO_ReadInputData(GPIOE)&0x07)+((GPIO_ReadInputData(GPIOB)&0x0380)>>4);
switch (hangvalue)
{
case 0x1F:
keyvalue=20;
break;
case 0x2F:
keyvalue=21;
break;
case 0x37:
keyvalue=22;
break;
case 0x3B:
keyvalue=17;
break;
case 0x3D:
keyvalue=18;
break;
case 0x3E:
keyvalue=19;
break;
default: break;
}
}
GPIO_ResetBits(GPIOE,GPIO_Pin_6 | GPIO_Pin_5 | GPIO_Pin_4 | GPIO_Pin_3); //PE.6, 5, 4, 3 output low
hangvalue=(GPIO_ReadInputData(GPIOE)&0x07)+((GPIO_ReadInputData(GPIOB)&0x0380)>>4);
while (hangvalue != 0x3f)
{
hangvalue=(GPIO_ReadInputData(GPIOE)&0x07)+((GPIO_ReadInputData(GPIOB)&0x0380)>>4);
}
return keyvalue;
}
return 0;
}
return 0;
}
Some buttons are not detected correctly:
The buttons 1, 2, 3, 4, 5 are 1, 2, 3, 4, 5.
Buttons 6, 7, 8, 9, 10 are 1, 2, 3, 9, 10
Buttons 11, 12, 13, 14, 15 are 1, 2, 3, 14, 15.
Buttons 16, 17, 18, 19, 20 are 16, 1, 2, 3, 20
Could you please tell me where I am wrong? Thanks!
|