先說某一組端口接一排8個LED燈的情況,如何做到讓這八個燈想亮哪個就亮哪個,想不亮哪個就不亮哪個。
比如說,8個燈,全部負(fù)極接地電位,正極接P1的8個端口,則此種情況下,如果要某個燈亮,則對應(yīng)的那一個單片機(jī)的端口就應(yīng)該為高電位,照此推算下來,如果要讓從P1.7到P1.0對應(yīng)的燈為滅亮滅滅亮亮滅亮,則端口的電位應(yīng)為低高低低高高低高,寫成二進(jìn)制八位數(shù),就是01001101。
要實現(xiàn)這個,在單片機(jī)的設(shè)計上,就只需要把01001101送到P1端口就完成任務(wù)了。
這里就有一個問題,這個01001101在送到P1端口之前它在哪兒呢?在不同的位置,送法也肯定是不同的。
我們先說一種情況,就是我們的程序不做其它任何事,就只是實現(xiàn)這個功能,那么,最簡單的做法,就是這個01001101已存在程序存儲器中某個單元中,我們把程序存儲器中的這個數(shù),直接抓出來送到P1端口就行了,用語言描述其過程,就是:將程序存儲器中的某一單元中的數(shù)據(jù),當(dāng)作數(shù)值,送入P1。
按這個思路,在單片機(jī)設(shè)計中,要考慮幾個問題,首先要考慮的是,讓其如何區(qū)分命令與數(shù)值,因為,在計算機(jī)中,命令與數(shù)值,都是以二進(jìn)制數(shù)來表示的,而51單片機(jī)采用哈佛結(jié)構(gòu),存在程序存儲器中的同一個區(qū)域,且并未做命令與數(shù)值的區(qū)別性標(biāo)記,也就是說,單片機(jī)控制器即不可能根據(jù)數(shù)據(jù)的特征來區(qū)分,也不可能根據(jù)其存在的物理區(qū)域來區(qū)分是命令還是數(shù)值,所以必然另想辦法。
在這個問題上,單片機(jī)是這樣設(shè)計的:程序的執(zhí)行過程,是隨時鐘一步一步地按程序存儲器單元順序從低到高地從程序存儲中取出數(shù)據(jù)并送入控制器中(遇跳轉(zhuǎn)指令則在跳轉(zhuǎn)后,從跳轉(zhuǎn)指令指定的地址開始,依然按這個規(guī)則進(jìn)行),程序存儲器中的第一個單元中的數(shù)據(jù)是必然的命令,每一命令緊隨其后的單元中的數(shù)據(jù)是否是數(shù)值、如果是,有多少個單元是數(shù)值,均由這條命令來指定,取完這一個或幾個單元的數(shù)據(jù)后,再下一個單元中的數(shù)據(jù),規(guī)定為命令。
我們可以認(rèn)為單片機(jī)可以采用這樣一種方式進(jìn)行處理(當(dāng)然還有其它方式):從程序存儲器中取出的數(shù)據(jù),進(jìn)入控制通道,通道最前面有兩道并聯(lián)且不會同時開同時關(guān)的門,命令進(jìn)甲道門,數(shù)值進(jìn)乙道門。對于將數(shù)值送入P1這個操作,其流程是:控制系統(tǒng)先收到將緊隨其后第二個單元中的數(shù)據(jù)送入P1的命令后,關(guān)閉甲門并打開乙門,之后再根據(jù)緊隨其后第一個單元中的數(shù)值所指向的P1的地址,將通向P1的門(而不是別的單元的門)全部打開,然后下一步,從程序存儲器中收到的數(shù)據(jù)就直接送到P1口了。如果僅有一個單元的數(shù)據(jù)被當(dāng)作數(shù)值傳到端口,則這三步操作完成后,乙門關(guān)而甲門開,接收下一個數(shù)據(jù)并被當(dāng)作命令送入控制器中。
再一個要解決的問題是:這個要被送入的數(shù)值存在哪個單元中?
單片機(jī)數(shù)值存放地的設(shè)計是這樣的:前面說過,它們與命令一同都存在程序存儲器中,那么存放的方式就有兩種,一種是可以由程序員任意存放于任一單元中,也可以就近存放于操作這個數(shù)值的命令之后。程序員在編程中可以任選取這兩者中的任何一種進(jìn)行數(shù)值存放,對了,后一種,就是匯編語言中說的立即數(shù),也就是上面所說到的那種處理方式。
對于前一種存放方式,我們在操作時,就必須在編程中確定并輸入其地址。至于立即數(shù)方式,則直接在立即數(shù)的操作命令中指明:這個數(shù)你們別再找了,就在我身后,也就是說,前一種方式,需要向控制系統(tǒng)專門提交(源數(shù)值)地址值,而立即數(shù)方式,不再需要提交地址值。為什么有這兩種設(shè)計?立即數(shù)方式具有一定的專用性,命令少速度快,前一種方式具有通用性但命令長而執(zhí)行時間相對較長。
下面,我們就來說具體編程,流程是找到那個將立即數(shù)送入P1的命令,然后寫出這個命令,再后面跟一個立即數(shù),這個就可以運(yùn)行了。但這里還有一個問題:51機(jī)是8位機(jī),其命令最多只能做到256條,所以,理論上,在單片機(jī)設(shè)計時,可以設(shè)計這么一條直接將立即數(shù)送入P1的命令,但是,因為256條的限制,綜合考慮,設(shè)計人員不一定會給這條命令讓路也就是說,這個單片機(jī)中不一定有這條命令。
下面,我們就來在51單片機(jī)的機(jī)器指令中找一下,看有沒有這么一條指令:我們知道,單片機(jī)中,P1屬于片內(nèi)存儲單元,其地址是90H,而在其指令系統(tǒng)表中,我們找到了一條MOV direct,#data,這條匯編指令的意思是將立即數(shù)傳遞到片內(nèi)存儲器中指定的一個單元,這個命令的機(jī)器碼就是75H,這個機(jī)器碼本身已經(jīng)指明緊隨之后的程序存儲器單元中的兩個數(shù)據(jù)為數(shù)值而不是命令,其中第一個數(shù)值direct是接收數(shù)值的單元地址,第二個數(shù)值就是要被傳送的數(shù)值01001101(4DH),三字節(jié)指令。這個指令比” MOV A, #data”要多一個字節(jié),它的機(jī)器命令是74H,這個命令中,已經(jīng)指明了接收數(shù)據(jù)的地址為RAM中的E0H單元,也就是累加器A,所以,不用你再寫一個接收地址了,二字節(jié)指令,專用性很強(qiáng),就是針對累加器A,當(dāng)然,你也可以寫成那個三字節(jié)指令,也當(dāng)然,這樣做真不當(dāng)然。
好了,寫匯編程序:“MOV direct,4DH”,再加一條讓其不斷重復(fù)執(zhí)行的程序,匯編編程就完成了。當(dāng)然,別忘了end,至于前面的ORG,可以不用,如果用的話,要么地址是0000H,要么前面還得加一條跳轉(zhuǎn)。
不想寫匯編,那就可以直接寫機(jī)器語言:“75H 90H 4DH”,再加一條跳轉(zhuǎn)指令,完成。
如果你用匯編,那就得用上匯編工具;如果你用機(jī)器語言,那你可以不用匯編工具,直接在燒寫工具中,在第一個單元(0000H)中寫入75H,在第二個單元中寫入90H,在第三個單元中寫入4DH,再寫入一個跳轉(zhuǎn)到第一個單元的指令,搞定,然后燒入、運(yùn)行。當(dāng)然,在這個程序中,你也可以不加跳轉(zhuǎn),但程序存儲器中后面的單元必須全部清空,否則結(jié)果不定。
說明:在以上例子中,單片機(jī)中控制器的作用,就只是開門關(guān)門。控制器接收到命令后,就是根據(jù)這個命令開相應(yīng)的門關(guān)相應(yīng)的門。
PS:精神不太好,發(fā)一下神經(jīng),如果有錯,千萬要指出,免得害人啊。
|