天天看點

C51鍵盤檢測相關問題總結

附注:

原理圖各接口連接配接關系可參考代碼中的端口定義;

P0口資料鎖存器為兩片74HC573晶片;

1.對獨立鍵盤的檢測

/*--------------------------
功能:用數位管實作60s計時器
上電時,數位管顯示00
key4控制開始/暫停計時
暫停狀态下,key1進行加1操作
key2進行減1操作
key3進行清零操作
---------------------------
Author: Zhang Kaizhou
Date: 2019-5-19 19:14:20
--------------------------*/
#include <reg52.h>
#define uchar unsigned char
#define uint unsigned int
	
sbit key1 = P3^4;
sbit key2 = P3^5;
sbit key3 = P3^6;
sbit key4 = P3^7;
sbit wei_address = P2^7;
sbit duan_address = P2^6;
uchar code table[] = {0x3f, 0x06, 0x5b, 0x4f,
					  0x66, 0x6d, 0x7d, 0x07,
				      0x7f, 0x6f, 0x77, 0x7c,
				      0x39, 0x5e, 0x79, 0x71}; // 定義一個無符号字元型數組table[],存放在單片機内部的ROM或Flash中

uchar n1 = 0, n2 = 0;							
	
void init();
void display(uchar num);
void keyScan();	
void delay(uchar xms);											
											
void main()
{
	init();
	while(1)
	{
		keyScan();
		display(n1);
	}
}

/*初始化函數*/
void init()
{
	TMOD = 0x01; // 定時器0,方式1
	TH0 = (65536 - 45872) / 256; // 定時50ms
	TL0 = (65536 - 45872) % 256;
	EA = 1; // 開全局中斷
	ET0 = 1; // 開定時器0溢出中斷
}

/*定時器0中斷服務程式*/
void T0_interrupt() interrupt 1
{
	TH0 = (65536 - 45872) / 256; // 定時器0重裝初值
	TL0 = (65536 - 45872) % 256;
	n2++;
	if(n2 == 20) // 定時到1s
	{
		n2 = 0;
		n1++;
		if(n1 == 60)
		{
			n1 = 0;
		}
	}
}

/*數位管顯示函數*/
void display(uchar num)
{
	uchar shi, ge;
	shi = num / 10;
	ge = num % 10;
	
	duan_address = 1; // 在數位管上顯示十位的數字
	P0 = table[shi];
	duan_address = 0;
	P0 = 0xff;
	wei_address = 1;
	P0 = 0xfe;
	wei_address = 0;
	delay(5);
	
	duan_address = 1; // 在數位管上顯示個位的數字
	P0 = table[ge];
	duan_address = 0;
	P0 = 0xff;
	wei_address = 1;
	P0 = 0xfd;
	wei_address = 0;
	delay(5);
}

/*鍵盤掃描函數*/
void keyScan()
{
	if(!key1) // key1按下,加1
	{
		delay(10);
		if(!key1) 
		{
			n1++;
			if(n1 == 60)
			{
				n1 = 0;
			}
			while(!key1);
		}
	}
	
	if(!key2) // key2按下,減1
	{
		delay(10);
		if(!key2) 
		{
			if(!n1)
			{
				n1 = 60;				
			}
			n1--;
			while(!key2);
		}
	}
	
	if(!key3) // key4按下,暫停或開始定時器0
	{
		delay(10);
		if(!key3) 
		{
			n1 = 0;
			while(!key3);
		}
	}
	
	if(!key4)
	{
		delay(10);
		if(!key4)
		{
			while(!key4);
			TR0 = ~TR0;
		}
	}
}

/*延時函數*/
void delay(uchar xms)
{
	uchar i, j;
	for(i = 0; i < xms; i++)
		for(j = 0; j < 110; j++);
}
           

2.對矩陣鍵盤進行掃描

/*------------------------
功能:掃描4x4矩陣鍵盤
Author: Zhang Kaizhou
Date: 2019-5-21 21:37:31
-------------------------*/
#include <reg52.h>
#define uchar unsigned char
	
sbit wei_address = P2^7;
sbit duan_address = P2^6;

uchar code table[] = {0x3f, 0x06, 0x5b, 0x4f,
					  0x66, 0x6d, 0x7d, 0x07,
  				      0x7f, 0x6f, 0x77, 0x7c,
					  0x39, 0x5e, 0x79, 0x71}; // 定義一個無符号字元型數組table[],存放在單片機内部的ROM或Flash中

uchar buffer, key;											
	
void init_digitron();											
void array_scan_oneline(uchar address);											
void array_scan();	
void display(uchar key);											
void delay(uchar xms);											
											
void main()
{
	init_digitron(); // 初始化數位管
	while(1) // 循環逐行掃描按鍵是否按下
	{
		array_scan();
	}
}

/*數位管初始化函數*/
void init_digitron()
{
	P0 = 0; // 關閉所有數位管
	duan_address = 1;
	duan_address = 0;
	
	P0 = 0x00; // 選中所有數位管
	wei_address = 1;
	wei_address = 0;
}

/*矩陣鍵盤掃描函數*/
void array_scan()
{
	array_scan_oneline(0xfe);
	array_scan_oneline(0xfd);
	array_scan_oneline(0xfb);
	array_scan_oneline(0xf7);
}

/*矩陣鍵盤掃描一行的函數*/
void array_scan_oneline(uchar address)
{
	P3 = address;
	buffer = P3;
	buffer = buffer & 0xf0;
	if(buffer != 0xf0) // 有鍵按下
	{
		delay(10); // 消抖
		buffer = P3;
		buffer = buffer & 0xf0;
		if(buffer != 0xf0)
		{
			buffer = P3;
			switch(buffer)
			{
				case 0xee: key = 0; break;
				case 0xde: key = 1; break;
				case 0xbe: key = 2; break;
				case 0x7e: key = 3; break;
				
				case 0xed: key = 4; break;
				case 0xdd: key = 5; break;
				case 0xbd: key = 6; break;
				case 0x7d: key = 7; break;
				
				case 0xeb: key = 8; break;
				case 0xdb: key = 9; break;
				case 0xbb: key = 10; break;
				case 0x7b: key = 11; break;
				
				case 0xe7: key = 12; break;
				case 0xd7: key = 13; break;
				case 0xb7: key = 14; break;
				case 0x77: key = 15; break;
			}
			while(buffer != 0xf0) // 等待按鍵釋放
			{
				buffer = P3;
				buffer = buffer & 0xf0;
			}
			display(key);
		}
	}
}

/*延時函數*/
void delay(uchar xms)
{
	uchar i, j;
	for(i = 0; i < xms; i++)
		for(j = 0; j < 110; j++);
}

/*數位管顯示函數*/
void display(uchar key)
{
	P0 = table[key];
	duan_address = 1;
	duan_address = 0;
}