單片機匯編實現延遲的程序代碼:
DELAY: MOV R7,#250 ;
D1: MOV R6,#250 ;
D2: DJNZ R6,D2 ;
DJNZ R7,D1 ;
RET
如果用高級語言編程,隻需要簡單地調用延時函數就可以實現,但是計算機具體(ti) 是怎麽(me) 實現的呢?要想知其所以然,還得從(cong) 匯編開始學起。
冒號前麵的“DELAY”、“D1”、“D2”為(wei) 語句行的名字,是為(wei) 了程序的條件語句跳轉用的,分號後麵為(wei) 注釋,計算機執行時將過濾掉這些信息,最大限度減少代碼長度,提高效率。
DELAY: MOV R7,#250 ; 名字為(wei) “DELAY”的語句:意思是將CPU內(nei) 部內(nei) 存RAM的R7位置填寫(xie) 為(wei) 250(原來為(wei) 0,為(wei) 什麽(me) 是0呢?因為(wei) 任何程序開始執行前都要複位,就像我們(men) 打算盤要將算子複位一樣,或者我們(men) 用沙盤寫(xie) 字,要將沙盤抹平類似)
D1: MOV R6,#250 ; 名字為(wei) “D1”的語句:將R6位置填寫(xie) 為(wei) 250
D2: DJNZ R6,D2 ; 名字為(wei) “D2”的語句:將R6位置的250減1,如果為(wei) 0就繼續執行下一條,不為(wei) 0就繼續執行D2這一句,因為(wei) R6=250,所以這個(ge) 語句要原地踏步執行250次!
DJNZ R7,D1 ; 這句沒有名字,因為(wei) 沒有別的語句要跳到這裏,所以就省略了。R7同樣等於(yu) 250,但它不是原地踏步,而是跳回了D1,這麽(me) 幹,D!、D2和本句將被循環執行250遍,需要強調的是:D2語句自身每次都要執行250遍,也就是執行了250*250=62500遍!
RET ;子程序結束(因為(wei) 延時程序一般不作為(wei) 獨立程序存在,它隻是一個(ge) 子程序,也就是高級語言中的一個(ge) 函數,看到這個(ge) 字符,子程序將跳回到母程序,進行下一步)。
這個(ge) 子程序這麽(me) 反複地循環指令,到底有什麽(me) 意義(yi) 呢?又是怎麽(me) 實現的延時程序呢?說起來計算機真是有點笨,它是*數程序執行的次數來累加時間的!也就是說語句本身就是為(wei) 了浪費時間!哈哈,可笑吧?這就像你沒有鍾表,但是你知道你跑操場一圈是一分鍾,然後就繞著操場跑了60圈,時間過了正好一小時一樣。
如果是人的話,誰也不會(hui) 笨到幹這麽(me) 累的活兒(er) 來計時,但計算機不一樣,它不論靜止還是運動,程序總是一拍一拍地運行著,所以它不累。
那麽(me) ,計算機執行一個(ge) 語句耗費的時間是多少呢?
以51型單片機為(wei) 例:如果采用12MHz的晶振,運行一個(ge) 機器周期為(wei) 1微秒,具體(ti) 為(wei) 什麽(me) 暫時不管。單片機的指令係統分為(wei) 單周期、雙周期和三周期指令(三周期實際上占用四個(ge) 周期,多餘(yu) 一個(ge) 周期浪費掉),這是有指令的內(nei) 容決(jue) 定的,內(nei) 容多的單周期執行不完,肯定要延長了。子程序裏麵的MOV是單周期、DJNZ是雙周期。
這樣,我們(men) 就可以算算這個(ge) 子程序累計進行了多少個(ge) 周期,然後乘以1微秒,就算出它占用的時間,也就是延時的時長了!
第一句:DELAY: MOV R7,#250 ;執行了一次,沒有任何語句跳轉給它,單周期。1
第二句:D1: MOV R6,#250 ;執行了250次,全部是第四句跳過來的,單周期。250
第三句:D2: DJNZ R6,D2 ;原地執行了250次,從(cong) 第二句順延(第二句執行完,沒有其它跳轉的話肯定要執行第三句)過來250次,也就是250*250=62500次,雙周期*2。125000
第四句:DJNZ R7,D1 ; 從(cong) 第三句順延過來250次,雙周期*2。500
總計:1+250+125000+500=1257501次,乘以1微秒,換算約為(wei) 0.13秒。
我們(men) 可以通過調整R6、R7的數值來調整延時的長度。事實上,8位計算機中,R6之類的工作寄存器地址最大隻能放下255的十進製數值,因此要通過上述程序達到更長的延時是辦不到的。
那怎麽(me) 辦呢?
我們(men) 可以再增加一個(ge) R4,讓上述的程序最多可以循環255遍,這樣,0.13秒的200多倍就是30秒上下了,不夠的話再增加循環,又可以擴大200多倍,當然,工作寄存器的數量是有限的,因此這個(ge) 延時程序也是有限的,如果還不夠用怎麽(me) 辦呢,就目前我所學的知識,隻能在母程序裏麵設置循環了,也就是讓這個(ge) 子程序在母程序裏麵繼續循環......