8x51 起手式 -LED 跑馬燈

講到自動控制一定會提到『 8x51 系列』的應用,這系列的晶片在近二十幾年來已經被廣泛開發到爛掉,無處不見其縱影呀,從燈號控制、定時裝置到各種自動化的家電、工業產品,都可以找到它的存在。因此,凡是講到要學習自動控制的應用與設計,『 8x51 系列』可說是必學的項目。

這學期因為專題教授強烈的『口頭勸說』和為了順便湊畢業學分,就跑去選修了『 8x51 微處理機』的課程,重溫了以前零星的經驗。話說這堂課有多次實作的作業,過程中玩弄電路板和程式非常有意思。不過課程免不了從最簡單的 LED 跑馬燈開始教,雖然乏味但也是一個惡搞經驗的開始〔尤其是不依照老師要求時 :D〕。

這是第一次作業的電路示意圖〔圖的標示和真實腳位不一樣,請參考 8x51 的腳位定義資料。〕:


作業目標是讓 LED 燈號從第一個燈開始,每 0.2 秒變一次燈號,向左旋轉三圈後,再往右反方向旋轉三圈,如此以重覆動作跑下去。程式設計流程大致上是:




程式是用 ASM 寫的,原始程式碼和詳細註解如下:

MOV R0, #24 ; 設定切換 LED 次數:跑三圈共23次
; 因為包括起始燈號,所以要設定成 n+1 次
MOV A, #11111110B ; 以 bit 為單位,設 1 代表該腳位會輸出 5V 電壓
; 設 0 則腳位輸出 0V 電壓,會讓 LED 有電位差而亮燈
; 這裡設最右邊第一顆 LED 燈泡為起始燈

RUNL:
MOV P0, A ; 使用 A 的設定值來設定 P0 ,以控制 LED
CALL SLEEP ; 呼叫 SLEEP 副程式,暫停 0.2 秒
RL A ; 將燈泡設定值向左平移

DJNZ R0, RUNL ; R0=R0-1
; 然後判斷 R0是否為 0
; 若 R0!=0:
; 跳回 RUNL 直到LED 跑完三圈(R0-1=0)
; 若 R0=0則往下繼續執行

MOV R0, #24 ; 設定切換 LED 次數(n+1)
RR A ; 此時 LED 設定會停在最左邊第一個位置
; 將燈泡設定值向右平移


RUNR:
MOV P0, A ; 使用 A 的設定值來設定 P0 ,以控制 LED
CALL SLEEP ; 呼叫 SLEEP 副程式,暫停 0.2 秒
RR A ; 將燈泡設定值向右平移

DJNZ R0, RUNR ; R0=R0-1
; 然後判斷 R0是否為 0
; 若 R0!=0:
; 跳回 RUNL 直到LED 跑完三圈(R0-1=0)
; 若 R0=0則往下繼續執行

MOV R0, #24 ; 設定切換 LED 次數(n+1)
RL A ; 此時 LED 設定會停在最右邊第一個位置
; 將燈泡設定值向左平移

JMP RUNL ; 跳回 RUNL 重新一次循環

; 暫停流程之副程式
; 12 clocks = 1 cycle = 0.000001 seconds
; 1200000 clocks = 0.1 seconds,故 2400000 clocks = 0.2 seconds
; SLEEP 被設計成可以浪費 2340912 clocks,算法如下:
; 12 + [(12+24)*R2 + 24] * R1
; = 12 + 9180 * 255
; = 2340912 clocks (0.195076 seconds)
SLEEP:
MOV R1, #FFH ; 指令會消耗12 clocks
; 設定R1=255
SLEEP1:
MOV R2, #FFH ; MOV 指令會消耗12 clocks
; 設定R2=255

SLEEP2:
NOP ; 浪費掉 12 clocks
DJNZ R2, SLEEP2 ; DJNZ 指令會消耗24 clocks
; 重覆跑 SLEEP2,共 R2 次
DJNZ R1, SLEEP1 ; DJNZ 指令會消耗24 clocks
; 重覆跑 SLEEP1,共 R1 次
RET ; 副程式結束並返回主程式
END ; 程式結束


這程式很笨,沒有 Interrupt 的使用,所以用很單純的 NOP 去吃掉時間,而一般書上和同學都用三個 Rx 去實作 Delay 的函式,但我偏不想這麼做〔多耗一點記憶體感覺程式就不優雅了〕,所以多了一點點時間誤差也就算了,反正人也感覺不出來 :P。

後記

8x51 就像是縮小精簡版的 x86 一樣,關念其實差不太多,就算比較少接觸 8x51 但也不至於忘掉太多過去的經驗〔至少我還有持續去玩弄 x86 的程式〕。還有在 Interrupt 的使用其實並不複雜,只不過因為老師的作業要求,所以也就沒有使用中斷去解決 Timer 的問題。

另外,找不到好用的 Open Source 8x51 模擬器,只好每次都燒到晶片上測試,實在很累人。哪天有空有動力時,再來為自己寫套好用的 simulator。最近也研究了一下 8x51 的 Assemler 和 C Compiler ,下次再來筆記一下好了。:)

留言

  1. SDCC - Small Device C Compiler
    http://sdcc.sourceforge.net/

    有附一個 debugger, 因為模擬 gdb 的行為, 所以用起來很像.

    回覆刪除

張貼留言

這個網誌中的熱門文章

有趣的邏輯問題:是誰在說謊

Web 技術中的 Session 是什麼?

淺談 USB 通訊架構之定義(一)

淺談 USB 通訊架構之定義(二)

Reverse SSH Tunnel 反向打洞實錄