PS2协议与实例

来源:本站
导读:目前正在解读《PS2协议与实例》的相关信息,《PS2协议与实例》是由用户自行发布的知识型内容!下面请观看由(电工技术网 - www.9ddd.net)用户发布《PS2协议与实例》的详细说明。

设计目的:

1.熟悉PS/2协议的原理

2.学习单片机的使用

设计内容:

依照PS/2协议,在51芯片上开发汇编程序,使得按下开发板上的按键时,能够在PC机上输出a、b、c。

实验环境:

开发板、STC12C2052AD芯片、PS/2线、PC机、Keil软件、STC-ISP程序下载器

相关参数:

单片机振荡频率6MHz(具体情况请看此型号单片机用户手册)

指令周期0.5微秒(51型单片机的指令周期是其振荡频率的12分之一)

PS/2连接器引脚定义(见参考文献《PS/2技术参考》)

能够接受的键盘时钟信号频率10-20KHz(最大33KHz,推荐设为15KHz)

设计思想:

使用开发板上的按钮产生中断信号,使单片机进入相应的中断处理程序,从而向PC机发送相应的扫描码。PC机主板中有一个解码芯片,此芯片在收到扫描码之后,引发PC机操作系统的中断(I/O的中断),转到操作系统中的中断处理程序,从面在系统中输出相应字符。

原理:

实际的通用键盘上的每一个键都对应一个唯一个扫描码,这些键会在极短的时间内被扫描一遍,以确认它们有没有被按下,如果某个键被按下了,就发送其相应的扫描码。而在开发板上,51芯片有三个按键,对应芯片上的两个中断口和一个定时/计数器输入口。中断接口可以直接使用,当按下键时就触发中断,而定时/计数器需要设置为初始值为FFH,一旦按下键便会溢出而产生中断的计数器。

主机与键盘有四根线相连,时钟信号数、数据线、接地线、电源线。

时钟信号在任何时刻都是由键盘产生的,PC机在时种的下降沿接收数据线上的信号,要是PC机向键盘发送数据,则键盘在时钟的上升沿接收数据线上的数据。虽是由键盘产生时钟信号,但是PC机对总线有着绝对的控制权,只要其将时钟线拉低(高低电平信号有这样的特性:只有一端的信号为低电平,则整条线的信号都为低电平。这就是为什么要向单片机I/O口输出一个信号,要先将外部输入单片机这个I/O口的信号释放(拉高)。否则输出的永远都是低电平),就要以抵制键盘的输出。

总线上有这些几种状态:

1、PC等待键盘输出状态(键盘可以输出状态):CLK=1,DATA=1;

2、键盘等待PC输出状态(PC可以输出状态):CLK=1,DATA=0(这个状态之前还有一些状态要生产生的,详情请见参考文献《PS/2技术参考》)

3、正在输出状态:此时的时钟线与数据线上的信号没有定值,依据所要发送的数据不同而不同,CLK=X,DATA=X

键盘从外部存储器中读取相应键位的扫描码,当要改变某个键所要发送的扫描码时,只需改变外部存储器中对应位置的扫描码,这样就可以方便地改变某键所要发送的扫描码。在存放扫描码时,只需将扫描码按顺序存放,如E0,70按存储地址从小到大顺序地排列。因为通码(make code)最多只有两个十六进制数,且如有两个则第一个必是E0H,而断码(break code)最多只有三个,且如果有三个,则第一个必是E0H,如果有二个,则第一个必是F0H。所以,当发送时,如果发现第一个是E0H或F0H的话,则再发送其后的一个扫描码。

注意事项:

1、 发送8个数据位时,是低位先发送(least significant bit first),如果是用高位先发送,主机自然是无法识别会发送的数据,会报警;

2、 如果想要精确计算时间,那么像子程序调用语句会占用两个指令周期也应该考虑到;

3、 连接线应该连在指示灯靠近51芯片的一端,否则无法接收到主机发来的信号;PS/2

4、 汇编程序前的org 语句必须按其指示的地址大小排列,小的在前,大的在后;

程序:

;=======================================

;program

;check clk and data before every 8 bit data sending

;a function is created for send all 11bit data

;a function is created for parity calculating

;CAPSLOCK :BIG LETTER P1.3=0,SMALL LETTER P1.3=1

;=======================================

;=======================================

;VARS USED LOCALY

;R0 IS USED LOCALY AS A COUNTER

;20H.1 20H.2 20H.3 20H.4 IS USED IN FUNCTION AS TEMP VAR

;R3,R4,R5 USED LOCALLY IN DELAY()

;===================================

;Define Samples

;====================================

MCLK EQU P1.2 ;VALUE OF CLOCK LINE

MDATA EQU P1.1 ;VALUE OF DATA LINE

SCAN EQU R1 ;VALUE OF THE SCAN CODE

RECV EQU R2 ;VALUE RECEIVED BY KEYBOARD

RECV2 EQU R6 ;THE VALUE RECEIVED SECONDLY

NEXTBIT EQU CY ;VALUE OF THE BIT WILL SENT NEXT

PARITY EQU 20H.1 ;VALUE OF PARITY

TEMP EQU 20H.2 ;THIS BIT IS FOR TEMPORITARY USE

TEMP1 EQU 20H.3 ;THIS BIT IS FOR TEMP USE

TEMP8BIT EQU 21H

LOOPCOUNTER EQU 30H ;COUNTER SPECIAL FOR SENDALLBIT

SCROLLLOCK EQU P1.5

CAPSLOCK EQU P1.6

NUMLOCK EQU P1.7

ERROR_LIGHT EQU P1.4 ;PARITY ERROR

ERROR_LIGHT_STOPBIT EQU P1.3 ;STOP BIT RECEIVE ERROR

;===================================;===================================

;ORG

;===================================

ORG 00H

JMP MAINORG 0003H

LJMP K1DOWNORG 000BH

LJMP K3DOWNORG 0013H

LJMP K2DOWN;============================================================

;MAIN

;============================================================

MAIN:;==============================

;SET INTERRUPTER AND TIMER

mov ie,#10000101B ;中断使能

mov ip,#00H ;中断优先

mov tcon,#00000101b ;中断为电平触发 ;TIME0 AS A BUTTON

MOV TMOD,#06H

MOV TH0,#0FFH

MOV TL0,#0FFH

SETB ET0

SETB TR0

;==============================

;==============================

;SET CLK AND DATA LINE TO NORMAL STATUS

SETB MCLK

SETB MDATA

;============================== SETB CAPSLOCK ;CAPSLOCK OFF(1)

SETB NUMLOCK ;NUMLOCK OFF(1)

SETB SCROLLLOCK ;SCROLLLOCK OFF(1)CHKSTATUS:

JNB MCLK,CHKSTATUS ;IF MCLK==0 THEN GOTO CHKSTATUS

JB MDATA,CHKSTATUS ;IF MDATA==1 THEN GOTO CHKSTAUS

;NOW MCLK=1 AND MDATA =0 ,READY TO RECEIVE DATA FROM PC

LCALL RECV_CHK_SEND ;RECEIVE DATA FROM PCLJMP CHKSTATUS ;WAIT FOR BREAK;============================================================

;///////MAIN

;============================================================

;===============================================================================================

; AREA FOR FUNCTION

;===============================================================================================

LJMP ENDOFFILE

;====================================

;IN THIS FUNCTION: RECEIVE ALL 10BIT DATA BY RECEIVEALLBIT() AND CHK WHETHER IT'S CORRECT THEN SEND CORRESPONDING SCANCODE TO PC

;====================================

RECV_CHK_SEND:

CLR P1.0 ;INDICATE START RECEIVEING

LCALL RECEIVEALLBIT ;RECV PARITY TEMP1

MOV A,RECV

CJNE A,#0EDH,RECV_CHK_SEND_END

;=====================

;RECV==EQ NOW SET LED

;CHKSTATUS_2:

; JNB MCLK,CHKSTATUS_2 ;IF MCLK==0 THEN GOTO CHKSTATUS

; JB MDATA,CHKSTATUS_2 ;IF MDATA==1 THEN GOTO CHKSTAUS

LCALL DELAY50

LCALL DELAY50

LCALL RECEIVEALLBIT ;RECV PARITY TEMP1

;========================

;THE CODE IS RIGHT AFTER THIS ,TESTED BY MOV "RECV,#00000110"

MOV A,RECV RRC A ;NOW C=LEAST BIT OF A

CPL C ;PC: C=1 ON ;C=0 OFF NOW IN KEYBOARD C=1 OFF(LIGHT OFF) C=0 ON(LIGHT ON)

MOV SCROLLLOCK,C RRC A ;NOW C=LEAST BIT OF A

CPL C ;PC: C=1 ON ;C=0 OFF NOW IN KEYBOARD C=1 OFF(LIGHT OFF) C=0 ON(LIGHT ON)

MOV NUMLOCK,C RRC A ;NOW C=LEAST BIT OF A

CPL C ;PC: C=1 ON ;C=0 OFF NOW IN KEYBOARD C=1 OFF(LIGHT OFF) C=0 ON(LIGHT ON)

MOV CAPSLOCK,C SETB P1.0 LJMP RECV_CHK_SEND_END

;/====================RECV_CHK_SEND_END:

RET

;====================================

;////////IN THIS FUNCTION: RECEIVE ALL 10BIT DATA BY RECEIVEALLBIT() AND CHK WHETHER IT'S CORRECT THEN SEND CORRESPONDING SCANCODE TO PC

;====================================;====================================

;RECIEVE ALL THE 10BIT DATA FROM PC AND CHECK WHETHER IT'S RIGHT

;SAVE THE 8BIT DATA TO RECV

;TEMP1: PARITY FIGURED OUT

;PARITY: PARITY RECEIVED

;====================================

RECEIVEALLBIT:

MOV LOOPCOUNTER,#0008H

RECV8BIT_LOOP:

LCALL RECEIVEONE ;GET ONE BIT AND SAVE IT TO CY

RRC A ;RIGHT MOVE THIS BIT TO A

DJNZ LOOPCOUNTER,RECV8BIT_LOOP ;LOOP FOR 8 TIMES

MOV C,P ;C=P(THIS DOUBLE PARITY JUST RECEIVED

CPL C ;CHANG TO ODD PARITY

MOV TEMP1,C ;STORE THE ODD PARITY TO TEMP1

MOV RECV,A ;RECV=A LCALL RECEIVEONE ;GET PARITY BIT

MOV PARITY,C ;PARITY=C LCALL RECEIVEONE ;PC PULL UP DATA LINE

MOV TEMP,C ;RECEIVE TERMINAL BIT(1) ;MOV P1,RECV ;JUST FOR TESTING

JNB MDATA,STOPBIT_ERROR ; 1==MDATA THEN RECEIVEALLBIT_ERROR ;SEND ACK

LCALL SENDACK MOV C,TEMP1 ; C = PARITY FIGURED OUT

MOV A,#00H ;A=OOH

RRC A ;SAVE C TO A

MOV TEMP8BIT,A ;SAVE A TO TEMP8BIT MOV C,PARITY

MOV A,#00H

RRC A CJNE A,TEMP8BIT,PARITY_ERROR ;DATA RECEIV SUCCESSFUL

MOV SCAN,#00H

LCALL SENDALLBIT ;IF THE PROGRAM CAN RUN HERE,INDICATE ALL IS IN GOOD CONDICION

;SCAN 00H TO TELL PC ALL IN IN GOOD

;MOV SCAN,#00H

;LCALL SENDALLBIT LJMP ENDOFSENDALLBIT

;===================

;THE PARITY IS WRONG ,SO KEYBOARD RECEIVED A WRONG DATA

PARITY_ERROR:

CLR ERROR_LIGHT

;MOV SCAN,#0FFH

;LCALL SENDALLBIT

;/==================

LJMP ENDOFSENDALLBIT ;===================

;STOPBIT ERROR

STOPBIT_ERROR:

CLR ERROR_LIGHT_STOPBIT

;MOV SCAN,#0FFH

;LCALL SENDALLBIT

LJMP ENDOFSENDALLBIT

ENDOFSENDALLBIT:

RET

;====================================

;/////////RECIEVE ALL THE 10BIT DATA FROM PC AND CHECK WHETHER IT'S RIGHT

;/////////SAVE THE 8BIT DATA TO RECV

;====================================

;====================================

;SENDACK

;====================================

SENDACK:

LCALL DELAY15

CLR MDATA

LCALL DELAY5

CLR MCLK

LCALL DELAY40

SETB MCLK

LCALL DELAY5

SETB MDATA

RET

;//==================================;====================================

;RECEIVE ONE BIT DATA FROM PC

;SAVE THIS BIT TO CY

;====================================

RECEIVEONE:

LCALL DELAY20

CLR MCLK

LCALL DELAY40

SETB MCLK

LCALL DELAY20

MOV C,MDATA ;SAVE THIS BIT OF DATA TO CY,SAVE IT TO RECV LATER

RET

;====================================

;/////RECEIVE ONE BIT DATA FROM PC

;====================================;====================================

;INVOKE THIS FUNCTION WHEN K1 IS DOWN

;====================================

K1DOWN:

MOV SCAN,#01CH

LCALL SENDALLBIT MOV SCAN,#0F0H

LCALL SENDALLBIT MOV SCAN,#01CH

LCALL SENDALLBIT ;LCALL DELAY ;DON'T PRINT SO FAST

RETI

;====================================

;//////INVOKE THIS FUNCTION WHEN K1 IS DOWN

;====================================

;====================================

;INVOKE THIS FUNCTION WHEN K2 IS DOWN

;====================================

K2DOWN:

MOV SCAN,#032H

LCALL SENDALLBIT MOV SCAN,#0F0H

LCALL SENDALLBIT MOV SCAN,#032H

LCALL SENDALLBIT ;LCALL DELAY ;DON'T PRINT SO FAST

RETI

;====================================

;//////INVOKE THIS FUNCTION WHEN K2 IS DOWN

;====================================;====================================

;INVOKE THIS FUNCTION WHEN K3 IS DOWN

;====================================

K3DOWN:

MOV SCAN,#021H

LCALL SENDALLBIT MOV SCAN,#0F0H

LCALL SENDALLBIT MOV SCAN,#021H

LCALL SENDALLBIT ;LCALL DELAY ;DON'T PRINT SO FAST

RETI

;====================================

;//////INVOKE THIS FUNCTION WHEN K3 IS DOWN

;====================================;====================================

;SEND ALL 11 BIT DATA

;====================================

SENDALLBIT:

;THE VAR SCANCODE MUST BE SET BEFORE THE FUNCTION

;SET CLK AND DATA LINE TO 1

INIT:

SETB MCLK;

SETB MDATA; ;CHECK WHETHER THE CLK AND DATA IS IN STATE THAT CAN TRANSFER DATA

CHKCLKHIGH:

JNB MCLK,CHKCLKHIGH ;IF CLK=0 THEN GOTO CHKCLKHIGH ELSE CONTINUE actually,this is the cache,wait for clk=1 to send the data

LCALL DELAY50 ;DELAY 50us

JNB MCLK,CHKCLKHIGH ;

JNB MDATA,CHKCLKHIGH;IF DATA=0 THEN GOTO CHKCLKHIGH ELSE CONTINUE

;NOW CLK=1 FOR 50US AND DATA=1

LCALL DELAY20; ;DELAY 20US ;================================

;CLK AND DATA CHECK FINISHED ,START DATA TRANSFAN

;================================

STARTSEND:

CLR NEXTBIT ;SET START BIT ;1 PR

LCALL SENDBIT;SENT THE START BIT ;170 PR

;SEND SCAN CODE

;NOW SCAN IS SET BEFOR SENDALLBIT()

;MOV SCAN,#035H ;LET SCAN= THE SCAN CODE OF KEY A ;2 PR

LCALL SENDSCAN ;SEND THE SCAN CODE ;1123 PR

; SEND PARITY ; #### COULD BE BETTER IN SENDING PARITY #########

LCALL CALPARITY

MOV C,PARITY LCALL SENDBIT ;140 PR

;SEND TERMINAL SIGN

SETB NEXTBIT ;TERMINAL SIGN=1 ;1 PR

LCALL SENDBIT ;140 PR

LCALL DELAY50 ;DELAY 50us

LCALL DELAY20 ;DELAY 50us

;FINISHED SENDING DATA USED 1950 PERIODS

RET ;SENDALLBIT END

;=====================================

;=====================================

;long time delay

;=====================================

Delay:

MOV R3, #000H

MOV R4, #000H

MOV R5, #0DH

Delay_Loop:

DJNZ R3, Delay_Loop

DJNZ R4, Delay_Loop

DJNZ R5, Delay_Loop

RET

;=====================================;=====================================================

;SEND THE SCAN CODE IN VAR SCAN

;PERIODS:1123 PR

;=====================================================

SENDSCAN:

CLR C ;1 PR

MOV A,SCAN ;2 PR

RRC A ;MOVE RIGHT ;1 PR

LCALL SENDBIT ;SEND 7TH ;140 PR RRC A ;MOVE RIGHT ;1 PR

LCALL SENDBIT ;SEND 6TH ;140 PR RRC A ;MOVE RIGHT ;1 PR

LCALL SENDBIT ;SEND 5TH ;170 PR RRC A ;MOVE RIGHT ;1 PR

LCALL SENDBIT ;SEND 4TH ;140 PR RRC A ;MOVE RIGHT ;1 PR

LCALL SENDBIT ;SEND 3TH ;140 PR RRC A ;MOVE RIGHT ;1 PR

LCALL SENDBIT ;SEND 2TH ;140 PR RRC A ;MOVE RIGHT ;1 PR

LCALL SENDBIT ;SEND 1TH ;140 PR RRC A ;MOVE RIGHT ;1 PR

LCALL SENDBIT ;SEND 0TH ;140 PR

RET

;=====================================================;=====================================================

;SEND THE NEXTBIT

;PERIODS:138 PERIODS

;=====================================================

SENDBIT:

MOV MDATA,C ;1 period

LCALL DELAY20 ;42 PERIODS

CLR MCLK ;PULL DOWN THE CLOCK LINE

LCALL DELAY40 ;82 PERIODS

SETB MCLK ;1 PERIODS

LCALL DELAY20 ;12 PERIODS

RET

;=====================================================

;======================================================

;SUB FOR DELAY 16US

;RAM USED:R0

;======================================================

DELAY16:

MOV R0,#003H ;2

DELAY16_IN:DJNZ R0,DELAY16_IN;THIS COMMAND WILL BE EXCUTE FOR 15 TIMES, 2period

RET

;======================================================

;======================================================

;SUB FOR DELAY 32US

;RAM USED:R0

;======================================================

DELAY32:

MOV R0,#00EH ;

DELAY32_IN:DJNZ R0,DELAY32_IN;THIS COMMAND WILL BE EXCUTE FOR 31 TIMES, 2period

RET

;======================================================;======================================================

;SUB FOR DELAY 50US correct?

;RAM USED:R0

;======================================================

DELAY50US:

MOV R0,#01aH ;

DELAY50_LOOP:DJNZ R0,DELAY50_LOOP;THIS COMMAND WILL BE EXCUTE FOR 31 TIMES, 2period

RET

;======================================================;======================================================

;SUB FOR DELAY 20US

;RAM USED:R0

;periods:TOTAL 40PERIODS

;======================================================

DELAY20:

MOV R0,#013H ;RUN 19TIMES 2period

DELAY20_IN:DJNZ R0,DELAY20_IN;THIS COMMAND WILL BE EXCUTE FOR 19 TIMES, 2period

RET

;======================================================;======================================================

;SUB FOR DELAY 5US

;RAM USED:R0

;periods:

;======================================================

DELAY5:

MOV R0,#004H ;RUN 10TIMES ;2period

DELAY5_IN:DJNZ R0,DELAY5_IN;THIS COMMAND WILL BE EXCUTE FOR 4 TIMES, 2period

RET

;======================================================;======================================================

;SUB FOR DELAY 20US correct?

;RAM USED:R0

;periods:TOTAL 40PERIODS

;======================================================

DELAY20US:

MOV R0,#00DH ;RUN 19TIMES 2period

DELAY20US_LOOP:DJNZ R0,DELAY20US_LOOP;THIS COMMAND WILL BE EXCUTE FOR 19 TIMES, 2period

RET

;======================================================

;======================================================

;SUB FOR DELAY 50US

;RAM USED:R0

;PERIODS:100 PERIODS

;======================================================

DELAY50:

MOV R0,#0B1H

DELAY50_IN:DJNZ R0,DELAY50_IN;

RET

;======================================================;======================================================

;SUB FOR DELAY 30US

;RAM USED:R0

;PERIODS:60 PERIODS

;======================================================

DELAY30:

MOV R0,#01DH

DELAY30_IN:DJNZ R0,DELAY30_IN;

RET

;======================================================

;======================================================

;SUB FOR DELAY 15US

;RAM USED:R0

;======================================================

DELAY15:

MOV R0,#00EH

DELAY15_IN:DJNZ R0,DELAY15_IN;

RET

;======================================================;======================================================

;SUB FOR DELAY 40US

;RAM USED:R0

;PERIODS:80 PERIODS

;======================================================

DELAY40:

MOV R0,#27H

DELAY40_IN:DJNZ R0,DELAY40_IN;

RET

;======================================================;======================================================

;CACULATE THE PARITY OF THE CODE

;RAM CHANGED:A,C,PARITY

;INPUT :SCAN

;RETURN VAR:PARITY

;======================================================

CALPARITY:

MOV A,SCAN

MOV C,P

CPL C

MOV PARITY,C

RET

;======================================================

;===================================================================================================================

ENDOFFILE:

END ;END OF THE PROGRAM

提醒:《PS2协议与实例》最后刷新时间 2024-03-14 01:04:54,本站为公益型个人网站,仅供个人学习和记录信息,不进行任何商业性质的盈利。如果内容、图片资源失效或内容涉及侵权,请反馈至,我们会及时处理。本站只保证内容的可读性,无法保证真实性,《PS2协议与实例》该内容的真实性请自行鉴别。