|
我只要簡(jiǎn)單的功能,按下一個(gè)按鍵,執(zhí)行一個(gè)功能,如按下9,P30輸出低電平。第二代碼報(bào)錯(cuò),第一個(gè)不會(huì)用。PS2讀電腦鍵盤實(shí)驗(yàn) 數(shù)碼管顯示 只看樓主
* ID:487236 樓主
* 2019-8-7 20:50 查看1538 回復(fù)0 收藏
* /****************************************************************************************
* PS2 讀電腦鍵盤實(shí)驗(yàn) *
* 連接方法 : P0口與J12連接 拔開(kāi)跳線帽用杜邦線連接左針與P3.2右針與P1.6連接 *
* 使用方法:用外部中斷讀取PS2鍵盤的數(shù)據(jù) 并在數(shù)碼管上顯示,此程序只處理數(shù)字鍵盤。 *
* *
* 其余按鍵功能用戶可以自行擴(kuò)展,為了程序簡(jiǎn)單便于閱讀和學(xué)習(xí),程序中沒(méi)有使用奇偶校驗(yàn), *
* 校驗(yàn)程序請(qǐng)自行添加。 * *
* *
* *****************************************************************************************/
*
* #include<reg52.h>
*
* sbit LS138A=P2^2;
* sbit LS138B=P2^3;
* sbit LS138C=P2^4;
*
* sbit BEEP = P1^5;
*
* sbit Key_Data = P1^6 ; //定義鍵盤引腳
* sbit Key_CLK = P3^2; //使用外部中斷
*
* /******************************************************************/
* /* 函數(shù)聲明 */
* /******************************************************************/
* void Decode(unsigned char ScanCode);//解碼子程序
* void delay(unsigned int i); //函數(shù)聲名
* void display();
* void beep();
*
*
* // 此表為 LED 的字模 // 0 1 2 3 4 5 6 7 8 9 A b c d E - L P U Hidden_ (20)
* unsigned char code Disp_Tab[] = { ~0xC0,~0xF9,~0xA4,~0xB0,~0x99,~0x92,~0x82,~0xF8,~0x80,~0x90,~0x88,~0x83,~0xC6,~0xA1,~0x86,~0xbf,~0xc7,~0x8c,~0xc1, ~0xff,~0xf7 };
* bit BF;
* unsigned char KeyV;
* unsigned char LedNumVal;
* int KEY_val,IntNum;
*
* /******************************************************************/
* /* 主函數(shù) */
* /******************************************************************/
* void main()
* {
*
* IT1 = 0; //設(shè)外部中斷1為低電平觸發(fā)
* EA = 1; //外部中斷開(kāi)
* EX0 = 1; //開(kāi)中斷
*
* while(1)
* {
* if (BF)
* {
* if (KeyV != 240)beep();
*
* Decode(KeyV); //解碼
*
* }
* else
* EA = 1; //開(kāi)中斷
* display();
* }
*
* }
*
* /******************************************************************/
* /* 外部中斷讀入信息 */
* /******************************************************************/
* void Keyboard_out(void) interrupt 0
* {
* if ((IntNum > 0) && (IntNum < 9))
* {
* KeyV = KeyV >> 1; //因鍵盤數(shù)據(jù)是低>>高,結(jié)合上一句所以右移一位
* if (Key_Data)
* KeyV = KeyV | 0x80; //當(dāng)鍵盤數(shù)據(jù)線為1時(shí)到最高位
* }
* IntNum++;
* while (!Key_CLK); //等待PS/2CLK拉高
*
* if (IntNum > 10)
* {
* IntNum = 0; //當(dāng)中斷11次后表示一幀數(shù)據(jù)收完,清變量準(zhǔn)備下一次接收
* BF = 1; //標(biāo)識(shí)有字符輸入完了
* EA = 0; //關(guān)中斷等顯示完后再開(kāi)中斷
* }
*
* }
*
* /******************************************************************/
* /* 解碼信息 */
* /******************************************************************/
* void Decode(unsigned char ScanCode) //注意:如SHIFT+G為12H 34H F0H 34H F0H 12H,也就是說(shuō)shift的通碼+G的通碼+shift的斷碼+G的斷碼
* {
*
* switch (ScanCode)
* {
* case 0x70 : // 當(dāng)收到0xF0,Key_UP置1表示斷碼開(kāi)始
* KEY_val = 0;
* break;
*
* case 0x69 :
* KEY_val = 1;
* break;
*
* case 0x72 :
* KEY_val = 2;
* break;
*
* case 0x7A :
* KEY_val = 3;
* break;
*
* case 0x6B :
* KEY_val = 4;
* break;
*
* case 0x73 :
* KEY_val = 5;
* break;
*
* case 0x74 :
* KEY_val = 6;
* break;
*
* case 0x6c :
* KEY_val = 7;
* break;
*
* case 0x75 :
* KEY_val = 8;
* break;
*
* case 0x7d :
* KEY_val = 9;
* break;
*
* case 0x71 :
*
* // dot = 0X7F;
* break;
*
* }
*
*
* BF = 0; //標(biāo)識(shí)字符處理完了
* }
*
*
* /***************************************************************************************/
* void display( )
* {
* unsigned char i;
* unsigned int LedOut[8];
*
* LedNumVal = KEY_val ;
*
* //顯示鍵值
* LedOut[0]=Disp_Tab[KeyV%10000/1000];
* LedOut[1]=Disp_Tab[KeyV%1000/100];
* LedOut[2]=Disp_Tab[KeyV%100/10];
* LedOut[3]=Disp_Tab[KeyV%10];
*
* //顯示對(duì)應(yīng)的字符
* LedOut[4]=Disp_Tab[LedNumVal%10000/1000]; //千位
* LedOut[5]=Disp_Tab[LedNumVal%1000/100];//百位帶小數(shù)點(diǎn)
* LedOut[6]=Disp_Tab[LedNumVal%100/10]; //十位
* LedOut[7]=Disp_Tab[LedNumVal%10]; //個(gè)位
*
*
* for( i=0; i<8; i++)
* { P0 = LedOut[i ];
*
* switch(i)
* {
* case 0:LS138A=0; LS138B=0; LS138C=0; break;
* case 1:LS138A=1; LS138B=0; LS138C=0; break;
* case 2:LS138A=0; LS138B=1; LS138C=0; break;
* case 3:LS138A=1; LS138B=1; LS138C=0; break;
* case 4:LS138A=0; LS138B=0; LS138C=1; break;
* case 5:LS138A=1; LS138B=0; LS138C=1; break;
* case 6:LS138A=0; LS138B=1; LS138C=1; break;
* case 7:LS138A=1; LS138B=1; LS138C=1; break;
*
* }
*
* delay(50);
* }
*
* }
*
* /***************************************************************************************
* 延時(shí)程序 *
* ****************************************************************************************/
* void delay(unsigned int i)
* {
* char j;
* for(i; i > 0; i--)
* for(j = 200; j > 0; j--);
* }
*
* /***************************************************************************************
* 蜂鈴器發(fā)聲 *
* ****************************************************************************************/
* void beep()
* {
* unsigned char i;
* for (i=0;i<255;i++)
* {
* delay(5);
* BEEP=!BEEP; //BEEP取反
* }
* BEEP=1; //關(guān)閉蜂鳴器
* }
*
單片機(jī)學(xué)習(xí)筆記(八)PS/2電腦鍵盤 只看樓主
* ID:108531 樓主
* 2016-3-12 16:47 查看3765 回復(fù)1 收藏
PS/2鍵盤是一種編碼鍵盤,只需要一根數(shù)據(jù)線和一根時(shí)鐘線就可以完成數(shù)據(jù)的輸入。
實(shí)驗(yàn)程序設(shè)計(jì)為,按鍵盤上的"J"鍵,繼電器閉合。
C語(yǔ)言源程序:
#include <reg52.h> //52單片機(jī)頭文件包含
#include <intrins.h>//常用移位函數(shù)頭文件包含
sbit key_data=P1^5; //定義鍵盤接口的數(shù)據(jù)腳
sbit key_clk=P3^2;//定義鍵盤接口的時(shí)鐘腳
sbit JDQ=P2^4; //定義繼電器連接引腳
bit BF=0; //定義位變量BF
unsigned char keyv=0; //定義無(wú)符號(hào)字符變量keyv并賦初值0
unsigned int intNum=0;//定義無(wú)符號(hào)整型變量intNum并賦初值0
unsigned char key_up=1;//定義無(wú)符號(hào)字符變量key_up并賦初值1
void ldedata(unsigned char scandata);//按鍵數(shù)據(jù)處理函數(shù)
void main() //主函數(shù)
{
EA=1; //打開(kāi)總中斷
EX0=1;//打開(kāi)0號(hào)中斷
IT0=1;//中斷方式為下降沿觸發(fā)方式
do{ //do-while循環(huán)
if(BF) //如果有鍵按下
ldedata(keyv);//處理按鍵數(shù)據(jù)
else
EA=1;//否則打開(kāi)中斷
}while(1); //總為真不斷循環(huán)
}
void key_scan() interrupt 0 //中斷函數(shù)鍵盤輸入key_scan 中斷入口0
{
if((intNum>0)&&(intNum<9)) //如果intNum>0并且intNum<9 就執(zhí)行if里面的語(yǔ)句
{
keyv=keyv>>1; //將字符變量keyv右移一位
if(key_data) //判斷key_data 是否為真 即是否有數(shù)據(jù)
keyv=keyv|0x80; //有就將keyv與0x80進(jìn)行或運(yùn)算再賦值給keyv
}
intNum++;//將intNum的值自加1
while(!key_clk)//鍵值是否處理完
if(intNum>10)//判斷intNum是否大于10
{
intNum=0;//將intNum賦值為0
BF=1;//將BF賦值為1
EA=0;//關(guān)閉總中斷
}
}
void ldedata(unsigned char scandata) //鍵盤數(shù)據(jù)處理函數(shù)
{
if(!key_up) //鍵盤松開(kāi)時(shí)
{
switch(scandata){ //處理鍵盤數(shù)據(jù)
case 0xf0://沒(méi)按下任何鍵
key_up=1;//按下
break;//跳出
case 0x12://左邊SHIFT
break;//跳出
case 0x59://右邊SHIFT
break;//跳出
default://缺省處理
P1=~scandata;//將按下的鍵碼輸出給P2口驅(qū)動(dòng)燈亮,因發(fā)光二極采用共陽(yáng)級(jí),所以取反輸出
if(scandata==0x3b)//當(dāng)按下J鍵時(shí)
JDQ=0;//打開(kāi)繼電器
if(scandata==0x29){//當(dāng)按下空格鍵時(shí)
JDQ=1;//關(guān)閉繼電器
}
break;//跳出
}
}
else{ //否則
key_up=0;//按鍵按下
switch(scandata){//處理按鍵
case 0x12://左邊SHIFT
break;//跳出
case 0x59://右邊SHIFT
break;//跳出
}
}
BF=0;//標(biāo)識(shí)字符表示處理完了
}
//實(shí)驗(yàn)結(jié)果 按下鍵盤j鍵繼電器打開(kāi) 按下空格鍵繼電器關(guān)閉
|
|