📄 mutiscankey8x8.asm
字号:
.IFNDEF Muti_Scan64key_DEF
key_push .EQU 15 ;define Key Flag bit
key_keep .EQU 14
key_open .EQU 13
;R0 ramBuffer
;Scan_value1st [R0] ;scan return value1
;Scan_value2nd [R0+#1] ;scan return value2
;Scan_value3rd [R0+#2] ;scan return value3
;Scan_value4th [R0+#3] ;scan return value4
Scan_value .ALIAS R0 ;The ram address of scan return data
Scan_buf .ALIAS R1 ;read port temporal
Scan_col .ALIAS R2 ;ScanKey code temporal
Scan_cul .ALIAS R3 ;scan culume index
detect_count .ALIAS R4 ;detected the multikey count
Max_detect_count .EQU 0x0004
debounce_times .EQU 0x0010 ;define debounce time
RowPort .ALIAS PORTB
Row_Mask_In .EQU 0x00FF ; I/P data mask, use bit set Hi
_Check_Code_1st_Bit .EQU 0
_Check_Code_2nd_Bit .EQU 1
_Check_Code_3rd_Bit .EQU 2
_Check_Code_4th_Bit .EQU 3
_Check_Code_5th_Bit .EQU 4
_Check_Code_6th_Bit .EQU 5
_Check_Code_7th_Bit .EQU 6
_Check_Code_8th_Bit .EQU 7
MaxCol .EQU 8
ColPortCtr .ALIAS PCON2B
//SK_PCON_Mask .EQU 0xFFFF ; O/P ctrl mask, use bit set two Hi,
//SK_PCON_Init .EQU 0x5555 ; O/P Ctrl init
//SK_Mask_Out .EQU 0xFF00 ; O/P data mask, use bit set Hi
_SK_1st_Line .EQU 0x8000
_SK_2nd_Line .EQU 0x4000
_SK_3rd_Line .EQU 0x2000
_SK_4th_Line .EQU 0x1000
_SK_5th_Line .EQU 0x0800
_SK_6th_Line .EQU 0x0400
_SK_7th_Line .EQU 0x0200
_SK_8th_Line .EQU 0x0100
_SK_1st_Pin .EQU 15
_SK_2nd_Pin .EQU 14
_SK_3st_Pin .EQU 13
_SK_4th_Pin .EQU 12
_SK_5th_Pin .EQU 11
_SK_6th_Pin .EQU 10
_SK_7th_Pin .EQU 9
_SK_8th_Pin .EQU 8
_SK_1st_Col .EQU 0X4000
_SK_2nd_Col .EQU 0X1000
_SK_3rd_Col .EQU 0X0400
_SK_4th_Col .EQU 0X0100
_SK_5th_Col .EQU 0X0040
_SK_6th_Col .EQU 0X0010
_SK_7th_Col .EQU 0X0004
_SK_8th_Col .EQU 0X0001
_SK_1st_Bit .SET 0x0001
_SK_2nd_Bit .SET 0x0002
_SK_3rd_Bit .SET 0x0004
_SK_4th_Bit .SET 0x0008
_SK_5th_Bit .SET 0x0010
_SK_6th_Bit .SET 0x0020
_SK_7th_Bit .SET 0x0040
_SK_8th_Bit .SET 0x0080
.ENDIF
;----------------------------------------------------------
; Scan key macro
;----------------------------------------------------------
Muti_Scan_64KEY .MACRO ramBuffer ;Scan 8x8 (PortB15~0 O/P -> PortB0~7 I/P)
PUSH IO[SR]
PUSH IO[LCR]
PUSH IO[LSA]
PUSH IO[LEA]
PUSH R0
PUSH R1
PUSH R2
PUSH R3
PUSH R4
PUSH R5
PUSH R6
R0=ramBuffer
CALL @_SCAN_KEY
POP R6
POP R5
POP R4
POP R3
POP R2
POP R1
POP R0
POP IO[LEA]
POP IO[LSA]
POP IO[LCR]
POP IO[SR]
.ENDM
;----------------------------------------------------------
; Scan key main flow
;----------------------------------------------------------
@_SCAN_KEY:
detect_count=#0 ;check if any key is in key keep status
R5=[Scan_value]
R6=Scan_value + #1
R5=R5 OR [R6]
R6=Scan_value + #2
R5=R5 OR [R6]
R6=Scan_value + #3
R5=R5 OR [R6]
BTEST R5.key_keep
IF TC JMP NEW_SCAN ;if no key in keep jmp new_scan
KEY_ST:
R5=Scan_value + detect_count
R5=[R5]
BTEST R5.key_keep
IF TC JMP NO_KEEP
Scan_col=R5 ;assign scan code the same to old scan_value
CALL _SK_Col_Out_Tri ;set all scan line tri-state
CALL _SK_Get_Cul_Pin ;get last scan cul pin
CALL _SK_Set_Line ;select scan line
CALL _SK_Col_Out_Lo ;scan line low
CALL _SK_Delay ;delay
Scan_buf =IO[RowPort] ;read data to buffer
CALL _SK_Get_Row_bit ;get last scan row port to R5
R5 = COM R5
Scan_buf = Scan_buf OR R5 ;check if keep or open
R5 = R5 XOR Scan_buf
R5 = R5 AND #Row_Mask_In
IF EQ JMP KEY_KEEP
JMP KEY_OPEN
NEW_SCAN:
Scan_col=#0
Scan_cul=#0
SCAN_NEXT:
Scan_cul++
R5=#MaxCol
CMP Scan_cul,R5
IF GT JMP CHECK_OVER
Scan_cul--
CALL _SK_Col_Out_Tri ;set all scan line tri-state
CALL _SK_Set_Line ;select scan line
CALL _SK_Col_Out_Lo ;scan line low
Scan_cul++
CALL _SK_Delay ;delay
Scan_buf =IO[RowPort] ;read data to buffer
Scan_buf =Scan_buf AND #Row_Mask_In ;check if keyin
R5=#Row_Mask_In
CMP Scan_buf,R5
IF EQ JMP SCAN_NEXT ;no keyin jmp next col scan
R6=#debounce_times
DEBOUNCE:
;start to debounce
CALL _SK_Delay ;delay
R5=IO[RowPort]
R5=R5 AND #Row_Mask_In
R5=R5 XOR Scan_buf
IF NE JMP SCAN_NEXT ;if debounce fail,jmp next col scan
R6--
R5=#0
CMP R5,R6
IF NE JMP DEBOUNCE
Scan_cul--
;----------------------------------------------------------
; Trans push KEY -> 0 ~ 63 code
;----------------------------------------------------------
SCAN_READ:
_SK_CODE:
BC IO[SR].Carry ;trans colume number to B5-B3
Scan_col = Scan_cul
Scan_col = ROL Scan_col
Scan_col = ROL Scan_col
Scan_col = ROL Scan_col
BTEST Scan_buf._Check_Code_1st_Bit ;check Hi bit
IF TC JMP _SK_CODE_0
BTEST Scan_buf._Check_Code_2nd_Bit
IF TC JMP _SK_CODE_1
BTEST Scan_buf._Check_Code_3rd_Bit
IF TC JMP _SK_CODE_2
BTEST Scan_buf._Check_Code_4th_Bit
IF TC JMP _SK_CODE_3
BTEST Scan_buf._Check_Code_5th_Bit
IF TC JMP _SK_CODE_4
BTEST Scan_buf._Check_Code_6th_Bit
IF TC JMP _SK_CODE_5
BTEST Scan_buf._Check_Code_7th_Bit
IF TC JMP _SK_CODE_6
BTEST Scan_buf._Check_Code_8th_Bit
IF TC JMP _SK_CODE_7
Scan_cul++
LJMP SCAN_NEXT
_SK_CODE_7:
Scan_col++
BS Scan_buf._Check_Code_8th_Bit
_SK_CODE_6:
Scan_col++
BS Scan_buf._Check_Code_7th_Bit
_SK_CODE_5:
Scan_col++
BS Scan_buf._Check_Code_6th_Bit
_SK_CODE_4:
Scan_col++
BS Scan_buf._Check_Code_5th_Bit
_SK_CODE_3:
Scan_col++
BS Scan_buf._Check_Code_4th_Bit
_SK_CODE_2:
Scan_col++
BS Scan_buf._Check_Code_3rd_Bit
_SK_CODE_1:
Scan_col++
BS Scan_buf._Check_Code_2nd_Bit
_SK_CODE_0:
BS Scan_buf._Check_Code_1st_Bit
KEY_PUSH:
BS Scan_col.key_keep
BS Scan_col.key_push
BC Scan_col.key_open
R5 = Scan_value + detect_count
[R5] = Scan_col
detect_count++
R5=#Max_detect_count
CMP detect_count,R5
IF LT JMP SCAN_READ
JMP SCAN_END
CHECK_OVER:
Scan_col=#Row_Mask_In
R5=Scan_value + detect_count
[R5] = Scan_col
detect_count++
R5=#Max_detect_count
CMP detect_count,R5
IF LT JMP CHECK_OVER
JMP SCAN_END
KEY_KEEP:
BS Scan_col.key_keep
BC Scan_col.key_push
BC Scan_col.key_open
R5 = Scan_value + detect_count
[R5] = Scan_col
detect_count++
R5=#Max_detect_count
CMP detect_count,R5
IF LT JMP KEY_ST
JMP SCAN_END
NO_KEEP:
Scan_col= #Row_Mask_In
R5 = Scan_value + detect_count
[R5] = Scan_col
detect_count++
R5=#Max_detect_count
CMP detect_count,R5
IF LT JMP KEY_ST
JMP SCAN_END
KEY_OPEN:
BC Scan_col.key_keep
BC Scan_col.key_push
BS Scan_col.key_open
R5 = Scan_value + detect_count
[R5] = Scan_col
detect_count++
R5=#Max_detect_count
CMP detect_count,R5
IF LT JMP KEY_ST
SCAN_END:
R5=#0X5555
IO[ColPortCtr] = R5
RET
;----------------------------------------------------------
; Set all colume Port used pin = i/p tri-status Lo.
;----------------------------------------------------------
_SK_Col_Out_Tri:
; set output pin bit as tri-state
R5 = #0
; R0 = IO[ColPortCtr]
; R0 = R0 AND #SK_PCON_Mask
IO[ColPortCtr] = R5
RET
;----------------------------------------------------------
; cloume /row set pin line
; trans A(0 ~ 7) to Bit
;----------------------------------------------------------
_SK_Set_Line:
BC IO[SR].Carry
R5 = SHL Scan_cul
R5 = R5 + #_SK_Set_Line_NO
NOP
JMP R5
_SK_Set_Line_NO:
LJMP _SK_Set_Line_0 ;PB15
LJMP _SK_Set_Line_1 ;PB14
LJMP _SK_Set_Line_2 ;PB13
LJMP _SK_Set_Line_3 ;PB12
LJMP _SK_Set_Line_4 ;PB11
LJMP _SK_Set_Line_5 ;PB10
LJMP _SK_Set_Line_6 ;PB9
LJMP _SK_Set_Line_7 ;PB8
LJMP SCAN_NEXT
_SK_Set_Line_0:
R5 = #_SK_1st_Line ;
RET
_SK_Set_Line_1:
R5 = #_SK_2nd_Line ;
RET
_SK_Set_Line_2:
R5 = #_SK_3rd_Line ;
RET
_SK_Set_Line_3:
R5 = #_SK_4th_Line ;
RET
_SK_Set_Line_4:
R5 = #_SK_5th_Line ;
RET
_SK_Set_Line_5:
R5 = #_SK_6th_Line ;
RET
_SK_Set_Line_6:
R5 = #_SK_7th_Line ;
RET
_SK_Set_Line_7:
R5 = #_SK_8th_Line ;
RET
;----------------------------------------------------------
; Set colume port. Scan port = OUTPUT LO, other tri-status;
;----------------------------------------------------------
_SK_Col_Out_Lo:
BTEST R5._SK_1st_Pin ;if bit11 as hi,set pb.11 as output,others scan pins as tri-status
IF TS JMP _SK_1stCol_Lo
BTEST R5._SK_2nd_Pin
IF TS JMP _SK_2ndCol_Lo
BTEST R5._SK_3st_Pin
IF TS JMP _SK_3rdCol_Lo
BTEST R5._SK_4th_Pin
IF TS JMP _SK_4thCol_Lo
BTEST R5._SK_5th_Pin
IF TS JMP _SK_5thCol_Lo
BTEST R5._SK_6th_Pin
IF TS JMP _SK_6thCol_Lo
BTEST R5._SK_7th_Pin
IF TS JMP _SK_7thCol_Lo
BTEST R5._SK_8th_Pin
IF TS JMP _SK_8thCol_Lo
LJMP SCAN_NEXT
_SK_1stCol_Lo:
R5 = IO[ColPortCtr]
; R0 = R0 AND #SK_PCON_Mask
R5 = R5 OR #_SK_1st_Col
IO[ColPortCtr] = R5
RET
_SK_2ndCol_Lo:
R5 = IO[ColPortCtr]
; R0 = R0 AND #SK_PCON_Mask
R5 = R5 OR #_SK_2nd_Col
IO[ColPortCtr] = R5
RET
_SK_3rdCol_Lo:
R5 = IO[ColPortCtr]
; R0 = R0 AND #SK_PCON_Mask
R5 = R5 OR #_SK_3rd_Col
IO[ColPortCtr] = R5
RET
_SK_4thCol_Lo:
R5 = IO[ColPortCtr]
; R0 = R0 AND #SK_PCON_Mask
R5 = R5 OR #_SK_4th_Col
IO[ColPortCtr] = R5
RET
_SK_5thCol_Lo:
R5 = IO[ColPortCtr]
; R0 = R0 AND #SK_PCON_Mask
R5 = R5 OR #_SK_5th_Col
IO[ColPortCtr] = R5
RET
_SK_6thCol_Lo:
R5 = IO[ColPortCtr]
; R0 = R0 AND #SK_PCON_Mask
R5 = R5 OR #_SK_6th_Col
IO[ColPortCtr] = R5
RET
_SK_7thCol_Lo:
R5 = IO[ColPortCtr]
; R0 = R0 AND #SK_PCON_Mask
R5 = R5 OR #_SK_7th_Col
IO[ColPortCtr] = R5
RET
_SK_8thCol_Lo:
R5 = IO[ColPortCtr]
; R0 = R0 AND #SK_PCON_Mask
R5 = R5 OR #_SK_8th_Col
IO[ColPortCtr] = R5
RET
;----------------------------------------------------------
; delay subcall
;----------------------------------------------------------
_SK_Delay:
R5 = #63 ;delay 3.84us clock=16MHZ
LOOP R5
NOP
NOP
NOP
NOP
.ENDL
RET
;----------------------------------------------------------
; Trans 0 ~ 63 code-> push column
;----------------------------------------------------------
_SK_Get_Cul_Pin:
R5=Scan_value + detect_count
R5=[R5]
R5 = R5 AND #0x003F
BC IO[SR].Carry
R5 = SHR R5
R5 = SHR R5
R5 = SHR R5
Scan_cul = R5
RET
;----------------------------------------------------------
; get row port
;----------------------------------------------------------
_SK_Get_Row_bit:
R5=Scan_value + detect_count
R5 = [R5]
R5 = R5 AND #0X0007
R5 = SHL R5
R5 = R5 +#_SK_Get_Row_Bit
NOP
JMP R5
_SK_Get_Row_Bit:
LJMP _SK_Get_Row_1Bit
LJMP _SK_Get_Row_2Bit
LJMP _SK_Get_Row_3Bit
LJMP _SK_Get_Row_4Bit
LJMP _SK_Get_Row_5Bit
LJMP _SK_Get_Row_6Bit
LJMP _SK_Get_Row_7Bit
LJMP _SK_Get_Row_8Bit
_SK_Get_Row_1Bit:
R5 = #_SK_1st_Bit
RET
_SK_Get_Row_2Bit:
R5 = #_SK_2nd_Bit
RET
_SK_Get_Row_3Bit:
R5 = #_SK_3rd_Bit
RET
_SK_Get_Row_4Bit:
R5 = #_SK_4th_Bit
RET
_SK_Get_Row_5Bit:
R5 = #_SK_5th_Bit
RET
_SK_Get_Row_6Bit:
R5 = #_SK_6th_Bit
RET
_SK_Get_Row_7Bit:
R5 = #_SK_7th_Bit
RET
_SK_Get_Row_8Bit:
R5 = #_SK_8th_Bit
RET
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -