- #include <iom16v.h> //包含型號頭文件
- #include <macros.h> //包含"位"操作頭文件
- #include <stdio.h> //標準輸入輸出頭文件
- #include <AVR_PQ1A.h> //包含自定義常量頭文件
- #include "YJ1602.C"
- #pragma interrupt_handler Int0:2 //外部中斷0中斷函數聲明
- #pragma data:code //將譯碼表放在FLASH
- const uchar unshifted[][2]= //shift鍵沒按下譯碼表
- {
- 0x0e,'`',
- 0x15,'q',
- 0x16,'1',
- 0x1a,'z',
- 0x1b,'s',
- 0x1c,'a',
- 0x1d,'w',
- 0x1e,'2',
- 0x21,'c',
- 0x22,'x',
- 0x23,'d',
- 0x24,'e',
- 0x25,'4',
- 0x26,'3',
- 0x29,' ',
- 0x2a,'v',
- 0x2b,'f',
- 0x2c,'t',
- 0x2d,'r',
- 0x2e,'5',
- 0x31,'n',
- 0x32,'b',
- 0x33,'h',
- 0x34,'g',
- 0x35,'y',
- 0x36,'6',
- 0x39,',',
- 0x3a,'m',
- 0x3b,'j',
- 0x3c,'u',
- 0x3d,'7',
- 0x3e,'8',
- 0x41,',',
- 0x42,'k',
- 0x43,'i',
- 0x44,'o',
- 0x45,'0',
- 0x46,'9',
- 0x49,'.',
- 0x4a,'/',
- 0x4b,'l',
- 0x4c,';',
- 0x4d,'p',
- 0x4e,'-',
- 0x52,'\'',
- 0x54,'[',
- 0x55,'=',
- 0x5b,']',
- 0x5d,'\\',
- 0x61,'<',
- 0x69,'1',
- 0x6b,'4',
- 0x6c,'7',
- 0x70,'0',
- 0x71,'.',
- 0x72,'2',
- 0x73,'5',
- 0x74,'6',
- 0x75,'8',
- 0x79,'+',
- 0x7a,'3',
- 0x7b,'-',
- 0x7c,'*',
- 0x7d,'9',
- 0,0
- };
- const uchar shifted[][2]= //shift鍵按下譯碼表
- {
- 0x0e,'~',
- 0x15,'Q',
- 0x16,'!',
- 0x1a,'Z',
- 0x1b,'S',
- 0x1c,'A',
- 0x1d,'W',
- 0x1e,'@',
- 0x21,'C',
- 0x22,'X',
- 0x23,'D',
- 0x24,'E',
- 0x25,'
- ,
- 0x26,'#',
- 0x29,' ',
- 0x2a,'V',
- 0x2b,'F',
- 0x2c,'T',
- 0x2d,'R',
- 0x2e,'%',
- 0x31,'N',
- 0x32,'B',
- 0x33,'H',
- 0x34,'G',
- 0x35,'Y',
- 0x36,'^',
- 0x39,'L',
- 0x3a,'M',
- 0x3b,'J',
- 0x3c,'U',
- 0x3d,'&',
- 0x3e,'*',
- 0x41,'<',
- 0x42,'K',
- 0x43,'I',
- 0x44,'O',
- 0x45,')',
- 0x46,'(',
- 0x49,'>',
- 0x4a,'?',
- 0x4b,'L',
- 0x4c,':',
- 0x4d,'P',
- 0x4e,'_',
- 0x52,'"',
- 0x54,'{',
- 0x55,'+',
- 0x5b,'}',
- 0x5d,'|',
- 0x61,'>',
- 0x69,'1',
- 0x6b,'4',
- 0x6c,'7',
- 0x70,'0',
- 0x71,'.',
- 0x72,'2',
- 0x73,'5',
- 0x74,'6',
- 0x75,'8',
- 0x79,'+',
- 0x7a,'3',
- 0x7b,'-',
- 0x7c,'*',
- 0x7d,'9',
- 0,0
- };
- #pragma data:data //將以后的變量放在RAM
- void Decode(uchar scancode);//聲明函數原型
- uchar edge, bitcount,ascii=' '; //edge為0下降沿中斷,為1上升沿中斷
- //bitcount為位計數值
- //ascii為翻譯后的ASCII碼,初值為空格
- /*******************************************
- 函數名稱: Init_kb
- 功 能: 初始化PS2函數
- 參 數: 無
- 返回值 : 無
- /********************************************/
- void Init_kb(void)
- {
- MCUCR = 2; //設置INT0為下降沿觸發中斷
- edge = 0; //0為下降沿中斷標志,1為上升沿中斷標志
- bitcount = 11; //每次11位數據,一個起始位(0),8個數據位,一個奇偶校驗位,一個停止位(1)
- DDRD&=~BIT(PD2); //配置中斷管腳為輸入
- PORTD|=BIT(PD2); //使能中斷管腳的上拉
- DDRA&=~BIT(PA0); //配置鍵盤數據輸入口為輸入
- PORTA|=BIT(PA0); //使能數據輸入管腳的上拉
- SREG|=BIT(GLOBAL);//打開全局中斷
- GICR|=BIT(EXTINT0);
- }
- /*******************************************
- 函數名稱: Disp_ascii
- 功 能: 在1602液晶上顯示鍵盤上的ASCII碼
- 參 數: ascii--將要顯示的ASCII碼
- 返回值 : 無
- /********************************************/
- void Disp_ascii(uchar ascii)
- {
- LCD1602_gotoXY(1,2);
- LCD1602_sendstr("KEY_ASCII:");
- LCD1602_sendbyte(iDat,ascii);
- }
- /*******************************************
- 函數名稱: Int0
- 功 能: 外部中斷0的中斷服務函數,上升沿中斷讀入11位數據,下降沿調用解碼程序
- 參 數: 無
- 返回值 : 無
- /********************************************/
- void Int0(void)
- {
- static uchar data; // 聲明局部靜態變量來保存掃描碼
- if (!edge) // 如果是下降沿觸發中斷
- {
- if(bitcount < 11 && bitcount > 2) //3到10位是數據,起始位,校驗位和停止位忽略
- {
- data = (data >> 1); //右移保存數據
- if(PINA&0x01)
- {
- data|=0x80; //存儲一個'1'
- }
- }
- MCUCR=3; //設置INT0為上升沿觸發中斷
- edge=1; //設置上升沿中斷標志
- }
- else //如果是上升沿觸發中斷
- {
- MCUCR=2; //設置INT0為下降沿觸發中斷
- edge=0; //設置下降沿中斷標志
- if(--bitcount==0) //如果11位全部接收完畢
- {
- Decode(data); //將掃描碼翻譯成ASCII碼
- bitcount = 11; //重新設為11位數據
- }
- }
- }
- /*******************************************
- 函數名稱: Decode
- 功 能:
- 參 數: scancode--需要翻譯的掃描碼
- 返回值 : 無
- /********************************************/
- void Decode(uchar scancode)
- {
- static uchar up=0,shift=0; //up為通、斷碼標志,shift為shift鍵按下標志
- uchar i;
- if (!up) //已接收的11位數據是通碼(up為0)
- {
- switch (scancode)//開始翻譯掃描碼
- {
- case 0xF0: //鍵盤釋放標志(隨后的一個字節是斷碼)
- up=1; //設置up為斷碼標志
- break;
- case 0x12: //左shift鍵按下
- shift=1; //設置shift為按下標志
- break;
- case 0x59: //右shift鍵按下
- shift=1; //設置shift為按下標志
- break;
- default:
- if(!shift) //如果shift鍵沒有按下
- { //查找unshifted表,表中左列是掃描碼,右列是對應的ASCII碼
- for(i=0;unshifted[i][0]!=scancode&&unshifted[i][0];i++);
- if(unshifted[i][0]==scancode)
- {
- ascii=unshifted[i][1];
- }
- }
- else //如果shift鍵按下
- { //查找shifted表
- for(i=0;shifted[i][0]!=scancode&&shifted[i][0];i++);
- if(shifted[i][0]==scancode)
- {
- ascii=shifted[i][1];
- }
- }
- break;
- }
- }
- else //已接收的11位數據是斷碼(up為1)
- {
- up = 0; //將斷碼標志復位
- switch (scancode) //檢測shift鍵釋放
- {
- case 0x12 : //左shift鍵
- shift = 0;
- break;
- case 0x59 : //右shift鍵
- shift = 0;
- break;
- default:
- break;
- }
- }
- }
- /*******************************************
- 函數名稱: main
- 功 能: 實現PS2鍵盤的驅動,在1602液晶上顯示鍵盤上的ASCII碼
- 參 數: 無
- 返回值 : 無
- /********************************************/
- void main(void)
- {
- Board_init( ); //初始化開發板
- LCD1602_initial( ); //初始化1602
- Init_kb(); //初始化PS2鍵盤接口
- while(1)
- {
- Disp_ascii(ascii); //顯示翻譯后的ASCII碼
- }
- }
復制代碼 |