(3) Matrix keyboard

When there are many keys in the keyboard, in order to reduce the occupation of the IO port, the keys are arranged in a matrix form

By "scanning" row by row or column by row, you can read the status of the button at any position

  • Nixie tube scan - output scan
  • Matrix keyboard scan - input scan

Commonality: reduce IO port occupation

Use scan by column:

Please add a picture description

P10-P13 control columns, P14-P17 control rows

unsigned char MatrixKey(){
    
    
	unsigned char KeyNumber = 0;
	
	P1 = 0xff;
	P1_3 = 0; // 扫描第一列
	if(P1_7 == 0){
    
    Delay(20);while(P1_7 == 0);Delay(20);KeyNumber = 1;}
	if(P1_6 == 0){
    
    Delay(20);while(P1_6 == 0);Delay(20);KeyNumber = 5;}
	if(P1_5 == 0){
    
    Delay(20);while(P1_5 == 0);Delay(20);KeyNumber = 9;}
	if(P1_4 == 0){
    
    Delay(20);while(P1_4 == 0);Delay(20);KeyNumber = 13;}
	
	P1 = 0xff;
	P1_2 = 0; // 扫描第二列
	if(P1_7 == 0){
    
    Delay(20);while(P1_7 == 0);Delay(20);KeyNumber = 2;}
	if(P1_6 == 0){
    
    Delay(20);while(P1_6 == 0);Delay(20);KeyNumber = 6;}
	if(P1_5 == 0){
    
    Delay(20);while(P1_5 == 0);Delay(20);KeyNumber = 10;}
	if(P1_4 == 0){
    
    Delay(20);while(P1_4 == 0);Delay(20);KeyNumber = 14;}
	
	P1 = 0xff;
	P1_1 = 0; // 扫描第三列
	if(P1_7 == 0){
    
    Delay(20);while(P1_7 == 0);Delay(20);KeyNumber = 3;}
	if(P1_6 == 0){
    
    Delay(20);while(P1_6 == 0);Delay(20);KeyNumber = 7;}
	if(P1_5 == 0){
    
    Delay(20);while(P1_5 == 0);Delay(20);KeyNumber = 11;}
	if(P1_4 == 0){
    
    Delay(20);while(P1_4 == 0);Delay(20);KeyNumber = 15;}
	
	P1 = 0xff;
	P1_0 = 0; // 扫描第四列
	if(P1_7 == 0){
    
    Delay(20);while(P1_7 == 0);Delay(20);KeyNumber = 4;}
	if(P1_6 == 0){
    
    Delay(20);while(P1_6 == 0);Delay(20);KeyNumber = 8;}
	if(P1_5 == 0){
    
    Delay(20);while(P1_5 == 0);Delay(20);KeyNumber = 12;}
	if(P1_4 == 0){
    
    Delay(20);while(P1_4 == 0);Delay(20);KeyNumber = 16;}
	
	return KeyNumber;
}

But the delay of this code running on my MCU is too high, and it takes several seconds to wait after pressing the button, so use the function that comes with the tutorial:

#include <REGX52.H>
void delay_10us(unsigned int ten_us)
{
    
    
	while(ten_us--);	
}
unsigned char key_matrix_flip_scan()
{
    
    
	static unsigned char key_value=0;

	P1=0x0f;//给所有行赋值0,列全为1
	if(P1!=0x0f)//判断按键是否按下
	{
    
    
		delay_10us(1000);//消抖
		if(P1!=0x0f)
		{
    
    
			//测试列
			P1=0x0f;
			switch(P1)//保存行为0,按键按下后的列值	
			{
    
    
				case 0x07: key_value=1;break;
				case 0x0b: key_value=2;break;
				case 0x0d: key_value=3;break;
				case 0x0e: key_value=4;break;
			}
			//测试行
			P1=0xf0;
			switch(P1)//保存列为0,按键按下后的键值	
			{
    
    
				case 0x70: key_value=key_value;break;
				case 0xb0: key_value=key_value+4;break;
				case 0xd0: key_value=key_value+8;break;
				case 0xe0: key_value=key_value+12;break;
			}
			while(P1!=0xf0);//等待按键松开	
		}
	}
	else
		key_value=0;		
	return key_value;		
}

Guess you like

Origin blog.csdn.net/Falling_Asteroid/article/details/130736639