?? 新建 文本文檔.txt
字號:
第二節
單片機自學教材之用單片機做流水燈(二)
第二節
上一節的實驗最后沒有得到“流水”效果,主要是單片機執行每條指令的時間很短,我們肉眼無法看到LED的熄滅與點亮;
單片機內部能按部就班的自動工作,正是在系統時鐘的作用下,內部各邏輯硬件產生各種所需脈沖信號而實現的。這個時鐘信號(既晶體振蕩信號)的周期稱“振蕩周期”。我們這個實驗中晶體使用的是12MHZ.
在單片機中,要處理最短周期的一條指令需要由12個振蕩周期(既晶振振蕩周期)組成的,這個叫“機器周期”。
8051核的單片機,大多數指令只用一個機器周期(既單周期),也有雙周期和四周期的指令。本實驗中用到的SETB P.x和CLR P.x均屬于單周期指令,也就是說,執行一句 SETB P.x 用時僅1uS(微秒),CLR P.x 也是1uS;難怪我們前面的程序不能看到流水效果。
現在,將程序改動一下,在每點亮一個LED后,讓程序干點別的事,也就是讓它等一會再將該LED熄滅,繼續執行下面的程序:
star: ;程序開始
clr p1.0 ;LED1亮
acall delay ;調用延時子程序
setb p1.0 ;LED1滅
clr p1.1 ;換燈,同上
acall delay
setb p1.1
clr p1.2
acall delay
setb p1.2
clr p1.3
acall delay
setb p1.3
clr p1.4
acall delay
setb p1.4
clr p1.5
acall delay
setb p1.5
clr p1.6
acall delay
setb p1.6
clr p1.7
acall delay
setb p1.7
ljmp star ;返回到開始循環
delay: ;延時子程序
mov r1,#50
del0:
mov r2,#100
del1:
mov r3,#100
djnz r3,$
djnz r2,del1
djnz r1,del0
ret ;延時子程序結束,返回到調用處的下一句
end
請將上面的程序保存為 Test.asm,進行編譯,并燒寫到AT89C2051中,之后將2051安裝到實驗板中實驗,這回肯定“流水”啦!
回過頭,讓我們看看延時子程序是怎樣工作的:
單片機內部有不少寄存器,這些寄存器在單片機通電時,你可以給他寫入數據(是單片機按你程序要求寫的數據,而不是編程器寫的),當第二次給他寫入新數據時,前次的數據就被新數據覆蓋;當然也可以從寄存器中讀取數據。當單片機沒有電源供給時,寄存器內部的數據也隨即消失;這些寄存器人們叫他RAM,而用編程器將我們編寫的程序燒寫到單片機中的存儲器叫ROM;現在,我們應該清楚:RAM是讓程序去使用的,ROM是我們編寫的程序存放的地方!
前面說過,單片機內部有不少RAM,本實驗用的AT89C2051有多少寄存器?我們現在不必關心,現在只須知道單片機內部有名叫R0~R7 的這8個寄存器。這8個寄存器每個都由8個單獨的位寄存器組成,最大存放數據為二進制的 1111 1111,十六進制 = FF,十進制 = 255。在使用時注意不要大于其有效范圍。
上面延時程序中,先用到 mov r1,#50 ,mov是移動的意思,該句是將50這個十進制數放到r1中;50是立即數,按匯編語言要求前面要加“#”號,匯編語言還規定,十六進制數后面要加“ H”,十六進制數的高位是字母時在字母前面還要加“0”,例如:#0F8H;二進制數后面加“B”,例如:#11110000B。十進制不加,例如:#100 。延時程序的第二、三句為 mve r2,#100 ;mov r3,#100 ;這兩句意思同前。
第四句中 djnz r3,$ 的意思是將 r3 里面的數減 1 后如果 r3 不等于 0 則跳到后面指定的程序位置,這里的“$”既要跳轉的程序位置,“$”代表當前語句處,也就是說,r3不等于 0,程序返回再次執行本句。如果r3 減 1 后等于 0,程序結束本句,繼續執行下面的語句。
延時程序的最后一句是 ret ,意思是退出本子程序,返回到調用本子程序處的下一句。
根據上面的解釋,一進入延時子程序首先為 r1, r2, r3 寄存器裝入我們需要的數據,然后先對 r3 進行減數,每次減 1 ,r3 減完后減 r2 ,減 r2 時就費事啦,因為 r2 每減 1 后不為 0 需要跳轉到 del1 標號處執行下面的語句,此時 r3 再次裝入數據100,并且還要再次對 r3 進行減數......,r2 減完后減 r1,減 r1的過程你研究研究看看。
每執行 djnz rn,rel (rn 指 r0~r7,rel 指轉移地址)指令一次,需要2個機器周期,單片機需耗時2uS(指本實驗),若忽略裝數等語句,延時子程序從開始到結束,單片機共耗時100*100*50*2nS,既1000000uS=1秒!若加上裝數等語句的耗時,延時時間大于1秒。
到此,我們做的流水燈已成功,原理大致也明白啦,若你自認為這一課你完全明白了,那請你將“流水燈”的流向改變一下,也可以改為兩邊向內流,內部向外流......,我想你一定能用前面學到的方法實現這些功能。可能有些高手說,前面的編程方法是最最笨的!,不錯!但玩單片機初期不必講究語言的簡練,只要能完成預先要求就好,這是初學者要知道的。那么還有更好的編程思路嗎:有!請繼續學習
單片機自學教材之用單片機做流水燈(三)
第三節
在上節課中讓 LED 流水是去逐個控制P1端口的每個位來實現的,那么我們在程序一開始就給P1口送一個數,這個數本身就讓P1.0先低,其他位為高,然后讓這個數據向高位移動不就實現“流水”效果啦?的確如此!
可惜,8051沒有讓P1數據移動的指令,但有對累加器ACC中數據左移或右移的指令,ACC是8051單片機內部算術邏輯單元中的一個“寄存器”(這里叫他寄存器是不正確的,但你可以先這樣理解,ACC在指令中常寫為A),他在數據傳輸和數據處理過程中作用十分重要,ACC為8位。他可與片內所有單字節寄存器交換數據,實際上P1和其他端口在單片機中也是一個寄存器。這樣我們可以將需移動的數據先放到ACC中,讓其移動,然后將ACC移動后的數據再轉送到P1口,這樣同樣可以實現“流水”效果。
程序如下:
star: ;開始
mov acc,#0feh ;ACC中先裝入LED1熄滅的數據(即二進制的 1111 1110)
mov p1,acc ;將ACC的數據送P1口
mov r0,#7 ;因上句送到 p1口的數據就熄滅了一位,
;所以將數據再移動7次就完成一個8位流水過程
loop: ;數據移動循環
rl a ;將ACC中的數據左移一位
mov p1,a ;把ACC移動過的數據送p1口顯示
acall delay ;調用延時
djnz r0,loop ;沒有移動夠7次繼續移動
ljmp star ;移動完7次后跳到開始重來,以達到循環流動效果
delay: ;延時子程序,就是上節課中的延時子程序
mov r1,#50
del0:
mov r2,#100
del1:
mov r3,#100
djnz r3,$
djnz r2,del1
djnz r1,del0
ret ;延時子程序結束,返回到調用處的下一句
end ;本匯編程序到此結束
接下來,將上述程序編譯,并燒寫到前面我們的實驗芯片中,流水效果與第二節課的一樣。
其實8051單片機有111條指令,這111條指令好比以前我們使用數字傳呼機時的“短語代碼”一樣,可以用幾個“短語代碼”去表示一句完整、通順的語句段落。有的指令常用,有的指令不常用,只要遵守語法規則,你可以用這些指令“組合”成你想象到的任何程序。當然,有時一條指令可以替代很多條指令,這樣會使程序簡捷,費碼減少,在編寫較大程序時可以讓程序存儲器放得下你需要的代碼。這也是單片機高手所追求的。當然,在程序存儲器空間不成問題時,你不這樣做但也可以達到預期的功能,這也不算錯。
單片機內部還有很多“部件”我們只是用到什么說什么,很不系統。但是我也不想系統的介紹這些,因系統介紹單片機結構和指令的書很多,何況寫的遠比我好,因此,希望你在看本講座的過程中,還要結合正規的教材學習其更多的指令和“部件”。
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -