51單片機(二十九)—— 矩陣鍵盤輸入實驗

一、矩陣鍵盤原理介紹

        在之前的文章中,我們介紹過獨立按鍵的使用,獨立按鍵需要每個按鍵使用一個IO口進行讀取,如果按鍵比較多,對IO資源的佔用比較多。使用矩陣鍵盤,並採用掃描的方式對按鍵進行讀取是解決按鍵多的一個有效辦法。採用矩陣按鍵的方式就可以有效的節省I/O資源。4*4的矩陣鍵盤只需要8個I/O口進行採集。6*6的矩陣鍵盤只需要12個I/O口就可以採集。

        本實驗的硬件電路是一個4X4的矩陣鍵盤。矩陣鍵盤的原理圖如下圖所示。

        由原理圖可以看出J23的1~4與矩陣鍵盤的每一行相連。5~8與矩陣鍵盤的每一列相連。每一列上設置了上拉電阻。矩陣鍵盤掃描時,令J23的1~4中的一個爲低電平,如果相應的行有按鍵按下,則J23的5~8中與這個按鍵對應的信號也被拉低。從而可以判斷出按下的按鍵。

        電路圖中D21~D24的作用是實現中斷功能。若令J23的1~4都爲低電平,有按鍵按下時,必有一個列信號爲低電平,由於二極管的作用,J24也被拉爲低電平。如果將J24接在外部中斷口上,就可以觸發中斷。

二、實驗例程測試

實驗1:查詢掃描

        在這個實驗中,我們採用查詢的方式對矩陣鍵盤進行讀取,這個實驗的代碼的主函數如下所示。

main()
{
	init_T0();
	for(;;)
	{
		keyma=KEYscan();
		keyvalue=Keychange(keyma);	
		if(keyvalue!=0xff)
		{
			for(n=0;n<7;n++)
			  showdata[n]=showdata[n+1];  //顯示的數據向左移位
			showdata[7]=BJTY_DuanMa[keyvalue];     //讀取最新的顯示值
		}
	}
}

        在主函數中,先初始化T0,T0主要是設置數碼管的掃描定時器。在定時器中斷中,進行數碼管的掃描。之後進入for循環,在否循環中,先調用KEYscan()函數,對矩陣鍵盤進行掃描,返回值爲IO的碼值。再調用Keychange(keyma); 函數把碼值轉換爲按鍵的鍵值,最後將按鍵值賦值給數碼管的斷碼進行顯示。

        KEYscan()函數是對矩陣鍵盤進行掃描的函數,函數定義如下所示。函數返回值是8個IO口的碼值。

 

unsigned char KEYscan(void) 
{
	unsigned char key;
	KEYboard=0xf0;     //低四位全部拉低
	if(KEYboard!=0xf0) //表示有按鍵按下
	{
		delay1ms(10);  //去抖
		if(KEYboard!=0xf0)
		{           //表示有按鍵按下
			KEYboard=0xfe; //掃描第一行將第一行拉低
			if(KEYboard!=0xfe)
			{
				delay1ms(10); //去抖
				if(KEYboard!=0xfe)
					key=KEYboard;
				while(KEYboard!=0xfe);   //等待按鍵釋放
				return key;
			}
			KEYboard=0xfd; //掃描第二行將第二行拉低
			if(KEYboard!=0xfd)
			{
				delay1ms(10); //去抖
				if(KEYboard!=0xfd)
					key=KEYboard;
				while(KEYboard!=0xfd);   //等待按鍵釋放
				return key;
			}
			KEYboard=0xfb; //掃描第三行將第三行拉低
			if(KEYboard!=0xfb)
			{
				delay1ms(10); //去抖
				if(KEYboard!=0xfb)
					key=KEYboard;
				while(KEYboard!=0xfb);   //等待按鍵釋放
				return key;
			}
			KEYboard=0xf7; //掃描第四行將第四行拉低
			if(KEYboard!=0xf7)
			{
				delay1ms(10); //去抖
				if(KEYboard!=0xf7)
					key=KEYboard;
				while(KEYboard!=0xf7);   //等待按鍵釋放
				return key;
			}
		}
	}
	return 0xff;
}

Keychange(keyma)函數的定義如下所示。

unsigned char Keychange(unsigned char y)
{
	switch(y)
	{
		case 0xee:return 0;break;//0 
		case 0xde:return 1;break;//1
		case 0xbe:return 2;break;//2
		case 0x7e:return 3;break;//3
		case 0xed:return 4;break;//4
		case 0xdd:return 5;break;//5
		case 0xbd:return 6;break;//6
		case 0x7d:return 7;break;//7
		case 0xeb:return 8;break;//8
		case 0xdb:return 9;break;//9
		case 0xbb:return 10;break;//a
		case 0x7b:return 11;break;//b
		case 0xe7:return 12;break;//c
		case 0xd7:return 13;break;//d
		case 0xb7:return 14;break;//e
		case 0x77:return 15;break;//f
		default:return 0xff;break;
	}
}

        燒寫之後可以看到實驗現象,按下矩陣鍵盤S1~S16中的任意一個按鍵,S1~S16這16個按鍵,分別與數值0~F相對應。按下的按鍵可以在數碼管上顯示出來。每按一次按鍵,數碼管上的顯示內容向左移一位。

 

    矩陣鍵盤的掃描與數碼管的掃描大同小異。掃描個過程如下:

    1、令行線輸出全爲0;

    2、如果列線輸入不全是1,則有按鍵按下;

    3、掃描第一行,如果列線不全是1,則第一行有按鍵按下,返回按鍵碼值;

    4、掃描第二行,如果列線不全是1,則第二行有按鍵按下,返回按鍵碼值;

    5、掃描第三行,如果列線不全是1,則第三行有按鍵按下,返回按鍵碼值;

    6、掃描第四行,如果列線不全是1,則第四行有按鍵按下,返回按鍵碼值。

實驗2:中斷掃描

        在這個實驗中,我們採用中斷方式進行矩陣鍵盤的讀取。例程的主函數如下所示。

main()
{
	init_T0();
	EX0=1;         //打開外部中斷0
	IT0=1;         //外部中斷採用邊沿觸發

	for(;;)
	{
		KEYboard=0xf0;     //低四位全部拉低		
		if(flag==1)
		{
			flag=0;
			keyma=KEYscan();
			keyvalue=Keychange(keyma);	
			if(keyvalue!=0xff)
			{
				for(n=0;n<7;n++)
				  showdata[n]=showdata[n+1];  //顯示的數據向左移位
				showdata[7]=BJTY_DuanMa[keyvalue];     //讀取最新的顯示值
			}
		}
	}
}

在主函數中,使能了外部中斷的通道0,採用邊沿觸發模式。一旦有按鍵按下,則會觸發外部中斷,在中斷處理函數中,將標誌位flag置1。在主函數中,判斷標誌位爲1時,進行鍵盤的掃描,並在數碼管上顯示。具體的掃描方法及顯示方法與查詢掃描方式是相同的。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章