📄 ps2key.c
字号:
#include <AT89S8253.H>
//declare global variables
unsigned char idata address;
unsigned char data LCDCont = 0x00; //00100000, [CS1] [CS2] [write] [command]
unsigned char cKeyStroke; // store keystroke
unsigned char cLastKey0; // the last key stroke
unsigned char cLastKey1; // the pervious key of last key
long iTimeOutTimer = 0; // reset, when PS2 unpressed too long
unsigned char cKeyStrokeBitCount = 0; // counter for PS2 keystroke bits
unsigned char idata row_count = 0x01; //the row number of 8*8 LED martrix
unsigned char idata mData[] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80}; // store column data for 8*8 LED martrix
// PS2 keyboard key mapping table
//0 1 2 3 4 5 6 7 8 9 A B C D E F//
unsigned char code cKeyChar[] = {
0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
0x21, 0x21, 0x21, 0x21, 0x21, 0x51, 0x21, 0x21, 0x21, 0x21, 0x5A, 0x53, 0x41, 0x57, 0x21, 0x21,
0x21, 0x43, 0x58, 0x44, 0x45, 0x21, 0x21, 0x21, 0x21, 0x2D, 0x56, 0x46, 0x54, 0x52, 0x21, 0x21,
0x21, 0x4E, 0x42, 0x48, 0x47, 0x59, 0x21, 0x21, 0x21, 0x21, 0x4D, 0x4A, 0x55, 0x21, 0x21, 0x21,
0x21, 0x21, 0x4B, 0x49, 0x4F, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x4C, 0x21, 0x50, 0x21, 0x21,
0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x31, 0x21, 0x34, 0x37, 0x21, 0x21, 0x21,
0x30, 0x2E, 0x32, 0x35, 0x36, 0x38, 0x21, 0x21, 0x21, 0x2B, 0x33, 0x2D, 0x2A, 0x39, 0x21, 0x21
};
// declare subroutin
void delay(unsigned long);
void tlcd_wc(unsigned char); // write control word to TEXT LCD
void tlcd_wd(unsigned char); // write data word to TEXT LCD
void init_timer0_m1(); // timer0 in mode1, 16bit counter
void main()
{
//=== initialize =====================
address = 0xF6;
init_timer0_m1(); // timer0, mode 1(16-bit counter)
EX1 = 1; // Enable external interrupt 1 for PS2 keyboard
IT1 = 1; // external interrupt 1 negative edge trigger
EA = 1; // Eanble selected interrupt
TR0 = 1; // turn on Timer0, Timer0 for dot matrix LED
// test program for TEXT LCD ============================================================
tlcd_wc(0x0E); // TEXT LCD ON 0000 1111, [1] [display on] [cursor on] [blinking off]
tlcd_wc(0x38); // 2lines and 5x7 0011 1000, 001[8bit],[2 lines][5x7]xx
tlcd_wc(0x01); delay(500); // CLEAR display 00000001, 0000000[clear display], delay 2ms
tlcd_wc(0x02); delay(500); //00000010, 000000[return home]0, delay 2ms
//mData[1] = 0xff;
while(1)
{
iTimeOutTimer ++;
if(iTimeOutTimer >100000) // PS2 keystroke hasn't been pressed with a long time
{
cKeyStrokeBitCount = 0;
cKeyStroke = 0x00;
iTimeOutTimer = 0;
}
} // end of --- while loop
} // end of --- "main"
////== Other SUBROUTINEs start here ===================================
////==================================================================
/* Delay program */
void delay( unsigned long value)
{
while(value>0) value--;
}
/* init Timer0 mode1 (16-bit counter) , user have to turn on TR0 */
void init_timer0_m1()
{
TR0 = 0; // set timer_0 run control 'STOP'
TMOD = (TMOD & 0xF0) | 0x01; //mode_1
ET0 = 1; //set tiemr0 interrupt ON
}
/* write command word to TEXT LCD*/
void tlcd_wc(unsigned char cTempdata)
{
TR0=0; //temperoray stop timer0 (dot matrix LED)
P0 = (LCDCont & 0x0F)|0x00; //CONTROL WORD=0000xxxx, [CS2] [CS1] [write] [command],
P2 = (address & 0xF0)|0x0E; //latch LCDCont to U20
P2 = address; //unselect U20
P0 = cTempdata;
P2 = (address & 0xF0)|0x0C; //select (pulse trigger) TEXT LCD
P2 = address;
TR0=1; //resume dot matrix LED scanning
delay(10); // for LCD requirement 46us
} //end of --- tlcd_wc
/* write data to TEXT LCD */
void tlcd_wd(unsigned char cTempdata)
{
//TR0=0; //temperoray stop timer0 (dot matrix LED)
P0 = (LCDCont & 0x0F) | 0x10; //0001xxxx, [CS2] [CS1] [write] [data]
P2 = (address & 0xF0) | 0x0E; // latch LCDCont to U20
P2 = address; // unselect U20
P0= cTempdata;
P2 = (address & 0xF0) | 0x0C; //select TEXT LCD
P2 = address; // unselect (pulse trigger)TEXT LCD
//TR0=1; //resume dot matrix LED scanning
delay(10); // for LCD requirement 46us
} // end of ---- tlcd_wd
//=== Interrupt subroutine start here=========================
// interrupt routine for PS2 keyboard, (interrupt 2)
void PS2() interrupt 2 using 1
{
cKeyStrokeBitCount ++;
if (cKeyStrokeBitCount==1)
{
cKeyStroke= 0x00;
P1_0 =1;
}
else
{
if (P3_4 == 1) //if the bit of keystroke is '1'
{
switch(cKeyStrokeBitCount) //LSB first
{
case 2: cKeyStroke = cKeyStroke | 0x01; break;
case 3: cKeyStroke = cKeyStroke | 0x02; break;
case 4: cKeyStroke = cKeyStroke | 0x04; break;
case 5: cKeyStroke = cKeyStroke | 0x08; break;
case 6: cKeyStroke = cKeyStroke | 0x10; break;
case 7: cKeyStroke = cKeyStroke | 0x20; break;
case 8: cKeyStroke = cKeyStroke | 0x40; break;
case 9: cKeyStroke = cKeyStroke | 0x80; break;
}
if (cKeyStrokeBitCount >10) //end of get key
{
cKeyStrokeBitCount = 0; // reset the keystroke counter
iTimeOutTimer = 0; // reset time out counter
if ((cKeyStroke != 0xF0) & (cLastKey0!= 0xF0) & cKeyStroke<0x7F) //0xF0 means release a key
{
tlcd_wd(cKeyChar[cKeyStroke]);
}
mData[0] = cKeyStroke;
cLastKey1 = cLastKey0;
cLastKey0 = cKeyStroke;
}
}
}
} /* end of ----interrupt routine for PS2 keyboard, (interrupt 2) */
void timer0() interrupt 1 using 1
{
TR0 = 0; // temporary suspend timer0, and restore data
row_count++;
if (row_count==8) row_count=0;
P0 = mData[row_count] ; //put data to matrix column
P2 = (address & 0xF8) | 0x0D; // select matrix column
P2 = address; // unselect matrix column and restore default address bus value
P0 = row_count | LCDCont; //put dat to matrix row
P2 = (address & 0xF8) | 0x0E; // select matrix row
P2 = address; // unselect matrix row and restore default address bus value
TL0=0; //reload counter for next row
TH0=240; //margin value is 235
TF0=0; // clear the flag of timer0 overflow
TR0 = 1; // resume timer0 for counting
} /* end of ----interrupt routine for timer 0, (8x8 Dot matrix LED) */
// <<<<<< end of "Interrupt subroutine"
//end of program
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -