1. 程式人生 > >一個PS/2模擬鍵盤的設計

一個PS/2模擬鍵盤的設計

;=======================================
;
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 LINEMDATA EQU P1.1;VALUE OF DATA LINESCAN EQU R1        
;VALUE OF THE SCAN CODERECV EQU R2        ;VALUE RECEIVED BY KEYBOARDRECV2 EQU R6    ;THE VALUE RECEIVED SECONDLYNEXTBIT EQU CY   ;VALUE OF THE BIT WILL SENT NEXTPARITY EQU 20H.1;VALUE OF PARITYTEMP   EQU 20H.2;THIS BIT IS FOR TEMPORITARY USETEMP1  EQU 20H.3;THIS BIT IS FOR TEMP USETEMP8BIT EQU 21H
LOOPCOUNTER EQU 30H 
;COUNTER SPECIAL FOR SENDALLBITSCROLLLOCK EQU P1.5
CAPSLOCK EQU P1
.6
NUMLOCK EQU P1
.7
ERROR_LIGHT EQU P1
.4;PARITY ERRORERROR_LIGHT_STOPBIT EQU P1.3;STOP BIT RECEIVE ERROR
;
===================================;===================================
;
ORG
;
===================================ORG 00H
JMP MAIN

ORG 0003H
LJMP K1DOWN

ORG    000BH
LJMP K3DOWN

ORG 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 PC     
LJMP 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 LATERRET
;====================================
;
/////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 FASTRETI
;====================================
;
//////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 FASTRETI
;====================================
;
//////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 FASTRETI
;====================================
;
//////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 PRRET
;=====================================================;=====================================================
;
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 PERIODSRET
;=====================================================;======================================================
;
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,    2periodRET
;======================================================;======================================================
;
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,    2periodRET
;======================================================;======================================================
;
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,    2periodRET
;======================================================;======================================================
;
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,    2periodRET
;======================================================;======================================================
;
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,    2periodRET
;======================================================;======================================================
;
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,    2periodRET
;======================================================;======================================================
;
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