;此範例的差別, 在填入LED_BUF緩衝區時,已經先轉換成7段顯示器字型, 送出掃描時, 就不用再轉換一次 LED_BUF EQU 32H ;LED顯示資料暫存器, 共需8個byet LED_CNT EQU 31H ;控制LED顯示位置暫存器 LED EQU P2 KB EQU P0 KB_BUF EQU 30H ORG 00H JMP MAIN ORG 0BH JMP SCAN_LED MAIN: ;LED顯示資料暫存器位址31H~38H初值預先設定為0~7 MOV R0,#LED_BUF ;指到顯示資料暫存器開頭 MOV DPTR,#FONT ;控制LED顯示位置 MOV A,#0 ;第一筆值為0 MOV R4,#8 FILL: MOV A,#0H ;7段顯示器預設全部都不亮 MOV @R0,A ;將數值填入R0所指記憶體位址 INC R0 DJNZ R4,FILL MOV TMOD,#00000001B MOV TH0,#(65536-2000) /256 MOV TL0,#(65536-2000) MOD 256 MOV IE,#10000010B MOV SP,#5FH SETB TR0 MOV R4,#0 MOV LED_CNT,#LED_BUF AGAIN: MOV R4,#4 MOV KB_BUF,#11111110B ;掃描訊號 NEXT: MOV KB,KB_BUF ;送至鍵盤 MOV A,KB ;讀回鍵盤訊號 ANL A,#11110000B ;將後4位元清為0 CJNE A,#11110000B,RECHECK ;判斷是否按鍵盤(前4位元有不為0的情況) MOV A,KB_BUF ;若無則將KB_BUF內的資料左旋 RL A ; MOV KB_BUF,A ;準備掃描下一行 DJNZ R4,NEXT ;R4內的資料減一,判斷是否掃瞄4次 JMP AGAIN ;重新開始掃描 RECHECK: MOV R5,#5 ;延遲,除彈跳 CALL DELAY MOV A,KB ;重新讀回按鍵訊號 ANL A,#11110000B CJNE A,#11110000B,KEY_IN ;判斷是否按鍵盤 JMP AGAIN ;若無則為彈跳訊號, 重新開始掃描 KEY_IN: MOV A,KB ;讀回鍵盤訊號 CALL KEY ;執行判斷按鍵副程式 MOV DPTR,#FONT MOVC A,@A+DPTR ;將按鍵值轉成對應7段顯示器字型 CALL SHIFT_L ;顯示資料向左移 MOV LED_BUF+7,A ;將這次按鍵值填在最右邊 WAIT: MOV A,KB ;重新讀回按鍵訊號 ANL A,#11110000B CJNE A,#11110000B,WAIT ;判斷按鍵是否放開 JMP AGAIN ;------ 判斷按鍵副程式, 並將該鍵對應的值 ----------- ;---------- (位置有錯自行修改' '內的值) ----------- KEY: CJNE A,#11101110B,S1 MOV A,#0 RET S1: CJNE A,#11101101B,S2 MOV A,#1 RET S2: CJNE A,#11101011B,S3 MOV A,#2 RET S3: CJNE A,#11100111B,S4 MOV A,#3 RET S4: CJNE A,#11011110B,S5 MOV A,#4 RET S5: CJNE A,#11011101B,S6 MOV A,#5 RET S6: CJNE A,#11011011B,S7 MOV A,#6 RET S7: CJNE A,#11010111B,S8 MOV A,#7 RET S8: CJNE A,#10111110B,S9 MOV A,#8 RET S9: CJNE A,#10111101B,S10 MOV A,#9 RET S10: CJNE A,#10111011B,S11 MOV A,#0ah RET S11: CJNE A,#10110111B,S12 MOV A,#0bh RET S12: CJNE A,#01111110B,S13 MOV A,#0ch RET S13: CJNE A,#01111101B,S14 MOV A,#0dh RET S14: CJNE A,#01111011B,S15 MOV A,#0eh RET S15: CJNE A,#01110111B,SEND MOV A,#0fh SEND: RET DELAY: MOV R6,#200 DEL: MOV R7,#200 DJNZ R7,$ DJNZ R6,DEL DJNZ R5,DELAY RET SHIFT_L: ;資料向左移, 送出掃描時, 顯示資料就跟著向左移 MOV LED_BUF,LED_BUF+1 MOV LED_BUF+1,LED_BUF+2 MOV LED_BUF+2,LED_BUF+3 MOV LED_BUF+3,LED_BUF+4 MOV LED_BUF+4,LED_BUF+5 MOV LED_BUF+5,LED_BUF+6 MOV LED_BUF+6,LED_BUF+7 RET ;7段顯示器掃描程式, 依序將LED_BUF內儲存之內容送至7段顯示器顯示 SCAN_LED: PUSH ACC PUSH PSW SETB RS0 ;使用暫存器庫1 CLR RS1 MOV TH0,#(65536-2000) /256 MOV TL0,#(65536-2000) MOD 256 MOV A,R4 ADD A,#0F8H ;在實驗版中, P1.7~P1.4另有其他用途, 先設為1, 避免干擾 MOV P1,A MOV R0,LED_CNT MOV A,@R0 MOV LED,A ;顯示於7段顯示器 INC LED_CNT INC R4 CJNE R4,#8,NOT_END MOV R4,#0 ;掃完8次,重設初值 MOV LED_CNT,#LED_BUF NOT_END: POP PSW POP ACC RETI FONT: DB 3fh,06h,5bh,4fh,66h,6dh,7dh,07h,7fh,6fh,77h,7ch,39h,5eh,79h,71h ;0~9,a~f之7段顯示器字型 END