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