;********************************************************************** ; 七段式 LED 測試,包含數字和英文字母, ; 利用計時中斷作延遲 Use Timer0, Mode 2, 8 bit, 256 maximun,自動載入 ; 每個 Machine Cycle=1.085 us, use 11.059 MHz oscilator ; 利用外部中斷 Int0 作 重新開始 ; Daniel Lu 2002'12'31 ;********************************************************************** OFT EQU 30H ;配置位址空間 30H 給OFT(offset) 儲存數值用 COUNT EQU 184 ;每 184 次大約等於 200 us US_200 EQU 31H ;每次計時中斷(US_200)累加一次 MS_50 EQU 32H ;每 50 毫秒累加 ORG 0000H ;設定起使位址 LJMP START ORG 0003H ;外部中斷 INT0 LJMP INILED ORG 000BH ;Timer0中斷 LJMP IRS_Display ORG 0013H RETI ORG 001BH RETI ORG 0023H RETI ;------------------------------------------------------- START MOV R1,#00H ;先作一小段延遲,讓系統Ready $ DJNZ R1,$ MOV SP,#50H ;指定堆疊起始位址 MOV DPTR,#TABLE ;將Table 所在的位址存到 DPTR SETB PT0 ;IP.1 中斷優先權設為高 SETB ET0 ;IE.1 啟動 Timer0 中斷服務 SETB IT0 ;Interrupt Type: 1 = 負緣觸發 SETB PX0 ;IP.0 中斷優先權設為高 SETB EX0 ;IE.0 啟動 Timer0 中斷服務 CALL SetTimer0 ;設定 Timer0 模式 CALL INILED ;呼叫 INILED 副函式,將每個 LED (a,b,c,d,e,f,g) 各跑一次 SETB EA ;啟動中斷服務 LOOP SJMP LOOP ;進入回圈 ;顯示字型的 Table----------.gfedcba -> 00000000B------------------------------- TABLE DB 3FH ;0 DB 06H ;1 DB 5BH ;2 DB 4FH ;3 DB 66H ;4 DB 6DH ;5 DB 7DH ;6 DB 27H ;7 DB 7FH ;8 DB 6FH ;9 DB 41H ;: DB 45H ;; DB 38H ;< DB 48H ;= DB 0EH ;> DB 4BH ;? DB 5FH ;@ DB 77H ;A DB 7CH ;B DB 58H ;C DB 5EH ;D DB 79H ;E DB 71H ;F DB 6FH ;G DB 74H ;H DB 04H ;I DB 0EH ;J DB 40H ;K //未定義 DB 38H ;L DB 40H ;M //未定義 DB 54H ;N DB 5CH ;O DB 73H ;P DB 67H ;Q DB 70H ;R DB 6DH ;S DB 78H ;T DB 1CH ;U DB 3EH ;V DB 40H ;W //未定義 DB 40H ;X //未定義 DB 6EH ;Y DB 5BH ;Z ;Output ----將 ACC 內的值反相輸出到 P1 ---------------------------------- OUTPUT CPL A ;因為 Active Low,所以必須先將 A 反相 MOV P1,A ;將 ACC 的值輸出到 P1 RET ;返回 ;INILED 副函式---從 a 段到 g 段 跑一遍 ----------------------------------- INILED CLR TR0 ;先停止 Timer0 MOV A,#80H ;初值為 1000 0000B $ RL A ; 0000 0001 -> 0000 0010 -> 0000 0100 .... 逐一顯示 CALL OUTPUT ;呼叫顯示函式 CALL DELAY ;延遲一下 CPL A ;因為在 OUTPUT 內會將 A 反相,所以這裡要再反相回來 CJNE A,#80H,$ ;如果不等於 1000 000B 則繼續 RL A,然後 OUTPUT ;上面和下面的 Code 功能相同,但是使用上面的 Code,總程式只佔 98 Bytes,下面則佔 123 bytes ;MOV A,#01H ;七段顯示器的 a 段 LED ;CALL OUTPUT ; ;MOV A,#02H ;七段顯示器的 b 段 LED ;CALL OUTPUT ; ;MOV A,#04H ;七段顯示器的 c 段 LED ;CALL OUTPUT ; ;MOV A,#08H ;七段顯示器的 d 段 LED ;CALL OUTPUT ; ;MOV A,#10H ;七段顯示器的 e 段 LED ;CALL OUTPUT ; ;MOV A,#20H ;七段顯示器的 f 段 LED ;CALL OUTPUT ; ;MOV A,#40H ;七段顯示器的 g 段 LED ;CALL OUTPUT ; CALL StartTimer0 ;重新啟動 Timer0 RETI ;Delay 副函式----------------------------------------- DELAY MOV R0,#05H ;Delay 參數,改變此次數可控制Delay 時間 $0 MOV R1,#00H ;外層回圈 ----- $1 MOV R2,#00H ;內層回圈 -- | $2 DJNZ R2,$2 ;內 _____| | DJNZ R1,$1 ;外__________| DJNZ R0,$0 ; RET ;返回 ;Timer Delay 副函式 (精確延遲)--------------------------------------- ;TimerDelay ; MOV MS_50,#00H ;將 MS_50 初始為 0 ;$IniT0 CALL StartTimer0 ; ;$DlayMS JNB TF0,$DlayMS ;延遲50 msec ; JNB P3.7,INIOFT ;如果 P3.7 為 0,則跳到 INIOFT ; INC MS_50 ;MS_50 加一 ; MOV R0,MS_50 ;將 MS_50 的值 copy 到 ACC 利用 ACC 作比較動作 ; CJNE R0,#20,$IniT0 ;延遲 50 ms * 20 = 1000 ms = 1 sec ; RET ;Set Timer0 副函式 -------------------------------------------------- SetTimer0 ;MOV TMOD,#11110001B ;模式 1,自動載入 ;MOV A,TMOD ;將 TMOD 的值 copy 到 ACC 準備作每個位元設定 ;ANL A,#11110000B ;將 Timer0 初始化為 0000B ;CLR ACC.3 ;GATE=0 -> 允許計時/計數 ;CLR ACC.2 ;C/!T=0 -> 計時模式 ;CLR ACC.1 ;M0=1 ;SETB ACC.0 ;M1=0 ->模式 2 ;MOV TMOD,A ;將設定好的值 回 copy 到 TMOD,設定TMOD MOV TMOD,#00100010B ;Timer0,Timer1都是模式 2,自動載入 MOV TH1,#FDH ;設定鮑率 SETB TR1 MOV SCON,#01010000B RET ;StartTimer0 --設定 Timer0 (TH0, TL0) 初值-------------------------------- StartTimer0 ;MOV TH0,#(65536-COUNT)/256 ;MOV TL0,#(65536-COUNT).MOD.256 MOV TH0,#(256-COUNT) MOV TL0,#00 CLR TF0 ;清除溢位 flag MOV OFT,#FFH ;初始化 Offset 為 0 MOV US_200,#00H MOV MS_50,#00H SETB TR0 ;TR0=1, Timer Run, 開始計時 RET ;Timer 0中斷服務--------------------------------------------------------- IRS_Display INC US_200 MOV R0,US_200 ;因為 ACC 用來輸出到 P1,所以利用 R0 來作比較 CJNE R0,#250,$ExtIRS ;如果未累積到 200 us * 250 =50 ms 則跳出中斷服務 MOV US_200,#00H ;如果已經達到 50 ms,則將 US_200 清為 0 INC MS_50 MOV R0,MS_50 CJNE R0,#20,$ExtIRS ;如果未累積到 50 ms * 20 =1000 ms 則跳出中斷服務 MOV MS_50,#00H INC OFT MOV R0,OFT CJNE R0,#43,$Show MOV OFT,#00 $Show MOV A,OFT MOVC A,@A+DPTR ;將 DPTR內的位址加上 ACC 內的 Offset 值所得的新位址,取新位址(Table 內)所在的值放到 ACC CALL OUTPUT ;顯示 CLR TI MOV A,#30H ADD A,OFT MOV SBUF,A ;傳送出去 $ExtIRS RETI