/*
连线定义:
C51 ~~ Key
P1.0-7 = DB.0-7
*/
#include <c51.h>
// define P1.0--P1.7
sbit P10=P1^0;
sbit P11=P1^1;
sbit P12=P1^2;
sbit P13=P1^3;
sbit P14=P1^4;
sbit P15=P1^5;
sbit P16=P1^6;
sbit P17=P1^7;
/*
char keyBuf[KEY_RINGBUF_LENGTH]; // key ring buffer
int iKeyHead; // pointer. for head
int iKeyTail; // pointer for tail
*/
char ScanCode[4]={0xfe,0xfd,0xfb,0xf7};
char key;
//int latency; // define the keyboard sensity
void keyInit(void) //initialize key board
{
TMOD=0x20; // T1=mod2
TH1=0xfd; //baudrate=9600
TL1=0xfd;
PCON=0x00;
SCON=0x50; // serial=mod1
TR1=1;
ES=0;
EA=0;
TI=0;
/* iKeyHead=0;
iKeyTail=0;*/
}
int ScanKey(struct KeyStatus *ks) //scan keyboard to get key code
{ // if any key pressed, return key code.
// if pressed, only return code once.
int c;
int i,j;
int key;
ks->NowStatus=KEY_UP;
for (i=0; i<4; i++) //scan
{
c=ScanCode[i];
P1=(c<<4)|0x0f;
delay(5);
c=P1 &0x0f;
if ( c ==0x0f) continue;
for (j=0; j<4; j++) //look up in the scancode tabel
if (!( c & (1<<j) ))
{
key=(i<<2)+j;
#ifdef INCLUDE_CONTROL
if ( key==KEY_CTRL) ks->Ctrl |= CTRL_CODE;
else if ( key==KEY_SHIFT) ks->Ctrl |= SHIFT_CODE;
else
#endif
{
ks->NowStatus=KEY_DOWN;
ks->Key=key;
};
};
}
if (ks->NowStatus==KEY_DOWN && ks->PreStatus==KEY_UP)
{
ks->PreStatus=KEY_DOWN;
return 1;
};
/* ks->Ctrl=0;*/
ks->PreStatus=ks->NowStatus; //still pressed,and not released yet
return 0;
}
// define the return value
#define ENTER 1 // get a line of input
#define CANCEL 0 // canceled the input
#define PAGEUP 2 // page up, need process last page of input
int Edln(char buf[CHAR_BUFFER_LENGTH] ) // edit a line ,and displayed on LCD
{
struct KeyStatus ks;
char cnt;
char c;
cnt=0;
ks.PreStatus=ks.NowStatus=KEY_UP;
while (cnt<CHAR_BUFFER_LENGTH) // avoid overflowing
{
if (ScanKey(&ks)) //get a new key
c=ks.Key;
else continue;
switch (c)
{
case KEY1: c='1'; break;
case KEY2: c='2'; break;
case KEY3: c='3'; break;
case KEY4: c='4'; break;
case KEY5: c='5'; break;
case KEY6: c='6'; break;
case KEY7: c='7'; break;
case KEY8: c='8'; break;
case KEY9: c='9'; break;
case KEY0: c='0'; break;
case KEY_DOT: c='.'; break;
case KEY_SUB: c='-'; break;
case KEY_ENTER:
buf[cnt]=0;
while (ks.PreStatus==KEY_DOWN)
ScanKey(&ks);
return ENTER;
case KEY_BACKSPACE:
if (cnt==0) continue;
cnt--;
lcdInstruction(LCD_SET_DDRAM| (cnt>>1) |0x10 );
prtc(' ');
prtc(' '); //clear one block
delay(10);
lcdInstruction(LCD_SET_DDRAM| (cnt>>1) |0x10 );
if (cnt&0x01)
prtc(buf[cnt-1]); // redraw the unaffected char
continue;
case KEY_CANCEL:
return CANCEL;
case KEY_PAGEUP:
return PAGEUP;
};
buf[cnt]=c;
cnt++;
prtc(c); //displayed on LCD
};
}