单片机系统中PS2键盘驱动程序的设计

上传人:无*** 文档编号:135581786 上传时间:2022-08-15 格式:DOC 页数:7 大小:123KB
收藏 版权申诉 举报 下载
单片机系统中PS2键盘驱动程序的设计_第1页
第1页 / 共7页
单片机系统中PS2键盘驱动程序的设计_第2页
第2页 / 共7页
单片机系统中PS2键盘驱动程序的设计_第3页
第3页 / 共7页
资源描述:

《单片机系统中PS2键盘驱动程序的设计》由会员分享,可在线阅读,更多相关《单片机系统中PS2键盘驱动程序的设计(7页珍藏版)》请在装配图网上搜索。

1、单片机系统中PS/2键盘驱动程序的设计 在单片机系统中,经常使用的键盘都是专用键盘.此类键盘为单独设计制作的,成本高、使用硬件连接线多,且可靠性不高,这一状况在那些要求键盘按键较多的应用系统中更为突出.与此相比,在PC系统中广泛使用PS/2键盘具有价格低、通用可靠,且使用连接线少(仅使用2根信号线)的特点,并可满足多种系统的要求.因此在单片机系统中应用PS/2键盘是一种很好的选择. 文中在介绍PS/2协议和PS/2键盘工作原理与特点的基础上,给出了一个在单片机上实现对PS/2键盘支持的硬件连接与驱动程序设计实现.该设计实现了在单片机系统中对PS/2标准104键盘按键输入的支持.使用Keil C

2、51开发的驱动程序接口和库函数可以方便地移植到其他单片机或嵌入式系统中.所有程序在Keil uVision2上编译通过,在单片机AT89C51上测试通过.1 PS/2协议目前,PC机广泛采用的PS/2接口为mini-DIN 6pin的连接器,如图1所示. PS/2设备有主从之分,主设备采用Female插座,从设备采用Male插头.现在广泛使用的PS/2键盘鼠标均在从设备方式下工作.PS/2接口的时钟与数据线都是集电极开路结构,必须外接上拉电阻(一般上拉电阻设置在主设备中).主从设备之间数据通信采用双向同步串行方式传输,时钟信号由从设备产生.1.1 从设备到主设备的通信 当从设备向主设备发送数据

3、时,首先检查时钟线,以确认时钟线是否为高电平.如果是高电平,从设备就可以开始传输数据;反之,从设备要等待获得总线的控制权,才能开始传输数据.传输的每一帧由11位组成,发送时序及每一位的含义如图2所示. 每一帧数据中开始位总是为0,数据校验采用奇校验方式,停止位始终为1.从设备到主设备通信时,从设备总是在时钟线为高时改变数据线状态,主设备在时钟下降沿读人数据线状态.1.2 主设备到从设备的通信 主设备与从设备进行通信时,主设备首先将时钟线和数据线设置为“请求发送”状态,具体方式为:首先下拉时钟线至少100us抑制通信,然后下拉数据线“请求发送”,最后释放时钟线.在此过程中,从设备在不超过10us

4、的间隔内必须检查这个状态,当设备检测到这个状态时,它将开始产生时钟信号.此时数据传输的每一帧由12位构成,其时序和每一位含义如图3所示. 与从设备到主设备通信相比,其每帧数据多了一个ACK位.这是从设备应答接收到字节的应答位,由从设备通过拉低数据线产生,应答位ACK总是为0.主设备到从设备通信过程中,主设备总是在时钟线为低电平时改变数据线的状态,从设备在时钟上升沿读人数据线状态.2 PS/2键盘的编码与命令集2.1 PS/2键盘的编码 目前,PC机使用的PS/2键盘都默认采用第2套扫描码集.扫描码有两种不同的类型:“通码(make code)”和“断码(break code)”.当一个键被按下

5、或持续按住时,键盘会将该键的通码发送给主机;而当一个键被释放时,键盘会将该键的断码发送给主机.根据键盘按键扫描码的不同,可将按键分为3类:第1类按键 通码为一个字节,断码为0xF0+通码形式.如A键,其通码为0x1C;断码为0xF0 0x1C.第2类按键 通码为两字节0xE0+0xXX形式,断码为0xE0+0xF0+0xXX形式.如Right Ctrl键,其通码为0xE0 0x14;断码为0xE0 0xF0 0x14.第3类特殊按键 有两个,Print Screen键,其通码为0xE0 0x12 0xE0 0x7C;断码为0xE0 0xF0 0x7C 0xE0 0xF0 0x12.Pause键

6、,其通码为0xE1 0x14 0x77 0xE1 0xF0 0xl4 0xF0 0x77;断码为空. 组合按键扫描码的发送是按照按键发生的次序,如按下面顺序按左Shift十A键: 按下左Shift键; 按下A键; 释放A键; 释放左Shift键,那么计算机上接收到的一串数据为0x12 0x1C 0xF0 0x1C 0xF0 0x12. 在文中的驱动程序设计中,就是根据按键的分类对其分别进行处理.2.2 PS/2键盘的命令集 主机可通过向PS/2键盘发送命令对键盘进行设置或者获得键盘的状态等操作.每发送一个字节,主机都会从键盘获得一个应答0xFA(“重发resend”和“回应echo”命令例外)

7、.驱动程序在键盘初始化过程中所用的指令:0xED,主机在该命令后跟随发送一个参数字节,用于指示键盘上Num Lock,Caps Lock,Scroll Lock Led的状态;0xF3,主机在这条命令后跟随发送一个字节参数定义键盘机打的速率和延时;0xF4,用于当主机发送0xF5禁止键盘后,重新使能键盘.3 PS/2键盘与单片机的连接电路 PS/2键盘与AT89C51单片机的连接方式如图4所示.P1.0接PS/2数据线;P3.2(INT0)接PS/2时钟线.因为单片机的P1,P3口内部是带上拉电阻的,所以PS/2的时钟线和数据线可以直接与单片机的P1,P3相连接.4 驱动程序设计 驱动程序的开

8、发使用Keil C51语言以及KeiluVision2编程环境.PS/2 104键盘驱动程序主要任务是实现单片机与键盘间PS/2通信,同时将接收到的按键扫描码转换为该按键的键值KeyVal,提供给系统上层软件使用.4.1 单片机与键盘间PS/2通信的程序设计 在PS/2通信过程中,主设备(文中是单片机)是在时钟信号为低时发送和接收数据信号.因为单片机向键盘发送的是指令,需要键盘回应,所以这部分程序采用查询方式;而单片机接收键盘数据时,数据线上的信号在时钟为低时已经稳定,所以这部分程序采用中断方式,且不需要在程序中加入延时程序. 单片机向PS/2键盘发送数据程序代码为:void ps2_sent

9、char(unsigned char sentchar)/ps2主设备向从设备发送数据unsigned char sentbit_cnt= 0x00;unsigned char sentchar_chk = 0x00;EX0=0; /关外部中断0/发起一个传送,发起始位PS2_SGN_CLOCK = 0; /将时钟线拉低并保持100 usdelay100us();PS2_SGN_DATA= 0; /起始位PS2_SGN_CLOCK = 1;/发送DATA0-7for(sentbit_cnt=0;sentbit_cnt=1; /待发送数据右移一位/发送校验位while(PS2_SGN_CLOCK

10、) _nop_(); /等待时钟线变低switch(sentchar_chk)case 0:case 2:case 4:case 6:PS2_SGN_DATA =1;break;/奇校验case 1:case 3:case 5:case 7:PS2_SGN_DATA = 0;break;/奇校验default;break;)while(!PS2_SGN_CLOCK) _nop_(); /等待时钟线变高while(PS2_SGN_CLOCK) _nop_(); /等待时钟线变低PS2_SGN_DATA =1;/发送停止位,停止位总为1while(!PS2_SGN_CLOCK) _nop_();

11、/等待时钟线变高while(PS2_SGN_CLOCK) _nop_(); /等待时钟线变低/接收ACK/if(PS2_SGN_DATA) error();/ACK信号由键盘发出,总为低电平while(!PS2_SGN_CLOCK) _nop_(); /等待时钟线变高EX0= 1; /开外部中断0单片机由PS/2键盘接收数据程序:外部中断0设置为下降沿触发void int0() interrupt 0 using 0 /EX0=0; /关外部中断0switch(ps2_revchar_cnt)case 1:case 8:mcu_revchar=1;if(PS2_SGN_DATA) mcu_re

12、vchar |= 0x01;ps2_revchar_cnt+;break;case 0:ps2_revchar_cnt+;break; /开始位,case 9:ps2_revchar_cnt+;break; /校验位,可添加校验程序case 10: _nop_();/停止位ps2_revchar_cnt= 0;revchar_flag=1;/置接收到数据标识位break;default:break;EX0=1;/开外部中断04.2 键盘扫描码转换程序设计 由于键盘扫描码无规律可循,因此由键盘扫描码获得相应按键的键值(字符键为其ASCII值,控制键如F1,Ctrl等为自定义值),只能通过查表的方

13、式获得.由于按键的3种类型及部分按键对应着两个键值(如A键的键值根据Caps和Shift键状态有0x41(A)和0x61(a)两种),因此综合考虑查表转换速度和资源消耗,设计中使用4个键盘表:键盘扫描码转换基本集和切换集(kb_plain_mapNR_KEYS与kb_shift_mapNR_KEYS);包含E0前缀的键盘扫描码转换基本集和切换集(kbeO_plain_mapNR_KEYS与kbe0_shiftmapNR_KEYS).PS/2 104键盘按键扫描码最大值为0x83,所以设置NR_KEYS为132.所有4个键盘表的定义均为如下形式:KB_MAPMAKE CODE=KEYVAL,如果

14、扫描码对应的按键为空(如KB_MAP0x00),则定义相应键值为NULL_KEY(0x00).以下是键盘扫描码基本集的部分代码实例:kb_plain_mapNR_KEYS=NULL_KEY;0x2C;0x6B;0x69;0x6F;0x30;0x39;NULL_KEY; /扫描码0x400x47/对应按键空,逗号,K,I,O,0,9,空/对应键值0x00,k,i,o,O,9,0x00 ; 如此设计键盘转换表的另一个好处在于,以后如需扩展支持有ACPI、Windows多媒体按键键盘时,只需要将键表中相应处修改即可,如ACPIPower按键通码为0xE0 0x37,修改kbe0_plain_map0

15、x37=KB_ACPI_PWR即可. 特殊按键Pause使用单独程序处理,如果接收到0xE1就转入这段程序.而Print Screen键则将其看作是两个通码分别为0xE0 0x12和0xE0 0x7C的“虚键”的组合键处理.在驱动程序中设定如下全局变量:led_status记录Scroll Lock Led,Num Lock Led和Caps Lock Led的状态(关为0,开为1);agcs_status记录左右Shift Ctrl Gui Alt状态,相应键按下则对应位为1,释放为0.E0_FLAG接到0xE0置1;E1_FLAG接收到0xE1置1;F0_FLAG接收到0xF0置1.按键键

16、值通过KeyVal提供上层程序使用.PS/2键盘扫描码键值转换程序ps2_codetrans()流程框架如图5所示.第1类按键的扫描码键值转换程序代码。if(F0_FLAG)/接收扫描码为断码switch(mcu_revchar)/处理控制键case 0x11:ages_status&=0xF7;break;/左alt释放case 0x12:ages_status&=0xFE;break;/左shift释放case 0x14:agcs_status&=0xFD;break;/左ctrl释放case 0x58;if(led_status&0x04) led_status &= 0x03; /ca

17、ps lockelse led_status |=0x04;ps2_ledchange();break;case 0x59: agcs_status &= 0xEF;break;/右shift释放case 0x77: if(led_status&0x02)led_status&=0x05;/num lockelse led_status |=0x02;ps2_ledchange();break;case 0x7E:if(led_status&0x01) led_status&=0x06;/scroll lockelse led_status |=0x01;ps2_ledchange();bre

18、ak;default;break;F0_FLAG=0;else/接收扫描码为通码if(led_status&0x04) caps_flag=1;else caps_flag = 0;if(led_status&0x02) num_flag =1;else num_flag =0;if(agcs_status&0x11) shift_flag = 1;elseshift_flag=0;/扫描码键值转换if(caps_flag = shift_flag) | (!num_flag) KeyVal=kb_plain_mapmcu_revchar;else KeyVal = kb_shift_mapm

19、cu_revchar;switch(mcu_revchar)(/处理控制键或状态键case 0x11:agcs_status|= 0x08;/左alt按下Case 0x12:agcs_status|= 0x01;/左shift按下case 0x14:agcs_status|= 0x02;/左ctrl按下case 0x59:agcs_status|= 0x10;/右shift按下default:break; 第2类按键的扫描码键值转换程序与上面相似.注意:在退出该程序段时,对E0_FLAG和F0_FLAG标识清0.Pause键的处理程序,如果接收到0xE1,置E1_FLAG=1,然后顺次将后续接

20、收到的7个字节数据和Pause的通码后7个字节比较,一致则返回KeyVal=KB_PAUSE;在比较完所有7个字节后清除E1_FLAG标识.键盘初始化程序kb_init()流程为: 上电后,接收键盘上电自检通过信号0xAA,或者自检出错信号0xFC.单片机接收为0xAA则进入下一步,否则进行出错处理. 关LED指示,单片机发送0xED,然后接收键盘回应0xFA,接着发送0x00接收0xFA. 设置机打延时和速率:单片机发送0xF3,接收0xFA,发送0x00(250 ms,2.0 cps),接收0xFA. 检查LED,发送0xED,接收0xFA,发送0x07(开所有LED),接收0xFA.发送0xED,接收0xFA,发送0x00(关LED),接收0xFA. 允许键盘,发送0xF4,接收0xFA.键盘LED改变ps2_ledchange()函数流程:发送0xED;接收0xFA;发送led_status;接收0xFA.5 结语 该驱动程序经Keil uVision2 编译,在AT89C51单片机上运行通过,实现了对PS/2 104键盘的支持,实现了对字符按键大小写切换,Num Lock切换、控制键及组合按键的支持.同时该程序对其他嵌入式或单片机系统中PS/2键盘的应用也有借鉴意义.

展开阅读全文
温馨提示:
1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
2: 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
3.本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
关于我们 - 网站声明 - 网站地图 - 资源地图 - 友情链接 - 网站客服 - 联系我们

copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!