原文转自:http://user.qzone.qq.com/345630492/blog/1260355328?ptlang=2052
这是我们组最近做的MCF52259开发板的测试程序。
PS2键盘接口有6根线,但只用了其中的4根:一根时钟线,一根数据线,另外两根是电源,数据在时钟的下降沿后有效。现在只用键盘作为输入,而并不对键盘发控制命令所以就用52259的一个外部中断作为时钟信号的输入,并设置为下降沿触发。
键盘在有键按下或按住不放时发送通码,键放开时发送断码,每个键的这两个码都是不一样的,在接收到码值后进行查表就能知道按下的具体是哪个键了,在这里是建了个3列的数组,第一列放的是对应的码值,第二列是键的第一功能,第三列是键的第二功能。这一系列的操作都放在中断程序里。为了提高查表的效率可以把表里的数据按照键的使用的频率进行排列。
代码如下:
#include "MCF52259_UART_driver.h"
#include "MCF52259_PS2_driver.h"
//用外部中断7作为PS2键盘的输入,
//接收到键盘的按键后将对应的ASCII码用串口0发送到PC机
//可接收的键包括小键盘的数据,1~0,及26个字母
//CapasLK键 shift 及回车键
uint8 key_ASCII;
uint8 decode_data[][3]=
{
{0x2B,'f','F'},//F
{0x3B,'j','J'},//J
{0x23,'d','D'},//D
{0x33,'h','H'},//H
{0x43,'i','I'},//I
{0x32,'b','B'},//B
{0x21,'c','C'},//C
{0x1C,'a','A'},//A
{0x24,'e','E'},//E
{0x42,'k','K'},//K
{0x34,'g','G'},//G
{0x4B,'l','L'},//L
{0x3A,'m','M'},//M
{0x31,'n','N'},//N
{0x44,'o','O'},//O
{0x4D,'p','P'},//P
{0x15,'q','Q'},//Q
{0x2D,'r','R'},//R
{0x1B,'s','S'},//S
{0x2C,'t','T'},//T
{0x3C,'u','U'},//U
{0x2A,'v','V'},//V
{0x1D,'w','W'},//W
{0x22,'x','X'},//X
{0x35,'y','Y'},//Y
{0x1A,'z','Z'},//Z
{0x70,'0'},//KP0
{0x69,'1'},//KP1
{0x72,'2'},//KP2
{0x7A,'3'},//KP3
{0x6B,'4'},//KP4
{0x73,'5'},//KP5
{0x74,'6'},//KP6
{0x6C,'7'},//KP7
{0x75,'8'},//KP8
{0x7D,'9'},//KP9
{0x45,'0',')'},//0
{0x16,'1','!'},//1
{0x1E,'2','@'},//2
{0x26,'3','#'},//3
{0x25,'4','$'},//4
{0x2E,'5','%'},//5
{0x36,'6','^'},//6
{0x3D,'7','&'},//7
{0x3E,'8','*'},//8
{0x46,'9','('}//9
};
void ps2_in_init(void)
{
//data pin
MCF_GPIO_PUCPAR|=MCF_GPIO_PUCPAR_URTS2_GPIO;
MCF_GPIO_DDRUC&=~MCF_GPIO_DDRUC_DDRUC2;
//clock pin
MCF_GPIO_PNQPAR&=~(3<<14);//MCF_GPIO_PNQPAR_IRQ7_IRQ7;
MCF_GPIO_PNQPAR|=MCF_GPIO_PNQPAR_IRQ7_IRQ7;
MCF_GPIO_DDRNQ&=~MCF_GPIO_DDRNQ_DDRNQ7;
//level and edge assign
MCF_EPORT_EPPAR|=MCF_EPORT_EPPAR_EPPA7_FALLING;
//direction
MCF_EPORT_EPDDR&=~MCF_EPORT_EPDDR_EPDD7;
MCF_EPORT_EPDR|=MCF_EPORT_EPDR_EPD7;
//interrupt enable
MCF_EPORT_EPIER|=MCF_EPORT_EPIER_EPIE7;
//enable interrupt
MCF_INTC0_IMRL&=~MCF_INTC_IMRL_MASKALL;
MCF_INTC0_IMRL&=~MCF_INTC_IMRL_INT_MASK7;
MCF_INTC0_ICR07=MCF_INTC_ICR_IP(2)+MCF_INTC_ICR_IL(2);
}
uint16 odd_check(uint16 data)
{
uint16 result="0";
uint8 i;
for(i=0;i<9;i++)
{
result^=data;
data>>=1;
}
result&=1;
return result;
}
uint8 decode(uint8 code)
{
static uint8 Break="0";
static uint8 Caps="0";
static uint8 Shift="0";
uint8 i;
if(Break==1)
{
Break="0";
if(code==0x12||code==0x59) Shift="0";
// uart0_putstr("break1");
return 0;
}
if(code==0xF0)
{
Break="1";
// uart0_putstr("break0");
return 0;
}
switch (code)
{
case 0x12: Shift="1"; return 0;//L shift
case 0x59: Shift="1"; return 0;//R shift
case 0x58: Caps^=1; return 0;//Capslk
case 0x5A: return '\n';//enter
}
i=0;
while(i<46&&decode_data[0]!=code)
{
i++;
}
if(i>=46) return 0;
else
{
if(i>=0&&i<=25) return decode_data[(Caps^Shift)+1];
else return decode_data[Shift+1];
}
}
__declspec(interrupt:0)uint8 irq7_handle(void)//source 7
{
static uint16 data="0";
static uint16 rece_data[3]={0,0,0};
static uint8 flag="0";
uint16 temp="0";
static uint8 bytenum="0";
MCF_EPORT_EPFR|=MCF_EPORT_EPFR_EPF7;
if(flag==0&&DATA==1)
{
uart0_putstr("start wrong\n");
return 0;
flag++;
}
else
{
temp=(uint16)DATA;
data|=temp<<flag;
flag++;
}
if(flag==11)
{
flag="0";
data&=~(1<<10);
data>>=1;
if(odd_check(data))
{
data&=~(1<<8);
uart0_putchar(decode(data));
}
else uart0_putstr("odd check wrong\n");
data="0";
}
}
文章评论(0条评论)
登录后参与讨论