|
/* 程序效果:按下按鍵,蜂鳴器響,數(shù)碼管有相應(yīng)的鍵值 顯示,按下E鍵繼電器關(guān),按下C鍵繼電器開。 這與上一程序的功能相同,比上一程序簡潔 但理解相對困難些。 運(yùn)行平臺:51hei單片機(jī)學(xué)習(xí)板 */
#include<reg52.h> //頭文件 #include<intrins.h> #define uchar unsigned char //宏定義 #define uint unsigned int sbit jdq=P3^5; //位聲明,驅(qū)動繼電器管腳 sbit fmq=P3^4; //位聲明,驅(qū)動蜂鳴器管腳 code uchar table[]={0x3f,0x06,0x5b,//數(shù)碼管顯示的數(shù)值 0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f, 0x77,0x7c,0x39,0x5e,0x79,0x71}; code uchar key_tab[17]={ //此數(shù)組為鍵盤編碼 0xed,0x7e,0x7d,0x7b, // 0,1,2,3, 0xbe,0xbd,0xbb,0xde, // 4,5,6,7, 0xdd,0xdb,0x77,0xb7, // 8,9,a, b, 0xee,0xeb,0xd7,0xe7,0xff}; // c,d,e,f, uchar l_key=0x00; //定義變量,存放鍵值 uchar l_keyold=0xff; //作為按鍵放開否的憑證 void readkey(); //掃描鍵盤,獲取鍵值 void display(uchar *lp,uchar lc); //顯示子函數(shù) void delay(); //延時(shí)子函數(shù) void main() //主函數(shù) { EA=1; //打開總中斷 EX0=1; //打開外部中斷 P0=0xf0; //鍵值高4位為高電平,低4位為低電平 while(1) { display(&l_key,1); //調(diào)用顯示子函數(shù) if(l_key==14) //是否按下E鍵,是則關(guān)閉繼電器 jdq=1; if(l_key==12) //是否按下C鍵,是則打開繼電器 jdq=0; } } void key_scan() interrupt 0//外部中斷0,0的優(yōu)先級最高 { EX0=0; //在讀鍵盤時(shí),關(guān)閉外部中斷,防止干擾帶來的多次中斷 TMOD&=0xf1; //設(shè)置定時(shí)器為工作方式1 TH0=0x2e; //設(shè)置初值,為12毫秒,十進(jìn)制值為11776 TL0=0x00; ET0=1; //開啟定時(shí)器中斷0 TR0=1; //啟動定時(shí)器計(jì)數(shù) } void time0() interrupt 1 //定時(shí)器0的中斷函數(shù) { TR0=0; //關(guān)閉定時(shí)器0 readkey(); //定時(shí)12ms后產(chǎn)生中斷,調(diào)用此函數(shù),讀取鍵值 } void readkey() //掃描鍵盤子函數(shù) { uchar i,j,key; //定義局部變量 j=0xfe; //設(shè)定初值 key=0xff; for(i=0;i<4;i++) // 逐列掃描鍵盤 { P0=j; if((P0&0xf0)!=0xf0) //有按鍵按下,高4位不可能全為1 { key=P0; //讀取P0口的值,推出循環(huán),否則循環(huán)下次 break; } j=_crol_(j,1); //此函數(shù)的功能是:左移循環(huán) } if(key==0xff) //如果讀取不到P0口的值,如干擾,則返回 { l_keyold=0xff; P0=0xf0; // 恢復(fù)P0口的值,等待按鍵按下 fmq=1; EX0=1; //在返回前,打開外部中斷 return; } fmq=0; //有按鍵按下,打開蜂鳴器 if(l_keyold==key) // 檢查按鍵放開否,如果相等表明沒有放開 { TH0=0x2e; //設(shè)置初值 TL0=0x00; TR0=1; //繼續(xù)啟動定時(shí)器,檢查按鍵放開否 return; } TH0=0x2e; TL0=0; TR0=1; //啟動定時(shí)器 l_keyold=key; //獲取鍵值,作為放開否的憑證 for(i=0;i<17;i++) //查表獲得相應(yīng)的16進(jìn)制值存放到l_key中 { if(key==key_tab[i]) { l_key=i; break; } } //程序運(yùn)行到此,就表明有鍵值存放到l_key中,主程序 //就可以檢測鍵盤值并作相應(yīng)的處理 } void display(uchar *lp,uchar lc) //顯示子函數(shù) { uchar i; //定義局部變量 P1=0xf8; //點(diǎn)亮第一個(gè)數(shù)碼管 P2=0; //P2口為輸出值 for(i=0;i<lc;i++) //循環(huán)顯示 { P2=table[lp[i]]; //查表獲得相應(yīng)的要顯示的數(shù)字的數(shù)碼段 delay(); //延時(shí) P2=0; //清零,準(zhǔn)備顯示下一個(gè)數(shù)值 } } void delay() //延時(shí)子函數(shù) { _nop_();_nop_();_nop_();_nop_();_nop_(); }
|