?? jianpang.asm
字號:
;功能:5*4鍵盤掃描程序
KEYNAME DATA 28H ;b4~b0位記錄按鍵值
;b7-作為按鍵有效標志,b7為0時,表示b4-b0位中的鍵值無效。
;b7為1時,表示b4-b0位記錄的按鍵值有效,且未尚未處理,不能
;接受新按鍵。
;外部程序執行了按鍵功能后,將按鍵有效標志清0,允許接收新按鍵
;b6-保留。
KEYSTU DATA 2AH ;鍵盤按鍵狀態寄存器,其中b2、b1、b0分別記錄最近
;三次定時中斷的按鍵狀態。
DISPBUF DATA 30H ;顯示緩沖區首地址(30H-33H)
PORTDR DATA 34H ;U105(八上升沿D型觸發器74HC273)芯片在內存中的影射地址
;設置影射地址的目的是為了在執行鍵盤掃描過程中不影響
;該輸出口高3位(b7~b5)位內容
TIMEBELL DATA 36H ;蜂鳴器鳴響時間
KEYRTIME DATA 37H ;按鍵時間計數單元
BTIME DATA 40H ;50ms計數單元
DISPB BIT 00H ;50ms定時時間到標志
SDI BIT P1.2 ;串行數據輸入
SCLK BIT P3.4 ;串行移位脈沖
PCLK BIT P3.5 ;并行鎖存脈沖
PORTA EQU 9000H ;8255A口地址
PORTB EQU 9100H ;8255B口地址
PORTC EQU 9200H ;8255C口地址
PORTS EQU 9300H ;8255控制/狀態口地址
PORTD EQU 8800H ;U105(八上升沿D型觸發器74HC273)地址
ORG 0000H
LJMP MAIN
ORG 002BH
LJMP CTC2 ;定時/計數器T2中斷服務程序入口地址
ORG 0050H
;-----主程序開始-----
PROC MAIN
MAIN:
MOV SP, #0DFH ;對于具有256字節內部RAM芯片來說,
;將0E0H-0FFH,共計32字節作為堆棧區
MOV DPTR, #8000H ;關閉蜂鳴器
MOV A, #0FFH
MOVX @DPTR, A
;---復位后,將01H-0FF內部RAM單元清0。
MOV R0, #01H
LOOP1:
MOV @R0, #0
INC R0
CJNE R0, #0, LOOP1
MOV KEYSTU, #07H ;按鍵狀態初始化為111
MOV KEYNAME, #1FH ;將鍵值設為1FH(無效)
;初始化U107(8255)可編程并行I/O接口芯片的工作方式
MOV DPTR, #PORTS ;8255控制/狀態口地址
MOV A, #10011011B ;A口工作在方式0,輸入;B口工作在方式0,輸入;
;C口高、低半部暫時定義為輸入
MOVX @DPTR, A ;送控制字寄存器
;將PD4~PD0置為高電平,使U105(74HC273)輸出級截止,降低功耗。
MOV DPTR, #PORTD ;U105口地址送DPTR
MOV A, PORTDR ;讀U105口在內存中的映象地址
ORL A, #1FH
MOVX @DPTR, A ;數據送U105輸出口
;----初始化定時器T2
MOV TH2, #0B8H ;10ms定時時間的對應初值(6時鐘)
MOV TL2, #00H ;B800H送定時器T2
MOV RCAP2H, #0B8H
MOV RCAP2L, #00H ;初始化重裝初值
; MOV TH2, #0DCH ;10ms定時時間的對應初值(12時鐘)
; MOV TL2, #00H ;DC00H送定時器T2
; MOV RCAP2H, #0DCH
; MOV RCAP2L, #00H ;初始化重裝初值
MOV T2CON, #00000100B ;初始化T2工作方式(自動重裝初值、定時),并啟動T2
;-----初始化中斷控制器
SETB ET2 ;允許定時器T2中斷
SETB EA ;開中斷
MOV BTIME, #5 ;初值為5(即每50ms檢測一次)
LOOP2:
JNB DISPB, LOOP2 ;50ms定時時間未到
CLR DISPB
LCALL KEYCHK ;每50ms讀鍵盤狀態
;檢查鍵盤有無輸入
MOV A, KEYNAME
JNB ACC.7, LOOP2 ;鍵盤按鍵無效,就循環等待
;按鍵有效,先將顯示緩沖區筆段碼左移一個字節
MOV R0, #DISPBUF ;顯示緩沖區首地址送R0
MOV R1, #DISPBUF+1 ;顯示緩沖區地址送R1
MOV R7, #3
LOOP3:
MOV A, @R1
MOV @R0, A
INC R0
INC R1
DJNZ R7, LOOP3
MOV A, KEYNAME ;讀按鍵值
ANL A, #1FH ;保留
MOV KEYNAME, A ;清除按鍵處理標志
CJNE A, #10H, NEXT1
NEXT1:
JC NEXT2
;按下了功能鍵,鍵值>=10H,用兩位LED來顯示
ANL A, #0F0H
SWAP A
MOV DPTR, #LEDTAB ;0-F字模表首地址送DPTR
MOVC A, @A+DPTR ;查表取模
MOV R1, #DISPBUF+2 ;顯示緩沖區地址送R1
MOV @R1, A ;字模送顯示緩沖區
NEXT2:
MOV A, KEYNAME ;讀按鍵值
ANL A, #0FH ;保留低4位
MOV DPTR, #LEDTAB ;0-F字模表首地址送DPTR
MOVC A, @A+DPTR ;查表取模
MOV R1, #DISPBUF+3 ;顯示緩沖區地址送R1
MOV @R1, A ;字模送顯示緩沖區
LCALL S_DISP ;串行顯示
LJMP LOOP2 ;循環等待
END
PROC S_DISP ;串行輸出子程序
S_DISP:
MOV R0, #DISPBUF ;顯示緩沖區首地址送R0
MOV R7, #4
LOOP2:
MOV A, @R0
MOV R6, #8
LOOP1:
CLR SCLK
RLC A
MOV SDI, C ;串行數據送SDI引腳
NOP
SETB SCLK ;鎖存串行輸入數據
DJNZ R6, LOOP1
;取下一顯示碼
INC R0
DJNZ R7, LOOP2
;4位筆段碼已全部移到串入并出芯片中
CLR PCLK
NOP ;延遲一個機器周期
SETB PCLK
RET
END
;定時/計數器T2中斷服務程序
PROC CTC2
CTC2:
PUSH PSW
PUSH ACC
PUSH DPH
PUSH DPL
;檢查是否需要關閉蜂鳴器
MOV A, TIMEBELL
JZ BLEXIT
DJNZ TIMEBELL, BLEXIT
;延遲時間到,關閉
MOV DPTR, #8000H ;關閉蜂鳴器
MOV A, #0FFH
MOVX @DPTR, A
BLEXIT:
;按鍵時間減1處理
MOV A, KEYRTIME
JZ KEYREXIT
;按鍵時間不為0,減1
DJNZ KEYRTIME, KEYREXIT
KEYREXIT:
DJNZ BTIME, EXIT ;溢出次數減1,不為0跳轉
;溢出次數已經回到0,重新初始化溢出次數
MOV BTIME, #5
SETB DISPB ;置位50ms時間到標志
EXIT:
CLR TF2 ;清除定時器T2溢出標志
POP DPL
POP DPH
POP ACC
POP PSW
RETI
END
PROC KEYCHK ;鍵盤檢測
KEYCHK:
;---鍵盤檢測-----------
MOV DPTR, #PORTD ;U105口地址送DPTR
MOV A, PORTDR ;讀U105口在內存中的映象地址
ANL A, #0E0H ;輸出全為低電平的掃描信號
MOVX @DPTR, A ;數據送U105輸出口,將PD4~PD0置為低電平
MOV DPTR, #PORTB ;8255(U107)B口地址送DPTR
MOVX A, @DPTR ;讀出B口
ANL A, #0FH ;屏蔽高4位
CJNE A, #0FH, NEXT1
;等于0F,說明沒有按鍵被按下
SETB C ;將C標志置1
SJMP NEXT2
NEXT1:
CLR C ;C標志清0
NEXT2:
MOV A, KEYSTU
RLC A ;左移一位,記錄最新的按鍵狀態
ANL A, #07H ;保留按鍵狀態
MOV KEYSTU, A ;保存按鍵狀態
;判別按鍵狀態,決定是否執行按鍵掃描
CJNE A, #2, NEXT3
;處于010態,視為干擾,作000態處理
ANL KEYSTU, #0F8H ;重置按鍵狀態
SJMP NEXT5
NEXT3:
CJNE A, #4, NEXT4
;處于100態,說明按鍵已穩定閉合,可進行按鍵掃描
LCALL KEYSCAN ;執行鍵盤掃描,確定哪一按鍵被按下
SJMP NEXT5
NEXT4:
CJNE A, #0, NEXT5
;鍵盤處于穩定按下狀態,執行按鍵重復輸入處理
MOV A, KEYRTIME
CJNE A, #0, NEXT5 ;時間未到!
LCALL KEYSCAN ;執行鍵盤掃描
NEXT5:
;將PD4~PD0置為高電平,使74HC273輸出級截止,降低功耗。
MOV DPTR, #PORTD ;U105口地址送DPTR
MOV A, PORTDR ;讀U105口在內存中的映象地址
ORL A, #1FH
MOVX @DPTR, A ;數據送U105輸出口
;---鍵盤檢測結束-----------
RET
END
PROC KEYSCAN ;鍵盤掃描程序
KEYSCAN:
MOV R7, #5 ;定義掃描次數
MOV R1, #0 ;初始化列地址
MOV R3, #01111111B ;掃描碼初值
LOOP1:
;生成掃描碼
MOV A, R3
RL A ;左移一位(從PD0開始掃描)
MOV R3, A ;保存掃描碼
ANL A, #00011111B ;保留掃描碼
MOV B, A ;暫時保存在B寄存器中
MOV DPTR, #PORTD ;U105口地址送DPTR
MOV A, PORTDR ;讀U105口在內存中的映象地址
ANL A, #0E0H ;保留與鍵盤掃描無關的b7~b5位。
ORL A, B ;與掃描碼或
MOVX @DPTR, A ;數據送U105輸出口,將PD4~PD0置為低電平
NOP ;延遲一個機器周期等待輸出口狀態穩定
MOV DPTR, #PORTB ;B口地址送DPTR
MOVX A, @DPTR ;讀B口
ANL A, #0FH ;屏蔽高4位
XRL A, #0FH ;與0FH異或
JNZ NEXT1 ;不為0,說明該列上有鍵被按下
;反之,該列上沒有按鍵被按下
INC R1 ;列地址加+1,繼續掃描
DJNZ R7, LOOP1
;已掃描了所有列,均沒發現有鍵被按下,本次掃描無效
SJMP EXIT
NEXT1:
JNB ACC.0, NEXT2
;ACC.0位為1,說明0行有按鍵被按下
MOV R2, #0 ;行地址為0
SJMP NEXT5
NEXT2:
JNB ACC.1, NEXT3
;ACC.1位為1,說明1行有按鍵被按下
MOV R2, #1 ;行地址為1
SJMP NEXT5
NEXT3:
JNB ACC.2, NEXT4
;ACC.2位為1,說明2行有按鍵被按下
MOV R2, #2 ;行地址為2
SJMP NEXT5
NEXT4:
;Acc.2~Acc.0均為0,則可肯定是Acc.3為1
MOV R2, #3 ;行地址為3
NEXT5:
;計算行列地址,查表取得鍵名
MOV A, R1
RL A
RL A ;列地址乘4(每列對應4行)
ADD A, R2 ;加行地址
MOV DPTR, #KEYTAB
MOVC A, @A+DPTR ;查表獲取鍵值
MOV KEYNAME, A ;按鍵值送鍵名寄存器
ORL KEYNAME, #80H ;按鍵有效標志置1
MOV KEYRTIME, #25 ;設置按鍵檢測時間,即每秒中允許重復輸入2次
;開蜂鳴器,響一短聲
MOV DPTR, #8000H ;開蜂鳴器
MOV A, #7FH
MOVX @DPTR, A
MOV TIMEBELL, #25 ;響25*10ms,即250Ms
EXIT:
RET
END
;***********按鍵掃描碼、鍵值對應關系******************
KEYTAB:
DB 0FH ;掃描碼為0,即PD0與PB0交叉點對應數字鍵"F"
DB 0EH ;掃描碼為1,即PD0與PB1交叉點對應數字鍵"E"
DB 0DH ;掃描碼為2,即PD0與PB2交叉點對應數字鍵"D"
DB 0CH ;掃描碼為3,即PD0與PB3交叉點對應數字鍵"C"
DB 09H ;掃描碼為4,即PD1與PB0交叉點對應數字鍵"9"
DB 06H ;掃描碼為5,即PD1與PB1交叉點對應數字鍵"6"
DB 03H ;掃描碼為6,即PD1與PB2交叉點對應數字鍵"3"
DB 0BH ;掃描碼為7,即PD1與PB3交叉點對應數字鍵"B"
DB 08H ;掃描碼為8,即PD2與PB0交叉點對應數字鍵"8"
DB 05H ;掃描碼為9,即PD2與PB1交叉點對應數字鍵"5"
DB 02H ;掃描碼為A,即PD2與PB2交叉點對應數字鍵"2"
DB 00H ;掃描碼為B,即PD2與PB3交叉點對應數字鍵"0"
DB 07H ;掃描碼為C,即PD3與PB0交叉點對應數字鍵"7"
DB 04H ;掃描碼為D,即PD3與PB1交叉點對應數字鍵"4"
DB 01H ;掃描碼為E,即PD3與PB2交叉點對應數字鍵"1"
DB 0AH ;掃描碼為F,即PD3與PB3交叉點對應數字鍵"A"
DB 13H ;掃描碼為10,即PD4與PB0交叉點對應"↑"
DB 12H ;掃描碼為11,即PD4與PB1交叉點對應"Enter"
DB 11H ;掃描碼為12,即PD4與PB2交叉點對應"ESC"
DB 10H ;掃描碼為13,即PD4與PB3交叉點對應"↓"
LEDTAB: ;八段LED共陽數碼管字模
;數碼 0 1 2 3 4 5 6 7
DB 0C0H, 0F9H, 0A4H, 0B0H, 99H, 92H, 82H, 0F8H
;數碼 8 9 A B C D E F
DB 80H, 90H, 88H, 83H, 0C6H, 0A1H, 86H, 8EH
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -