这个代码用来驱动PS/2键盘,将得到的键值显示在LCD1206上。源码如下:
#include<mega16.h>
#include<delay.h>
#define LCD_DATA_PORT PORTA //the next three port should be the same
#define LCD_DATA_DDR DDRA //must use the high 4bit
#define LCD_DATA_PIN PINA
#define LCD_RS PORTA.0 //RS lcd
#define LCD_WR PORTA.1//WR lcd
#define LCD_EN PORTA.2 //EN lcd
#define LCD_DRS DDRA.0 //WR direction define
#define LCD_DWR DDRA.1 //RS direction define
#define LCD_DEN DDRA.2 //EN direction define
#define LCD_DATA 0xf0 //DATA PORT
#define clock PIND.2//CLOCK IN
#define data PIND.3//DATA IN
#define uchar unsigned char
#define uint unsigned int
uchar flash conv[47]={'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f','g',
'h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','~','-','=',']',
';','"',',','.','/','[',' '};
uchar temp,tt=0;
bit BF=0,mark=0,first=1;//ready or not
uchar keynum=0x00;//memory key number
uchar sp2key_scan(void);
interrupt [EXT_INT0] void ext_int0_isr(void)
{
if ((temp>0)&&(temp<9))
{
keynum=keynum>> 1;
if (data==1)keynum=keynum|0x80;
}
temp++;
if (temp>10)
{
temp=0;//reset
BF=1;//keyscan ready;
}
}
void LCD_en_write(void) //enable LCD
{
LCD_DEN=1;//SET LCD_EN OUTPUT
LCD_EN=1;//EN=1
delay_us(10);
LCD_EN=0;//EN=0
}
//cord:when 1,write command when 0,write data
//data:command or data you want to write to 1602
void LCD_Write(char cord,unsigned char numb) //write data
{
delay_us(25);
LCD_DRS=1;//SET RS OUTPUT
if(cord==0)LCD_RS=1; //RS=1,write data
else LCD_RS=0;//RS=0,write command
LCD_DATA_PORT&=0X0f; //clr high 4bit
LCD_DATA_PORT|=numb&0xf0; //wirte high 4bit
LCD_en_write();
numb=numb<<4; //turn the low 4bit to high 4bit
LCD_DATA_PORT&=0X0f; //clr high 4bit
LCD_DATA_PORT|=numb&0xf0; //write low 4bit
LCD_en_write();
}
void LCD_init(void) //lcd init
{
LCD_DWR=1;//set en output
LCD_WR=0;//write enable
LCD_DATA_DDR|=LCD_DATA; //set data port out
LCD_EN=1;// set EN out
LCD_RS=1;// set RS out
delay_us(40);
LCD_Write(1,0x28); //4bit show
LCD_Write(1,0x10); //show cursor
LCD_Write(1,0x06); //cursor move right
LCD_Write(1,0x01); //clr
delay_ms(2);
}
void LCD_set_xy( unsigned char x, unsigned char y ) //write address funcation
{
unsigned char address;
if (y==0) address=0x80+x;
else address=0xc0+x;
LCD_Write(1,address);
}
void LCD_write_string(unsigned char X,unsigned char Y,unsigned char flash *s)
{
LCD_set_xy(X,Y); //write address
while (*s) // write the char to show
{
LCD_Write(0,*s);
s++;
}
}
void LCD_write_char(unsigned char X,unsigned char Y,unsigned char numb) //col x=0~15,row y=0,1
{
LCD_set_xy(X,Y); //write address
LCD_Write(0,numb);//write data;
}
void main(void)
{
unsigned char key;
unsigned char jud;
unsigned char t;
DDRD.2=DDRD.3=0;//set portd input (at least INT0 INT1 input)
PORTD.2=PORTD.3=1;//high status
DDRB=0XFF;
PORTB=0XFF;
MCUCR=0x02;
GICR=0B01000000;
delay_ms(200);//delay 4s
LCD_init();
LCD_Write(1,0x0f); //show cursor
LCD_set_xy(0,0);
#asm("sei"); //all interrupt open
for(;;)
{
if(key<48)
{
t=key;key=255;#asm("cli");
if(t==47)//del one byte ??????
{
PORTB.4=!PORTB.4;
LCD_set_xy(jud-1,0);
LCD_Write(0,' ');
LCD_set_xy(jud-1,0);
}
else
{
PORTB.1=!PORTB.1;
if(jud>15){jud=0;LCD_Write(1,0x01);LCD_set_xy(0,0);}
LCD_Write(0,conv[t]);
jud++;
}
#asm("sei");
}
tt=sp2key_scan();//get key number
if(!mark&&tt<255)
{
if(tt==90)first=0;//0xe0
else if(tt==89){mark=1;first=1;}//clear,break up
else if(tt<255&&!mark)key=tt;//down
}
else if(tt<255)mark=0;
}
}
uchar sp2key_scan()
{
unsigned char temp2;
unsigned char k;
temp2=keynum;
if(BF==1&&first)
{
BF=0;keynum=0;
switch ( temp2 )
{
case 0x45: k=0; break; //0
case 0x16: k=1; break; //1
case 0x1e: k=2; break; //2
case 0x26: k=3; break; //3
case 0x25: k=4; break; //4
case 0x2e: k=5; break; //5
case 0x36: k=6; break; //6
case 0x3d: k=7; break; //7
case 0x3e: k=8; break; //8
case 0x46: k=9; break; //9
case 0x1c: k=10; break; //a
case 0x32: k=11; break; //b
case 0x21: k=12; break; //c
case 0x23: k=13; break; //d
case 0x24: k=14; break; //e
case 0x2b: k=15; break; //f
case 0x34: k=16; break; //g
case 0x33: k=17; break; //h
case 0x43: k=18; break; //i
case 0x3b: k=19; break; //j
case 0x42: k=20; break; //k
case 0x4b: k=21; break; //l
case 0x3a: k=22; break; //m
case 0x31: k=23; break; //n
case 0x44: k=24; break; //o
case 0x4d: k=25; break; //p
case 0x15: k=26; break; //q
case 0x2d: k=27; break; //r
case 0x1b: k=28; break; //s
case 0x2c: k=29; break; //t
case 0x3c: k=30; break; //u
case 0x2a: k=31; break; //v
case 0x1d: k=32; break; //w
case 0x22: k=33; break; //x
case 0x35: k=34; break; //y
case 0x1a: k=35; break; //z
case 0x0e: k=36; break; //~
case 0x4e: k=37; break; //-
case 0x55: k=38; break; //=
case 0x29: k=46; break; //SPACE
case 0x5a: k=48; break; //ENTER
case 0x66: k=47; break; //CAPS
case 0x5b: k=39;break; //]
case 0x4c: k=40;break;//;
case 0x52: k=41;break;// '
case 0x41: k=42; break; //,
case 0x49: k=43;break;//.
case 0x4a: k=44;break; // /
case 0x54: k=45; break; //[
case 0xf0: k=89;break;//f0
case 0xe0: k=90;break;//eo
//check up
}
return k;//return key value
}else if(BF==1)
{
BF=0;keynum=0;
switch ( temp2 )
{
case 0x12: k=91; break; //PRINT SCRN
case 0x14: k=92; break; //PAUSE
case 0x70: k=93; break; //INSERT
case 0x6c: k=94; break; //HOME
case 0x7D: k=95; break; //PG UP
case 0x71: k=96; break; //DELETE
case 0x69: k=97; break; //END
case 0x7A: k=98; break; //PG DN
case 0x75: k=99; break; //U ARROW
case 0x6B: k=100; break; //L ARROW
case 0x72: k=101; break; //D ARROW
case 0x74: k=102; break; //R ARROW
case 0x4A: k=103; break;//KP/
case 0x5a: k=104; break; //KP EN
case 0xf0: k=89; break;//f0
default : k=255;
}
return k;//return key value
}
return 255; //no key pull down
}
|