當前位置:編程學習大全網 - 編程語言 - 用arm7做壹個流水燈的設計。

用arm7做壹個流水燈的設計。

從原理圖可以看出,如果我們想讓接在P1.0口的LED1亮起來,那麽我們只要把P1.0口的電平變為低電平就可以了;相反,如果要接在P1.0口的LED1熄滅,就要把P1.0口的電平變為高電平就可以;同理,接在P1.1~P1.7口的其他7個LED的點亮和熄滅方法方法同LED1。因此,要實現流水燈功能,我們只要將LED2~LED8依次點亮、熄滅,依始類推,8只LED變會壹亮壹暗的做流水燈了。

實現8個LED流水燈程序用中文表示為:P1.0低、延時、P1.0高、P1.1低、延時、P1.1高、P1.2低、延時、P1.2高、P1.3低、延時、P1.3高、P1.4低、延時、P1.4高、P1.5低、延時、P1.5高、P1.6低、延時、P1.6高、P1.7低、延時、P1.7高、返回到開始、程序結束。

從上面中文表示看來實現單片機流水燈很簡單,但是我們不能說P1.0妳變低,它就變低了。因為單片機聽不懂我們的漢語的,只能接受二進制的“1、0......”機器代碼。我們又怎樣來使單片機按我們的意思去工作呢?為了讓單片機工作,只能將程序寫為二進制代碼交給其執行;早期單片機開發人員就是使用人工編寫的二進制代碼交給單片機去工作的。今天,我們不必用煩人的二進制去編寫程序,完全可以將我們容易理解的“程序語言”通過“翻譯”軟件“翻譯”成單片機所需的二進制代碼,然後交給單片機去執行。這裏的“程序語言”目前主要有匯編語言和C語言兩種;在這裏我們所說的“翻譯”軟件,同行們都叫它為“編譯器”,將“程序語言”通過編譯器產生單片機的二進制代碼的過程叫編譯。前面說到,要想使LED1變亮,只需將對應的單片機引腳電平變為低電平就可以了。現在讓我們將上面提到的8只LED流水燈實驗寫為匯編語言程序。

實現8個LED流水燈匯編語言源程序?liu01.asm?

;-----?主程序開始?-----

START:?CLRP1.0;P1.0輸出低電平,使LED1點亮

ACALL?DELAY?;調用延時子程序

SETB?P1.0;P1.0輸出高電平,使LED1熄滅

CLRP1.1;P1.1輸出低電平,使LED2點亮

ACALL?DELAY?;調用延時子程序

SETB?P1.1;P1.1輸出高電平,使LED2熄滅

CLRP1.2;P1.2輸出低電平,使LED3點亮

ACALL?DELAY?;調用延時子程序

SETB?P1.2;P1.2輸出高電平,使LED3熄滅

CLRP1.3;P1.3輸出低電平,使LED4點亮

ACALL?DELAY?;調用延時子程序

SETB?P1.3;P1.3輸出高電平,使LED4熄滅

CLRP1.4;P1.4輸出低電平,使LED5點亮

ACALL?DELAY?;調用延時子程序

SETB?P1.4;P1.4輸出高電平,使LED5熄滅

CLRP1.5;P1.5輸出低電平,使LED6點亮

ACALL?DELAY?;調用延時子程序

SETB?P1.5;P1.5輸出高電平,使LED6熄滅

CLRP1.6;P1.6輸出低電平,使LED7點亮

ACALL?DELAY?;調用延時子程序

SETB?P1.6;P1.6輸出高電平,使LED7熄滅

CLRP1.7;P1.7輸出低電平,使LED8點亮

ACALL?DELAY?;調用延時子程序

SETB?P1.7;P1.7輸出高電平,使LED8熄滅

ACALL?DELAY?;調用延時子程序

AJMP?START?;8個LED流了壹遍後返回到標號START處再循環

;-----?延時子程序?-----

DELAY:?MOVR0,#255?;延時壹段時間

D1:MOVR1,#255

DJNZ?R1,$

DJNZ?R0,D1

RET;子程序返回

END;程序結束

在上面主程序中用到了五條匯編語言指令:CLR、ACALL、SETB、LJMP、END。

CLR:?是將其後面指定的位清為0,程序中使對應端口輸出低電平

ACALL:是子程序調用指令,程序中調用了DELAY延時子程序

SETB:是將其後面指定的位置成1,程序中使對應端口輸出高電平

AJMP:是無條件跳轉指令,意思是:跳轉到指定的標號處繼續運行

END:?是程序結束的偽指令,意思是告訴編譯器,程序到此結束。偽指令只告訴編譯器此程序到此有何要求或條件,它不參與和影響程序的執行。

在上面源程序中"ACALL?DELAY"指令的作用是調用DELAY延時子程序。為什麽要使用這指令呢?如果不用該指令能夠實現"流水"效果嗎?答案是肯定的,壹定要用該指令才能看到我們需要的"流水"效果。如果不用該指令,則由於8個LED發光與熄滅的時間都很短,我們肉眼無法看到LED的熄滅與點亮,憑我們肉眼看到的是LED1~LED8都同時亮(半亮),而看不到“流水”效果的!註:初學者可以將上面源程序中所有"ACALL?DELAY"指令行刪除後再編譯後燒寫到單片機進行驗證壹下。

產生這種現象主要是因為單片機執行每條指令的時間很短,我們知道實驗板上單片機的時鐘高達11.0592MHz,在這個時鐘信號(即晶體振蕩信號)下,壹個“機器周期”僅大約1.08uS(微秒)。本程序中我們用到的SETB?P.x和CLR?P.x均屬於單周期指令,也就是說,執行壹句?SETB?P.x?用時僅1.08uS(微秒),CLR?P.x?也是1.08uS(微秒);也就是點亮和熄滅時間都為1.08uS(微秒),在如此高速的流水速度下,8個LED發光與熄滅的時間都很短,當然憑我們的肉眼看不到“流水”效果了!

這裏需要說明的是,按匯編語法要求,所編制的程序(下稱源程序)之格式和書寫要求必須依下列原則:?

1、源程序必須為純文本格式文件,如用Windows“附件”中的“記事本”編寫的文本文件或用UltraEdit文本編輯器編輯;

2、源程序的擴展名應是?*.ASM;?

3、壹行只能寫壹條語句,以回車作為本句的結束,每壹語句行長度應少於80個字符(即40個漢字)。

4、每行的格式應為:標號:?命令?參數?;註釋?。即壹行由四部份組成,各部份的順序不能搞錯,依實際要求可以缺省其中的壹部份或幾部份,甚至全部省去,即空白行。需要使用標號時標號後面必須有“:”(冒號),而命令語句和參數之間必須用空格分開,如果命令有多個參數,則參數與參數之間必須用“,”(逗號)分開,需要註釋時註釋前必須用“;”(分號),“;”後面的語句可以寫任何字符,包括漢字用於解釋前面的匯編語句,它將不參與匯編,不生成代碼。由於匯編程序對我們還不直觀,所以在編寫源程序時,應當養成多寫註釋的習慣,這樣有助於今後源程序的閱讀和維護。?

標號是標誌程序中某壹行的符號名,編譯後標號的數值就是標號所在行代碼的地址。在宏匯編ASM51中標號的長度不受限制,但標號中不能包含‘:'或其它的壹些特殊符號,也不能用漢字,可以用數字作標號,但必須用字母開頭。當標號作參數用(如標號作轉移地址),在命令後面出現時,必須舍去‘:'(如上面程序中的?AJMP?START中的START是不能再有:)。每行只能有壹個標號,壹個標號只能用在壹處,如果有兩行用了同壹個標號,則匯編時就會出錯。由於標號的長度沒有限制,可以用有意義的英文或漢語拼音來說明行,使源程序讀起來更方便。在源程序中的字母不區分大小寫,也就是說?start?和?START?是壹樣的,請不要用大小寫方式去區分不同的標號。

好啦!我們知道了匯編語言程序的規則,現在就動手編輯源程序吧。馬上啟動Keil單片機集成開發環境,建立新工程liu01.UV2,將上面的源程序liu01.asm導入到工程中,設置好Keil工程的編譯參數,編譯得到HEX格式的目標文件liu01.hex,用?ISP編程器?將目標文件liu01.hex燒寫到AT89S51單片機中,接下來就是將燒寫好的AT89S51從編程器上取下,放到“?S51增強型單片機實驗板?”上通電,我們就看到了LED1~LED8的"流水"效果了。

到此,我們做的流水燈已成功,工作原理也清楚啦,若妳完全掌握了上面程序,那麽妳就可以將“流水燈”的流向改變壹下,可以將從"左向右流"改為從"右向左流",也可以改為"兩邊向內流"、"內部向外流"......,我想妳壹定能用前面學到的方法實現這些功能。可能有些高手說,前面的編程方法是最最笨的!不錯!但初學單片機初期可以不必講究語言的簡練,只要能實現預先要求就好,最主要的是學好基本指令(111條)的用法,清楚各個指令的功能,這是初學者要知道的。那麽還有更好的編程思路嗎?當然有!請跟隨站長繼續學習下面的內容。

在前面學習的程序中我們讓LED流水是去逐個控制P1端口的每個位來實現的,因此程序顯得有點復雜,下面我們就采用新的思路來編程。新的編程思路如下:我們在程序壹開始就給P1口送壹個數,這個數本身就讓P1.0先低,其他位為高,然後讓這個數據向高位移動不就實現“流水”效果啦?的確如此!8051指令中沒有讓P1數據移動的指令,但有對累加器ACC中數據左移或右移的指令,ACC在指令中常寫為A,累加器A數據左移指令為"RL?A",累加器數據右移指令為"RR?A",累加器在數據傳輸和數據處理過程中作用十分重要,累加器ACC為8位。他可與片內所有單字節寄存器交換數據,實際上P1和其他端口在單片機中也是壹個寄存器。這樣我們可以將需移動的數據先放到ACC中,讓其移動,然後將ACC移動後的數據再轉送到P1口,這樣同樣可以實現“流水”效果。下面程序就是采用新的編程思路源程序liu02.asm。

實現8個LED流水燈匯編語言程序?liu02.asm?

;-----?主程序開始?-----

START:?MOVACC,#0FEH;ACC中先裝入LED1亮的數據(二進制的11111110)?

MOVP1,ACC?;將ACC的數據送P1口?

MOVR0,#7?;將數據再移動7次就完成壹個8位流水過程?

LOOP:?RLA;將ACC中的數據左移壹位

MOVP1,A?;把ACC移動過的數據送p1口顯示

ACALL?DELAY?;調用延時子程序

DJNZ?R0,LOOP;沒有移動夠7次繼續移動?

AJMP?START?;移動完7次後跳到開始重來,以達到循環流動效果

;-----?延時子程序?-----

DELAY:?MOVR0,#255;延時壹段時間

D1:MOVR1,#255

DJNZ?R1,$

DJNZ?R0,D1

RET?;子程序返回

END?;程序結束

接下來,我們將上述程序編譯,並燒寫到實驗芯片中,放到實驗板上可以看到程序的"流水"效果是壹樣的,但源程序看起來更加簡潔,直觀。其實8051單片機有111條指令,有的指令常用,有的指令不常用,只要遵守語法規則,妳可以用這些指令“組合”成妳想象到的任何程序。當然,有時壹條指令可以替代很多條指令,這樣會使程序簡潔,程序代碼減少,在編寫較大程序時可以讓程序存儲器放得下妳需要的代碼,這也是單片機高手所追求的“程序簡潔高效”。當然,初學者不必刻意去追求程序的簡潔高效,主要是要全面地掌握各種指令的應用,只要妳對基本指令都熟悉了,那麽妳也就可以編出簡潔高效的程序了,不過這編程“內功”是需要妳勤學苦練,日積月累的練習、實驗才能達到的哦!馬上拿起妳的實驗板,現在就開始動手吧:)

上面我們學習的兩個程序都是比較簡單的流水燈程序,"流水"花樣只能實現單壹的"從左到右"流方式。下面介紹壹個實用的流水燈程序,程序能夠實現任意方式流水,而且流水花樣無限,只要更改流水花樣數據表的流水數據就可以隨意添加或改變流水花樣,真正實現隨心所欲的流水。只要將下面的程序稍稍修改壹下,通過S51增強型單片機實驗板的擴展接口連接到霓虹燈高壓驅動接口板就可以驅動真正的霓虹燈了。

實用的查表方式多功能流水燈程序?liu03.asm?

;-----?主程序開始?-----

ORG0000H;上電復位,程序從0000H開始執行

START:?MOVSP,#60H?;堆棧初始化為60H

MOVDPTR,#LIU_TAB;流水花樣表首地址送DPTR

LOOP:?CLRA

MOVC?A,@A+DPTR

CJNE?A,#0FFH,SHOW;檢查流水結束標誌

AJMP?START;所有花樣流完,則從頭開始重復流

SHOW:?MOVP1,A;將數據送到P1口

ACALL?DELAY

INCDPTR

AJMP?LOOP

;-----?延時子程序?-----

DELAY:?MOVR0,#255?;延時壹段時間

D1:MOVR1,#255

DJNZ?R1,$

DJNZ?R0,D1

RET;子程序返回

;-----?下面是流水花樣數據表?-----

LIU_TAB:?

DB?01111111B;二進制表示的流水花樣數據

DB?10111111B

DB?11011111B

DB?11101111B

DB?11110111B

DB?11111011B

DB?11111101B

DB?11111110B

DB?11111110B

DB?11111101B

DB?11111011B

DB?11110111B

DB?11101111B

DB?11011111B

DB?10111111B

DB?01111111B

DB?7FH,0BFH,0DFH,0EFH,0F7H,0FBH,0FDH,0FEH?;十六進制表示

DB?0FEH,0FDH,0FBH,0F7H,0EFH,0DFH,0BFH,7FH

DB?7EH,0BDH,0DBH,0E7H,0E7H,0DBH,0BDH,7EH

DB?7FH,3FH,1FH,0FH,07H,03H,01H,00H

DB?0FFH?;流水花樣結束標誌0FFH

END;程序結束

  • 上一篇:“抽象類”和“接口”的區別是什麽?
  • 下一篇:Excel表格中定時啟動宏怎麽操作
  • copyright 2024編程學習大全網