;
=======================================
;
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 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 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