打印
[AVR单片机]

驱动开发板上的PS2接口,实现PS2键盘

[复制链接]
3761|6
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
lpydidi|  楼主 | 2010-3-16 22:14 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 lpydidi 于 2010-3-16 22:16 编辑

/*******************************************  
  文件:PS2_KB.C  
  环境:编译为ICC AVR6.25A,仿真为AVR Studio4.10   
  硬件:ATMEGA16芯片  
  日期:2006年12月10日   
  功能:驱动开发板上的PS2接口,实现PS2键盘(支持第2套扫描码)  
  备注:参考《AVR系列单片机C语言编程与应用实例》(清华大学出版社)  
/******************************************/   
#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   
};

相关帖子

沙发
lpydidi|  楼主 | 2010-3-16 22:17 | 只看该作者
#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码   
}   
}

使用特权

评论回复
板凳
suoma| | 2010-3-16 22:27 | 只看该作者
留个印

使用特权

评论回复
地板
xiaoxin1986| | 2010-3-16 23:29 | 只看该作者
好东西,复制下来慢慢看

使用特权

评论回复
5
ethunter| | 2012-3-4 20:38 | 只看该作者
好东西,收藏下了,HOHO

我有点翻箱底子了,这贴给顶上去了

使用特权

评论回复
6
简单ZHANGGUO| | 2013-8-31 20:11 | 只看该作者
不好使啊

使用特权

评论回复
7
ningling_21| | 2013-8-31 20:47 | 只看该作者
简单ZHANGGUO 发表于 2013-8-31 20:11
不好使啊

这程序没用?

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

0

主题

319

帖子

1

粉丝