這個是程序是來自我以前開發的一個項目,其中里面的的void ps_send(uchar x) 這個函數,便可實現向電腦發送按鍵的數據 你只要對照 ps2 掃描碼的表填入適當的參數即可
#include "STC89C51.H" #include"keyboard.h" #include<INTRINS.H> #define nop() _nop_() uchar *receive_buf;//接收來自計算機的數據 //uchar key; unsigned char key_buf[21]; /******延時子程序********/ void delay_ms(uchar a) {uchar i; uchar j; for(j=0;j<a;j++) for(i=200;i>0;i--); } void delay_us(void)//30us {uchar i; for(i=0;i<7;i++) { _nop_(); } } /************行列轉換成索引號*****************/ /* uchar code_chang(uchar ini_code) {uchar i; i=ini_code; switch(i) {case 0x01:return(1);break; case 0x02:return(2);break; case 0x04:return(3);break; case 0x08:return(4);break; case 0x10:return(5);break; default:; } } */ //初始化按鍵端口 void init_key(void) { unsigned char i=0; //右按鍵板 P2=0xff; //左按鍵板 P0=0xff; k_num_5 = 1; k_num_4 = 1; k_num_7 = 1; k_num_8 = 1; k_num_9 = 1; // led=0; for(i=0;i<21;i++) { key_buf[i]=1; } } //讀按鍵值并將其轉換為索引號 unsigned char read_key(void) {unsigned char i; key_buf[0]=k_esc; key_buf[1]=k_F1; key_buf[2]=k_F3; key_buf[3]=k_F2; key_buf[4]=k_F5; key_buf[5]=k_F4; key_buf[6]=k_menu; key_buf[7]=k_num_lock; key_buf[8]=k_num_6; key_buf[9]=k_num_1; key_buf[10]=k_num_2 ; key_buf[11]=k_num_3 ; key_buf[12]=k_num_0; key_buf[13]=k_del; key_buf[14]=k_enter; key_buf[15]=k_back; key_buf[16]=k_num_5; key_buf[17]=k_num_4; key_buf[18]=k_num_7; key_buf[19]=k_num_8; key_buf[20]=k_num_9; for(i=0;i<21;i++) {if(0==key_buf[i]) { key_buf[i]=1; return i; break; } } } /********代碼轉換**************/ uchar change_code(uchar key) //返回一個ASCII鍵值 {uchar i; static bit shitf_direct=0,key_flat=1; i=key; if(7==i&&1==key_flat) {key_flat=0; shitf_direct=1; } else if(7==i&&0==key_flat) {key_flat=1; shitf_direct=0; } else {} if ( 1==shitf_direct)//轉到方向盤(1為方向盤,0為數字盤) { lock_LED =0; switch(i) { case 12:return(0x2D);break;//insert case 9:return(0x23);break;//end case 10:return(0x28);break;//down case 11:return(0x22);break;//pagedown case 17:return(0x25);break;//left case 16:return(0x0C);break;//NC case 8:return(0x27);break;//right case 18:return(0x24);break;//home case 19:return(0x26);break;//up case 20:return(0x21);break;//pageup default:; } } else {lock_LED =1; return(trdata[i]); } } /*************鍵盤掃描*****************/ /* void int1() interrupt 2 using 1 {//uchar scankb(void) uchar sccode,recode; if((P0&0x0f)!=0x0f)//有鍵按下 {delay_ms(10); if((P0&0x0f)!=0x0f)//仍然有鍵按下 {recode=P0|0xf0; //列號保存 P0=0x0f; sccode=0xfe; while((sccode&0x40)!=0)//移位沒完 { P2=sccode;//行掃描開始 if(P0 != 0x0F) //若在該行 { P0=0x0f; P2=0; //return(code_chang(~sccode)+5*code_chang(~recode));//返回Keyword key=code_chang(~sccode)+5*code_chang(~recode);break; } else {sccode=(sccode<<1)|0x01;}//不在該行則掃下一行 } } } // return(0); } */ /** ps/2發送數據 ***/ void ps_send(uchar x) { uchar i,temp,char_temp; bit flat_check=1; delay_ms(3); temp=x; for(i=0;i<8;i++) {char_temp=temp&0x01; if(char_temp==0x01) {flat_check=!flat_check; } temp>>=1; } k_clk = 1; while(!k_clk); k_clk=1; k_data=1; if(k_clk==1) {delay_us();//30us } if(k_clk==1&&k_data==1) {k_data=0; nop();nop();nop();nop();nop();nop();nop();nop();nop();nop();//delay10us; k_clk=0; nop();nop();nop();nop();nop();//delay5us; temp=x; for(i=0;i<8;i++) {k_clk=1; nop();nop();nop();nop();nop();//delay5us; char_temp=temp&0x01; if(char_temp==0x01) { k_data=1; } else { k_data=0; } nop();nop();nop();nop();nop();nop();nop();nop();nop();nop();//delay10us; k_clk=0; nop();nop();nop();nop();nop();//delay5us; temp>>=1; } k_clk=1; nop();nop();nop();nop();nop();//delay5us; k_data=flat_check; nop();nop();nop();nop();nop();nop();nop();nop();nop();nop();//delay10us; k_clk=0; nop();nop();nop();nop();nop();//delay5us; k_clk=1; nop();nop();nop();nop();nop();//delay5us; k_data=1; nop();nop();nop();nop();nop();nop();nop();nop();nop();nop();//delay10us; k_clk=0; nop();nop();nop();nop();nop();//delay5us; k_clk=1; delay_us(); k_clk=1; k_data=1; if(k_clk==1&&k_data==0) { return;//goto receive PC of data } } } /***************************************************************************************** 串行通訊 采用11位帶奇偶效檢串口異步通信 ******************************************************************************************/ /******串口發送***********/ /* void series_sent(uchar keyword) {uchar i,key_L; uint j; bit odd=0; key_L=keyword; for(i=0;i<8;i++) {odd=odd ^ key_L^7; key_L<<=1; } SBUF=keyword; TB8=odd;//odd=1為奇數 ,odd=0為偶數 while(TI==0); for(j=0;j<500;j++); } */ /****************串口中斷***************************/ /* void UART() interrupt 4 using 2 {bit odd,odd_check; uchar i, buf; if(RI) { buf=SBUF; odd=RB8; for(i=0;i<8;i++) {odd_check=odd_check ^ buf ^7; buf<<=1; } if(odd_check!=odd)//校驗出錯發送錯誤代碼0x55 { SBUF=0x55;//錯誤代碼0x55 while(!TI);//等待發送完成 TI=0;//清除發送標志 } else {*receive_buf=SBUF;//將來自計算機的數據保存 } RI=0;//清除接收標志 } } */ /************************************************************ //mcu初始化 **************************************************************/ void ini(void) { TMOD=0X20; /*定時器1八位自動重裝*/ TL1=0XFA;TH1=0XFA; /*12MHz,9600波特,誤差8.5%*/ //SCON=0Xd8;PCON=0X10; /*11位異步,定時器控制*/ //TR1=1; AUXR=0xbf; //12T:0xbf 1T:0x40 RCAP2H=0XFF; //設T2為波特率發生器 12M----9600----0xFFD9 RCAP2L=0Xd9; TR2=1; // T2IE=1; // T2RSE=1; ET2=1; TCLK=1; RCLK=1; TMOD=0x11; //設T1為定時方式1,設T0為定時方式1 TH1=0xec; //5ms TL1=0X78; TH0=0xff; //100us ff9b TL0=0xaa; PCON=0x00; // SCON=0xD0; //串行口工作方式3 // ES=1; //開串行口中斷 EA=1; ET0=1; //T0開中斷 ET1=1; //T1開中斷 IT0=1; //外部中斷0邊沿觸發, EX0=1;//中斷允許 IT1=1; // 外部中斷1邊沿觸發? EX1=1;//中斷允許 TR1=1; //啟動T1 TR0=1; //啟動T0 } /**********看門狗***************/ void watchdog() { WDT_CONTR = 0x3f; } /***************************/ void main(void) {uchar chg_code,key; ini(); init_key(); watchdog();//看門狗 for(;;) { // key=scankb();//鍵盤掃描 key= read_key(); chg_code=change_code(key);//代碼轉換 // series_sent(chg_code);//串口發送 ps_send(chg_code);//PS/2發送 watchdog(); } }