| | 网站首页 | 网络文摘 | 资料下载 | 软件下载 | 零售商城 | IC库存查询 | 维修论坛 | 供求信息 | 图片中心 | 留言本 | | |
![]() |
![]() |
| 您现在的位置: Chinadz.Net-中国电子网 >> 网络文摘 >> IC应用 >> 文章正文 |
|
|||||
| AT89C2051设计的PC/AT键盘 | |||||
作者:佚名 文章来源:本站转载 点击数: 更新时间:2006-9-5 ![]() |
|||||
|
在工业控制、测量仪器等领域,已大量使用嵌入式PC,如 ADVANTECH公司的PC/104、AMD公司的E86嵌入式PC等。它们除具有 PC的功能外,还提供了功能强大的各种标准接口,如:平板 /VGA显示器控制接口、光驱接口、以太网接口、RS-232/422/485 接口、PC/AT键盘接口等。这就为新产品开发的标准化、模块化提供了方便,可大大缩小研发周期,降 低研制成本,快速进入市场。由于嵌入式PC具有标准PC/AT 键盘接口,也就是说,可以用标准的PC/AT键盘来对嵌入式 PC进行操作与控制。但是,在很多实际应用中,由于一般只用到某几个固定的键,并希望键盘具有体积小巧、便于布放等特点,为此,希望能够设计一种小巧、灵活的 PC/AT键盘,来满足各种需求。本文介绍一种由AT89C2051设计实现的 PC/AT键盘。 1 PC/AT键盘的特点 PC/AT键盘由单片微控制器、键盘矩阵和支持逻辑三部分组成。键盘微控制器的主要功能是扫描键盘,以得到有效的闭合键,一旦键被按下或放开,就为系统板产生键代码,将键代码以串行格式传递到系统板,同时产生将键代码转换为供系统板使用的并行数据所需的时钟信号。 AT键盘使用接通键码,其值在00~7F之间,以串行数据格式传递到系统板;每发送一个键码包含11个数据位,即1个起始位、 8个数据位(低位在前,高位在后)、1个奇偶校验位、1个停止位。在键码传送的同时,微控制器还传送1个键码时钟同步信号,用于同步键码数据的接收。键码中每个数据位的传送发生在 键盘时钟的下降沿,时钟的波特率为16 Kb/s。图1为接通键码是2C,即按下t键时,键码的传送格式。
对于PC/AT键盘,如果按下键0.5 s之前放开该键,则键盘电路产生一个断开键码,将这个键码也以串行数据的格式传送出去。AT键盘的断开键码为F0,在断开键码之后再跟接通键码。其中断开键码通知BIOS键盘例程,按下的键序列功能已结束,键已被放开。如果在键按下 0.5 s之后仍未放开该键,则键盘电路产生一个接通键代码(与接通键码相同),并以每秒6个键码的速率(每166.7 ms一个键码)进行传送,此过程直到键盘电路检测到断开代码为止。常用键的键码如表 1所列。
2 硬件设计 键盘电路如图2所示,由ATMEL公司的微控制器AT89C2051 、MAXIM 公司的看门狗自动复位电路MAX813L及键盘矩阵组成。由于AT 89C2051的可用端口为16个,除复位端RES、看门狗信号输出端WDI、键码数据输出端TXD和时钟输出端CLK外,还剩12个可用端口,这样,其最大可独立响应6×6=36个键的输入,可满足工控机常用控制键的要求。 MAX813L为看门狗电路,它实时接收来自AT89C2051的WDI信号,并自动判断两次 WDI信号的间隔时间。当时间间隔小于1.6 s时,其RST输出端保持低电平;当时间间隔大于1.6 s时,其RST输出端输出高电平,AT89C2051被复位。AT89C2051 具有如下特点: ◇ 具有2K字节可编程闪存; 3 软件设计 软件包括定时0中断子程序、定时1中断子程序、主程序等。其中,定时器0定时中断子程序用于定时检测有无键被按下、判断哪个键被按下并确定对应的键码。定时器 1定时中断子程序用于确定输出键码和时钟信号的波特率,并定时输出看门狗信号,用于防止软件出现死机现象。主程序根据有无键被按下标志,确定是否输出键码和同步时钟信号。如有键被按下,则调入由定时中断子程序所确定的键码,输出相应的键码并同时输出同步时钟信 号。主程序流程如图3所示。
4 设计实例 下面为一设计实例,要求所设计的小键盘输出F1、F2、 F3、F4、Page UP、Page Down、Esc、Enter 8个PC/AT PS/2键盘信号。8个按键的一端分别接P3.7、P1.0~P1.6端口,8个按键的另一端为公共 接地端。 全部程序如下所示: KEY: DO; $NOLIST $INCLUDE (REG51.DCL) $LIST DECLARE WDI LITERALLY 'P3_0'; DECLARE SW1 LITERALLY 'P3_7'; DECLARE SW2 LITERALLY 'P1_0'; DECLARE SW3 LITERALLY 'P1_1'; DECLARE SW4 LITERALLY 'P1_2'; DECLARE SW5 LITERALLY 'P1_3'; DECLARE SW6 LITERALLY 'P1_4'; DECLARE SW7 LITERALLY 'P1_5'; DECLARE SW8 LITERALLY 'P1_6'; DECLARE KEY$DATA LITERALLY 'P3_1'; DECLARE KEY$CLK LITERALLY 'P1_7'; DECLARE (DK,KEY$CODE,PARITY,SHIFT$REG,NUMBER,DI,DN) BYTE; DECLARE (T0$INT) BIT; /******* INTERRUPT OF TIMER 1 ********/ TIMER1: PROCEDURE INTERRUPT 3 USING 1; DISABLE; WDI=1; DK=0; TH1=0BEH; TL1=0E6H; DN=800; IF SW1=0 THEN DO; DI=DN; DO WHILE DI>0; DI=DI-1; END; IF SW1=0 THEN DK=1; KEY$CODE=5AH; /*Enter*/ PARITY=0FFH; END; IF SW2=0 THEN DO; DI=DN; DO WHILE DI>0; DI=DI-1; END; IF SW2=0 THEN DO; DK=2; KEY$CODE=76H; /*Esc*/ PARITY=00H; END; IF SW3=0 THEN DO; DI=DN; DO WHILE DI>0; DI=DI-1; END; IF SW3=0 THEN DK=3; KEY$CODE=75H; /*8/up*/ PARITY=00H; END; IF SW4=0 THEN DO; DI=DN; DO WHILE DI>0; DI=DI-1; END; IF SW4=0 THEN DK=4; KEY$CODE=72H; /*2/down*/ PARITY=0FFH; END; IF SW5=0 THEN DO; DI=DN; DO WHILE DI>0; DI=DI-1; END; IF SW5=0 THEN DK=5; KEY$CODE=06H; /*F2*/ PARITY=0FFH; END; IF SW6=0 THEN DO; DI=DN; DO WHILE DI>0; DI=DI-1; END; IF SW6=0 THEN DK=6; KEY$CODE=04H; /*F3*/ PARITY=00H; END; IF SW7=0 THEN DO; DI=DN; DO WHILE DI>0; DI=DI-1; END; IF SW7=0 THEN DK=7; KEY$CODE=0CH; /*F4*/ PARITY=0FFH; END; IF SW8=0 THEN DO; DI=DN; DO WHILE DI>0; DI=DI-1; END; IF SW8=0 THEN DK=8; KEY$CODE=05H; /*F1*/ PARITY=0FFH; END; WDI=0; DN=0; T1$RET: ENABLE; END; /****INTERRUPT OF TIMER 0****/ TIMER0: PROCEDURE INTERRUPT 1 USING 2; DISABLE; WDI=1; IF NUMBER=0 THEN DO; KEY$CLK=0; KEY$DATA=1; END; ELSE DO; KEY$CLK=1; DI=4; DO WHILE DI>0; DI=DI-1; END; IF (SHIFT$REG AND 01H)=0 THEN KEY$DATA=0; IF (SHIFT$REG AND 01H)=1 THEN KEY$DATA=1; DI=4; DO WHILE DI>0; DI=DI-1; END; KEY$CLK=0; NUMBER=NUMBER-1; END; T0$RET: T0$INT=1; WDI=0; ENABLE; END; /*************MAIN PROGRAM***********/ MAIN_PRG: SW1=1; /**** INIT PORT ****/ SW2=1; SW3=1; SW4=1; SW5=1; SW6=1; SW7=1; SW8=1; KEY$CLK=0; KEY$DATA=0; KEY$CODE=00H; PARITY=00H; SHIFT$REG=00H; NUMBER=11; T0$INT=0; DK=0; DI=0; DN=0; TMOD=10H; /*T1 MODE 1*/ IE=0C8H; /****T1 interrupt enable **** TCON=40H; /****T1 begin work ****/ TH1=0BEH; /*T1 100Hz */ TL1=0E6H; TH0=7BH; /*T0 16kHz*/ TL0=7BH; ENABLE; MAIN$LOOP: IF DK=0 THEN GOTO MAIN$END; TMOD=02H; /*T0 BEGIN WORK*/ IE=0C2H; /*T1 STOP WORK*/ TCON=10H; T0$INT=0; SHIFT$REG=00H; WAIT1: IF T0$INT=0 THEN GOTO WAIT1; /*send S bit*/ T0$INT=0; SHIFT$REG=KEY$CODE; WAIT2: IF T0$INT=0 THEN GOTO WAIT2; /*send Key$code*/ SHIFT$REG=SHR(SHIFT$REG,1); T0$INT=0; IF NUMBER>2 THEN GOTO WAIT2; SHIFT$REG=PARITY; WAIT3: IF T0$INT=0 THEN GOTO WAIT3; /*send parity bit*/ T0$INT=0; SHIFT$REG=0FFH; WAIT4: IF T0$INT=0 THEN GOTO WAIT4; /*send ST bit*/ T0$INT=0; DK=0; WAIT5: IF T0$INT=0 THEN GOTO WAIT5; /* KEY$CLK=0 for 300us*/ T0$INT=0; DK=DK+1; IF DK<4 THEN GOTO WAIT5; /****************SEND 0F0H**************/ KEY$CLK=1; KEY$DATA=1; T0$INT=0; DK=0; IE=00H; /*T0 STOP WORK*/ TCON=00H TMOD=10H; /*T1 BEGAN WORK*/ IE=0C8H; TCON=40H; TH1=0BEH; TL1=0E6H; CALL TIME(200); TMOD=02H; /*T0 BEGIN WORK*/ IE=0C2H; /*T1 STOP WORK*/ TCON=10H; T0$INT=0; NUMBER=11; T0$INT=0; SHIFT$REG=00H; WAIT11: IF T0$INT=0 THEN GOTO WAIT11; /*send S bit*/ T0$INT=0; SHIFT$REG=0F0H; WAIT12: IF T0$INT=0 THEN GOTO WAIT12; /*send 0F0H code*/ SHIFT$REG=SHR(SHIFT$REG,1); T0$INT=0; IF NUMBER>2 THEN GOTO WAIT12; SHIFT$REG=0FFH; WAIT13: IF T0$INT=0 THEN GOTO WAIT13; /*send parity bit*/ T0$INT=0; SHIFT$REG=0FFH; WAIT14: IF T0$INT=0 THEN GOTO WAIT14; /*send ST bit*/ T0$INT=0; DK=0; WAIT15: IF T0$INT=0 THEN GOTO WAIT15; /* KEY$CLK=0 for 300us*/ T0$INT=0 DK=DK+1; IF DK<4 THEN GOTO WAIT15; /***************SEND KEY$CODE******************/ KEY$CLK=1; KEY$DATA=1; T0$INT=0; DK=0; IE=00H; /*T0 STOP WORK*/ TCON=00H; TMOD=10H; /*T1 BEGAN WORK*/ IE=0C8H; TCON=40H; TH1=0BEH; TL1=0E6H; CALL TIME(200); TMOD=02H; /*T0 BEGIN WORK*/ IE=0C2H; /*T1 STOP WORK*/ TCON=10H; T0$INT=0; NUMBER=11; T0$INT=0; SHIFT$REG=00H; WAIT21: IF T0$INT=0 THEN GOTO WAIT21; /*send S bit*/ T0$INT=0; SHIFT$REG=KEY$CODE; WAIT22: T0$INT=0 THEN GOTO WAIT22; /*send Key$code*/ SHIFT$REG=SHR(SHIFT$REG,1); T0$INT=0; IF NUMBER>2 THEN GOTO WAIT22; SHIFT$REG=PARITY; WAIT23: IF T0$INT=0 THEN GOTO WAIT23; /*send parity bit*/ T0$INT=0; SHIFT$REG=0FFH; WAIT24: IF T0$INT=0 THEN GOTO WAIT24; /*send ST bit*/ T0$INT=0; DK=0; WAIT25: IF T0$INT=0 THEN GOTO WAIT25; /* KEY$CLK=0 for 300us*/ T0$INT=0; DK=DK+1; IF DK<4 THEN GOTO WAIT25; KEY$CLK=1; KEY$DATA=1; T0$INT=0; DK=0; IE=00H; /*T0 STOP WORK*/ TCON=00H; DO DI=1 TO 300; /*DELAY TIME*/ CALL TIME(20); END; MAIN$END: KEY$CLK=1; KEY$DATA=1; NUMBER=11; SHIFT$REG=0; GOTO MAIN$LOOP; END KEY; 本文介绍的PC/AT键盘具有结构简单、设计灵活性强、易于编程、体积小、成本低的特点,并可 根据用户需要随意设计和布放,对使用工控机的各种测试与控制仪器具有通用性。 |
|||||
| 【发表评论】【加入收藏】【告诉好友】【打印此文】【关闭窗口】 | |||||
| 最新热点 | 最新推荐 | 相关文章 | ||
| 基于AT89C51的电源切换控制器 AT89C2051在自动窗控制器中的 采用实时时钟芯片DS1302+AT8 基于单片机的语音数字联网火 用AT89C51设计智能流量显示仪 AT89C51单片机在数控车床切削 AT89C51单片机在无线数据传输 由AT89C51/55构成的温湿度自 基于AT89C51的激光密码锁的设 AT89C51与nRF401芯片在RFID系 |
网友评论:(只显示最新10条。评论内容只代表网友观点,与本站立场无关!) |
| | 设为首页 | 加入收藏 | 联系站长 | 友情链接 | 版权申明 | | |
![]() |
Copyright ©1998 - 2006 Chinadz.Net中国电子网 ChinaDZ.Com 粤ICP备05002474号 站长:汽车 |