8課:單片機尋址方式與指令係統

18luck网站

18luck网站電子設計 | 18luck网站Rss 2.0 會員中心 會員注冊
搜索: 您現在的位置: 18luck网站 >> 18luck平台 >> 單片機 >> 正文

8課:單片機尋址方式與指令係統

作者:佚名    文章來源:本站原創    點擊數:    更新時間:2017-7-7

   通過前麵的學習(xi) ,我們(men) 已經了解了單片機內(nei) 部的結構,並且也已經知道,要控製單片機,讓它為(wei) 我們(men) 幹學,要用指令,我們(men) 已學了幾條指令,但很零散,從(cong) 現在開始,我們(men) 將要係統地學習(xi) 8051單片機的指令部份。

一、概述

1、指令的格式

   我們(men) 已知,要讓計算機做事,就得給計算機以指令,並且我們(men) 已知,計算機很“笨”,隻能懂得數字,如前麵我們(men) 寫(xie) 進機器的75H,90H,00H等等,所以指令的第一種格式就是機器碼格式,也說是數字的形式。但這種形式實在是為(wei) 難我們(men) 人了,太難記了,於(yu) 是有另一種格式,助記符格式,如MOV P1,#0FFH,這樣就好記了。 這兩(liang) 種格式之間的關(guan) 係呢,我們(men) 不難理解,本質上它們(men) 完全等價(jia) ,隻是形式不一樣而已。

2、匯編

  我們(men) 寫(xie) 指令使用匯編格式,而計算機和單片機隻懂機器碼格式,所以要將我們(men) 寫(xie) 的匯編格式的指令轉換為(wei) 機器碼格式,這種轉換有兩(liang) 種辦法:手工匯編和機器匯編。手工匯編實際上就是查表,因為(wei) 這兩(liang) 種格式純粹是格式不一樣,所以是一一對應的,查一張表格就行了。不過手工查表總是嫌麻煩,所以就有了計算機軟件,用計算機軟件來替代手工查表,這就是機器匯編。

二、單片機的尋址

  讓我們(men) 先來複習(xi) 一下我們(men) 學過的一些指令:MOV P1,#0FFH,MOV R7,#0FFH這些指令都是將一些數據送到對應的位置中去,為(wei) 什麽(me) 要送數據呢?第一個(ge) 因為(wei) 送入的數能讓燈全滅掉,第二個(ge) 是為(wei) 了要實現延時,從(cong) 這裏我們(men) 能看出來,在用單片機的編程語言編程時,經常要用到數據的傳(chuan) 遞,事實上數據傳(chuan) 遞是單片機編程時的一項重要工作,一共有28條指令(單片機共111條指令)。下麵我們(men) 就從(cong) 數據傳(chuan) 遞類指令開始吧。

  分析一下MOV P1,#0FFH這條指令,我們(men) 不難得出結論,第一個(ge) 詞MOV是命令動詞,也就是決(jue) 定做什麽(me) 事情的,MOV是MOVE少寫(xie) 了一個(ge) E,所以就是“傳(chuan) 遞”,這就是指令,規定做什麽(me) 事情,後麵還有一些參數,分析一下,數據傳(chuan) 遞必須要有一個(ge) “源”也就是你要送什麽(me) 數,必須要有一個(ge) “目的”,也就是你這個(ge) 數要送到什麽(me) 地方去,顯然在上麵那條單片機指令中,要送的數(源)就是0FFH,而要送達的地方(目的地)就是P1這個(ge) 寄存器。在數據傳(chuan) 遞類指令中,均將目的地寫(xie) 在指令的後麵,而將源寫(xie) 在最後。

  這條指令中,送給P1是這個(ge) 數本身,換言之,做完這條指令後,我們(men) 能明確地知道,P1中的值是0FFH,但是並不是任何時候都能直接給出數本身的。例如,在我們(men) 前麵給出的單片機延時程序例是這樣寫(xie) 的:

MAIN: SETB P1.0     ;(1)

   LCALL DELAY ;(2)

    CLR P1.0      ;(3)

   LCALL DELAY   ;(4)

    AJMP MAIN    ;(5)

;以下子程序

DELAY: MOV R7,#250   ;(6)

D1: MOV R6,#250   ;(7)

D2: DJNZ R6,D2    ;(8)

   DJNZ R7,D1   ;(9)

   RET        ;(10)

   END        ;(11)

表1

-----------------------------------------------------

 MAIN: SETB P1.0     ;(1)

   MOV 30H,#255

    LCALL DELAY ;

    CLR P1.0      ;(3)

    MOV 30H,#200

    LCALL DELAY   ;(4)

    AJMP MAIN    ;(5)

;以下子程序

DELAY: MOV R7,30H   ;(6)

D1: MOV R6,#250   ;(7)

D2: DJNZ R6,D2    ;(8)

   DJNZ R7,D1   ;(9)

   RET        ;(10)

   END        ;(11)

表2

 這樣一來,我每次調用延時程序延時的時間都是相同的(大致都是0.13S),如果我提出這樣的要求:燈亮後延時時間為(wei) 0.13S燈滅,燈滅後延時0.1秒燈亮,如此循環,這樣的程序還能滿足要求嗎?不能,怎麽(me) 辦?我們(men) 能把延時程序改成這樣(見表2):調用則見表2中的主程,也就是先把一個(ge) 數送入30H,在子程序中R7中的值並不固定,而是根據30H單元中傳(chuan) 過來的數確定。這樣就能滿足要求。

 

   從(cong) 這裏我們(men) 能得出結論,在數據傳(chuan) 遞中要找到被傳(chuan) 遞的數,很多時候,這個(ge) 數並不能直接給出,需要變化,這就引出了一個(ge) 概念:如何尋找操作數,我們(men) 把尋找操作數所在單元的地址稱之為(wei) 尋址。在這裏我們(men) 直接使用數所在單元的地址找到了操作數,所以稱這種辦法為(wei) 直接尋址。除了這種辦法之外,還有一種,如果我們(men) 把數放在工作寄存器中,從(cong) 工作寄存器中尋找數據,則稱之為(wei) 寄存器尋址。例:MOV A,R0就是將R0工作寄存器中的數據送到累加器A中去。提一個(ge) 問題:我們(men) 知道,工作寄存器就是內(nei) 存單元的一部份,如果我們(men) 選擇工作寄存器組0,則R0就是RAM的00H單元,那麽(me) 這樣一來,MOV A,00H,和MOV A,R0不就沒什麽(me) 區別了嗎?為(wei) 什麽(me) 要加以區別呢?的確,這兩(liang) 條指令執行的結果是完全相同的,都是將00H單元中的內(nei) 容送到A中去,但是執行的過程不一樣,執行第一條指令需要2個(ge) 周期,而第二條則隻需要1個(ge) 周期,第一條指令變成最終的目標碼要兩(liang) 個(ge) 字節(E5H 00H),而第二條則隻要一個(ge) 字節(E8h)就能了。

 

  這麽(me) 斤斤計較!不就差了一個(ge) 周期嗎,如果是12M的晶體(ti) 震蕩器的話,也就1個(ge) 微秒時間了,一個(ge) 字節又能有多少?

   不對,如果這條指令隻執行一次,也許無所謂,但一條指令如果執行上1000次,就是1毫秒,如果要執行1000000萬(wan) 次,就是1S的誤差,這就很可觀了,單片機做的是實時控製的事,所以必須如此“斤斤計較”。字節數同樣如此。

再來提一個(ge) 問題,現在我們(men) 已知,尋找操作數能通過直接給的方式(立即尋址)和直接給出數所在單元地址的方式(直接尋址),這就夠了嗎?

看這個(ge) 問題,要求從(cong) 30H單元開始,取20個(ge) 數,分別送入A累加器。

   就我們(men) 目前掌握的辦法而言,要從(cong) 30H單元取數,就用MOV A,30H,那麽(me) 下一個(ge) 數呢?是31H單元的,怎麽(me) 取呢?還是隻能用MOV A,31H,那麽(me) 20個(ge) 數,不是得20條指令才能寫(xie) 完嗎?這裏隻有20個(ge) 數,如果要送200個(ge) 或2000個(ge) 數,那豈不要寫(xie) 上200條或2000條命令?這未免太笨了吧。為(wei) 什麽(me) 會(hui) 出現這樣的狀況?是因為(wei) 我們(men) 隻會(hui) 把地址寫(xie) 在指令中,所以就沒辦法了,如果我們(men) 不是把地址直接寫(xie) 在指令中,而是把地址放在另外一個(ge) 寄存器單元中,根據這個(ge) 寄存器單元中的數值決(jue) 定該到哪個(ge) 單元中取數據,比如,當前這個(ge) 寄存器中的值是30H,那麽(me) 就到30H單元中去取,如果是31H就到31H單元中去取,就能解決(jue) 這個(ge) 問題了。怎麽(me) 個(ge) 解決(jue) 法呢?既然是看的寄存器中的值,那麽(me) 我們(men) 就能通過一定的辦法讓這裏麵的值發生變化,比如取完一個(ge) 數後,將這個(ge) 寄存器單元中的值加1,還是執行同一條指令,可是取數的對象卻不一樣了,不是嗎。通過例程來說明吧。

MOV R7,#20

   MOV R0,#30H

LOOP:MOV A,@R0

   INC R0

   DJNZ R7,LOOP

    這個(ge) 例程中大部份指令我們(men) 是能看懂的,第一句,是將立即數20送到R7中,執行完後R7中的值應當是20。第二句是將立即數30H送入R0工作寄存器中,所以執行完後,R0單元中的值是30H,第三句,這是看一下R0單元中是什麽(me) 值,把這個(ge) 值作為(wei) 地址,取這個(ge) 地址單元的內(nei) 容送入A中,此時,執行這條指令的結果就相當於(yu) MOV A,30H。第四句,沒學過,就是把R0中的值加1,因此執行完後,R0中的值就是31H,第五句,學過,將R7中的值減1,看是否等於(yu) 0,不等於(yu) 0,則轉到標號LOOP處繼續執行,因此,執行完這句後,將轉去執行MOV A,@R0這句話,此時相當於(yu) 執行了MOV A,31H(因為(wei) 此時的R0中的值已是31H了),如此,直到R7中的值逐次相減等於(yu) 0,也就是循環20次為(wei) 止,就實現了我們(men) 的要求:從(cong) 30H單元開始將20個(ge) 數據送入A中。

這也是一種尋找數據的辦法,由於(yu) 數據是間接地被找到的,所以就稱之為(wei) 間址尋址。注意,在間址尋址中,隻能用R0或R1存放等尋找的數據。

Tags:單片機教程,指令係統,單片機  
責任編輯:admin
請文明參與討論,禁止漫罵攻擊,不要惡意評論、違禁詞語。 昵稱:
1分 2分 3分 4分 5分

還可以輸入 200 個字
[ 查看全部 ] 網友評論
關於我們 - 聯係我們 - 廣告服務 - 友情鏈接 - 網站地圖 - 版權聲明 - 在線幫助 - 文章列表
返回頂部
刷新頁麵
下到頁底
晶體管查詢
51La