⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 200.asm

📁 用8051实现的PS2协议的PC键盘
💻 ASM
📖 第 1 页 / 共 4 页
字号:
$MOD51
;$TITLE(KEY BOARD FOR IBM AT)
;$DATE(DEC-17-98)
;$NOPAGING
;---------------
; new key layout
;---------------
;---constant definitions---
KeyMask        EQU     07H     ; used to force head, tail pointers in range
; Stack 60H to 7FH
STACK          EQU     5FH     ; one less than actual stack
; Keycode table offset
; AT codes are first, then the bit table for the key
TableCol       EQU     2       ; number of bytes per key in table
BitByteOffset  EQU     1       ; in table
ShiftKeyOffset EQU     03H     ;sea 2003. 64 ; shift key matrix code offset 
;---internal variable declarations---
; 00-07 RO-..-R7 using register bank0
LastDown       DATA    08H     ; stores last key down matrix address
WatchCtr       DATA    09H     ; watchdog counter
DebncPtr       DATA    0AH     ; pointer to debounce queue
CHANGES        DATA    0BH     ; holds keys in given column
ChgMask        DATA    0CH     ; bit mask used to find key that changed
KEY_OFFSET     DATA    0DH
RepeatRate     DATA    0EH     ; keyboard repeat rate
RptCtr         DATA    0FH     ; autorepeat counter
BuzzerCounter  DATA    10H
; 11H-12H not used
WchDogByte     DATA    13H     ; watchdog memory byte
TxCtr          DATA    14H     ; bit counter for sending data to IBM
TenMsCtr       DATA    15H     ; ten millisecond count
RepeatDelay    DATA    16H     ; of keyboard
TEMP           DATA    17H     ; save received byte from AT
LastSent       DATA    18H     ; last byte sent to host
RESEND_BYTE    DATA    19H     ; save byte that is to be resent to AT
; 1AH -1FH not used
DIAGNOSIS      DATA    20H     ; keyboard diagnostic byte
;--------
ShiftPushed    BIT     DIAGNOSIS.4 ; shift key flag
HostReset      BIT     DIAGNOSIS.5   

FLAGS          DATA    21H     ; flags byte 
;----
REPEATING      BIT     FLAGS.0 ; last key down is repeating
SCANNING       BIT     FLAGS.1 ; scan in progress
DelayFlag      BIT     FLAGS.2 ; scan routine pushed a value onto
                               ; debounce delay que so skip next update
ReceivingCommand BIT   FLAGS.3 ; from IBM
RESPONDING     BIT     FLAGS.4 ; sending command response to IBM AT
Cmd2ndByte     BIT     FLAGS.5 ; receiving 2nd data byte from IBM AT
UpLoading      BIT     FLAGS.6 ; sending data(keyinfo,message) to IBM AT

FLAGS2         DATA    22H     
;-----
BadParity      BIT     FLAGS2.1 ; Parity bit bad in reception
DoAAH          BIT     FLAGS2.2 ; Tells warm start to send AAH power up code
WarmStart      BIT     FLAGS2.3 ; warm start - electro static discharge hit
KbIsAble       BIT     FLAGS2.4 ; matrix
NUM_LOCK       BIT     FLAGS2.5 ; num lock status
SCROLL_LOCK    BIT     FLAGS2.6 ; scroll lock status
CAPS_LOCK      BIT     FLAGS2.7 ; caps lock status
; 23H,24H not used
; Keyboard fifo pointer addresses
TailPntr       DATA    25H     ; fifo tail pointer
HeadPntr       DATA    26H     ; fifo head pointer
FifoFul        BIT     26H.7   ; hi bit of headpntr - to show fifo is full

; 27H - 3FH not used

SHIFT_KEY	DATA   28H	;sea 12.9
shift_sign	BIT    SHIFT_KEY.0 ;sea 12.9
shift_ok	BIT    SHIFT_KEY.1 ;sea 12.9

; Image of matrix 40H TO 47H, column0 to 7
; 48H TO 4FH reserved for matrix expansion
ImgLow         DATA    40H     ; status ram low address
ImgHigh        DATA    47H     ; status ram high address
; buffer 50H TO 57H
BufrLow        DATA    50H     ; low address of fifo
BufrHi         DATA    57H     ; high address of fifo
; Debounce delay queue 58H TO 5FH
DebncBot       DATA    58H     ; delay_Queue limits for debouncing
DebncTop       DATA    5FH
; SFR bits
DataOut        BIT     P3.0    ; host data drive line       -RXD
ClockOut       BIT     P3.1    ; host clock drive line      -TXD
ClkIn          BIT     P3.2    ; host clock sense line      -INT0
DataIn         BIT     P3.3    ; host data sense line       -INT1

;---external variable declaration---
Xmem           XDATA   0000H
; timer 0 is used here as a 1 millisecond timer ISR
; configure timer 0 in mode 0 -> 13 bit timer
; will only set TH0 -> 8 most significant bits of 13 bit timer
;*************************************************************
; for 16 Mhz crystal,
; time per tick = 1 / (crystal/12) = 12 / crystal = 0.75 uSEC
; 1 mSEC = 1000 uSEC, no. of ticks = 1000 / .75 = 1333
; Timer 0 (13 bit counter = 2000H (8192) will overflow interrupt).
; counter = 8192 - 1333 = 6859
; 6859 / 32 = 214.3 (prescale 32)-->set TH0 = 214
; 214 * 32 = 6848 --> INT. tIME = (8192 - 6848)*.75 = 1.008 msec
;**************************************************************
; timer 1, serial port not used
; 2 interrupt sources are used : timer0 , int1
; lowest priority interrupts : timer0
;****************************
;   Interrupt Vector Table
;****************************
	ORG 0000
	JMP BEGIN

	ORG 000BH              ; timer0 overflow
	JMP TIMER0

	ORG 0013H              ; external interupt 1,IBM data line went low
	JB UpLoading,IntClr    ; if sending data, ignore this interrupt
	CALL FromHost?         ; else, read command from IBM-AT
IntClr: 
        RETI
;*************************
;    Initialization
;*************************
        ORG 0030H
BEGIN:
	MOV R0,#7FH ;>>
ClearInternal:
	MOV @R0,#0
	DJNZ R0,ClearInternal
MAIN:
;	MOV 8EH,#3H		; sea 12.9   cpu: 89E554RC 
	MOV A,#0		; sea 12.9
	MOV SHIFT_KEY,A		; sea 12.9

	MOV IE,#0              ; disable all interrupts
	MOV TCON,#0            ; stop timer0
   	MOV P1,#0EFH ;>> turn buzzer off
	MOV P3,#0FFH
        CALL IntClr
        CALL IntClr
        CALL IntClr
        CLR A
        MOV PSW,A              ; BANK 0
INIT1:  
        CLR SCANNING         
        CLR ShiftPushed        ; reset shift key flag
        SETB ClockOut          ; clock line high
	SETB DataOut           ; data line high
	SETB ClkIn           
	SETB DataIn          
	JNB ClkIn,INIT1        ; wait for clock to go high
INIT2:  
        MOV SP,#STACK          ; 5FH
	CLR ReceivingCommand   ; not receiving AT commands

	MOV R0,#DebncTop       ; 5FH
INIT3:  
        MOV @R0,#0FFH
        DEC R0
        CJNE R0,#DebncBot - 1,INIT3 ; 58H

        MOV HeadPntr,#BufrLow  ; FIFO_HEAD := 50H
        MOV TailPntr,#BufrLow  ; FIFO_TAIL := 50H
        MOV DebncPtr,#DebncBot ; 58H
        MOV WatchCtr,#100
; setup timer0
	MOV TenMsCtr,#10
	MOV TH0,#214           ;>> for 1 msec. interrupts
	MOV RptCtr,#127        ; make watchdog happy
        MOV IE,#86H            ; enable EXT1,TIMER0 interrupts
        MOV TCON,#14H          ; start timer0-EXT1 edge triggered
	SETB KbIsAble
INIT4:
; initilization signal:
; will turn shift key led on and then stays on until communication with host. 
; then led will be turned off before really starting keyborad routine.
        JNB WarmStart,ColdBoot   
        MOV FLAGS,#0
        JB DoAAH,SendAA
        JMP MainLoop
; set keyboard defaults-power up reset only
ColdBoot:
	MOV RepeatRate,#10     ; default repeat rate, in 10's of msec
	MOV RepeatDelay,#50    ; default repeat delay, in 10's of msec
	SETB ClockOut
	SETB DataOut
	SETB ClkIn
	SETB DataIn
	MOV A,DIAGNOSIS        ; get error flags
	ANL A,#07H             ; single out error bits
	JZ SendAA              ; jump if no errors
        MOV A,#0FDH            ; get failure code 
	CALL ToHost            ; send to host
	JMP ColdCont
SendAA:
	MOV A,#0AAH            ; load power-up reset successful code
	CALL ToHost            ; and send it to the host
	CLR DoAAH
ColdCont:
	SETB WarmStart         ; show that a cold boot has been performed
; due to the speed of xtal we use (12 mhz), it is far too fast
; we need to slow down in order to sync with host, otherwise
; host will think that keyboard is going to send code to it
; then host will lock up. I believe that 100 msec should be long enough.
;***************
;  main loop
;***************
MainLoop: 
        CALL FromHost?       ; see if AT is trying to send to keyboard
        CALL DecodeKey_SendToHost ; key offset to scan code and send
        CALL WatchDog        ; check to make sure timer0 is working
        JMP MainLoop
;*****************************************
;1msec  timer 0 Interrupt Service Routine
;*****************************************
; background

TIMER0:
	using 0	 ; sea 12.6 addition

	PUSH PSW
	PUSH ACC
	PUSH AR0 ;sea 12.6

        MOV A,BuzzerCounter ;>>
        JZ RELOADING
        DJNZ BuzzerCounter,RELOADING
        CLR P1.4 ; turn buzzer off
RELOADING:
	MOV TH0,#214 ; reload timer0
	MOV WchDogByte,#0AAH   ; tweek foreground watchdog memory
        DJNZ TenMsCtr,TIM4     ; if 10 milliseconds have gone by
	MOV TenMsCtr,#10       ; restart 10 msec timer
; test the repeat counter and watchdog
	DEC RptCtr             ; RptCtr used for autorepeat
	MOV A,RptCtr           ; timing and as a background watchdog
	CJNE A,#80H,TIMER0_END ; it should always be less than 128
	SETB WarmStart
	CLR DoAAH
	JMP MAIN
TIM4:
        JB ReceivingCommand,TIMER0_END
	MOV A,TenMsCtr
	CJNE A,#4,TIM8         ; scanning is done on the 4msec
	JMP SCAN_TIME          ; count of the ten msec timer
TIM8:
        CJNE A,#8,TIMER0_END   ; scan also done on the 8 msec count
; Time to scan the keyboard
SCAN_TIME:
        JB SCANNING,TIMER0_END ; if scan not in progress
	JNB KbIsAble,TIMER0_END
	SETB SCANNING          ; show scanning is taking place
	CALL IRET              ; re-enable the timer0 interrupt
; Update the debounce que before jumping to the scan routine
; if this is the 8msec time
	CJNE A,#8,TIM5         ; if time for debounce update
	JBC DelayFlag,TIM5     ; and scan routine hasn't updated it
	MOV KEY_OFFSET,#0FFH   ; initial Key Offset to invalid code
	INC DebncPtr           ; and push it on the debounce que
	MOV A,DebncPtr         ; put pointer in range
	ADD A,#-(DebncTop+1)   ; CY=1 IF A>=DebncTop+1 OR A>DebncTop
	JNC PntrOk             ; if pointer overflows
	MOV DebncPtr,#DebncBot ; set to bottom of que
PntrOk:
	MOV R0,DebncPtr        ; put value into indirect
	MOV @R0,KEY_OFFSET     ; push the byte onto the que
TIM5:
        CALL SCAN_MATRIX

TIMER0_END:
        POP AR0 ;sea 12.6
	POP ACC
	POP PSW
IRET:
        RETI
;******************************
;(1)    Scan Matrix Routine
;******************************
; background
SCAN_MATRIX:
	using 0	 ; sea 12.6 addition

	PUSH AR1 ;sea 12.6

	MOV R1,#ImgLow         ; 40H
ScanLoop:
	CALL ScanColumn
	JZ NextColumn ; no change scan next column
	JMP ValidityTest       ; if any keys changed, go validate them
NextColumn:
	INC R1                 ; else, set up to test next col
        CJNE R1,#ImgHigh + 1,ScanLoop ;>>

;---------------sea----------------------
;	JNB P1.1,sea1
;sea3:
;	JB  shift_ok,ScanDone
;	CLR shift_sign
;	JMP ScanDone
;sea1:
;	JB shift_sign,ScanDone
;	call Clock20
;	JNB P1.1,sea2
;	JMP sea3
;sea2:
;	call Clock20
;	JNB P1.1,sea4
;	JMP sea3
;sea4:
;	SETB shift_sign
;	SETB shift_ok
;---------------sea----------------------

ScanDone:
	CLR SCANNING           ; show we are done scanning

	POP AR1 ;sea 12.6

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -