<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>

新聞中心

EEPW首頁(yè) > 嵌入式系統 > 設計應用 > 單片機學(xué)習之六:基本I/O口試驗二:跑馬燈

單片機學(xué)習之六:基本I/O口試驗二:跑馬燈

作者: 時(shí)間:2016-09-18 來(lái)源:網(wǎng)絡(luò ) 收藏

  一、試驗現象:

本文引用地址:http://dyxdggzs.com/article/201609/297082.htm

  二極管從右至左依次發(fā)光。

  二、試驗目的:

  l 掌握寄存器A,Rn的使用方法

  l 掌握左移指令

  l 掌握延時(shí)程序的編寫(xiě)

  三、任務(wù)分析:

  電路圖同試驗1,有了上一個(gè)試驗的基礎,這個(gè)程序對我們就沒(méi)有什么難度啦。我們可以這樣作:

  首先:mov p0,#ofeh(讓最右邊的燈亮),然后經(jīng)過(guò)一段延時(shí),再:mov p1,#ofdh,這樣依次賦值,直到:mov p0,#07fh(最左面的燈亮)。然后用ajmp指令返回,讓燈光再重新開(kāi)始循環(huán)。

  這樣固然可以,但是程序不夠簡(jiǎn)單明了,我們要寫(xiě)8個(gè)mov語(yǔ)句。設想一下,假如有幾十個(gè)燈,那寫(xiě)起來(lái)不是麻煩死啦?

  好在有一條左移指令rl a,它的作用是把累加器a中的數循環(huán)左移。

  順便說(shuō)一下累加器a,它是中的最常用的寄存器,大部分單操作數的指令都以a作為操作對象(例如rl a);也有很多雙操作數指令的一個(gè)操作數取自a(例如mov a,#00h);還有加、減、乘、除等算數指令的運算結果也經(jīng)常保留在a中,或者ab寄存器對中。

  所以我們的程序就可以這樣來(lái)實(shí)現啦:首先給a賦值,再輸出到p0;然后延時(shí);接下來(lái)把a中的數進(jìn)行左移。然后重復上面的過(guò)程就可以啦。

  四、試驗程序

  org 0000h

  start: clr p1.5

  mov a,#0feh ;給a賦立即數,執行之后,a中的數據是11111110

  loop: mov p0,a ;把a中的數據傳輸到p0

  lcall delay ;(1)

  rl a ;(2)

  ajmp loop ;返回標號為loop的指令

  delay: mov r6,#02h ;(3)

  del1: mov r5,#0ffh ;(4)

  del2: djnz r5,del2 ;(5)

  djnz r6,del1 ;(6)

  ret ;(7)

  end

  注釋?zhuān)?/p>

  1、這是一個(gè)子程序調用指令。在程序設計中,常常把具有一定功能的公用程序編成子程序,以便讓主程序調用。

  該指令的執行過(guò)程是這樣的:當執行lcall指令后,程序就轉到lcall后面標號delay指定的程序處往下執行,當執行遇到ret指令時(shí),就返回lcall指令下面的一條指令,即rl a指令。

  從上面的分析,我們可以知道:標號為delay的程序應該是一段延時(shí)程序,那么它到底延時(shí)了多長(cháng)時(shí)間呢?我們一會(huì )給大家講解這個(gè)時(shí)間的計算方法,先往下看吧。

  同樣,子程序調用也有兩條指令:acall和lcall。兩者的區別是:acall指令調用的子程序起始地址必須和acall后面的第一條指令在同一個(gè)2k區域的程序存儲器內;而lcall指令可以調用存放在程序存儲器中64K字節范圍內的任何地方的子程序。簡(jiǎn)單的說(shuō)就是acall調用的范圍小,而lcall的范圍大。如果你拿不準的話(huà),就用lcall吧。

  2、這條指令的功能是:把累加器a中的內容向左移動(dòng)一位,最高位的內容A7被移動(dòng)到最低位A0,圖示如下:

  

 

  3、現在我們來(lái)分析delay子程序的延時(shí)時(shí)間:

  我們先看(3)(4)(5)(6)(7)這樣幾個(gè)語(yǔ)句:

  (3)的意思是給r6賦值02h。r6是什么?我們好像以前沒(méi)有說(shuō)過(guò)。大家先知道它也是一個(gè)8位的寄存器就行啦,關(guān)于它的內容,我們下面在介紹。

  (4)的意思和(3)類(lèi)似,不再贅述。

  (5)應用了djnz指令,這個(gè)指令的意思是:減1不為0轉移。因此語(yǔ)句(6)的意思是:把r5中間存的內容減去1,如果不是0,就繼續執行該條語(yǔ)句,否則,執行下面的語(yǔ)句。

  (6)根據上面的分析我們知道:(6)的意思是:把r6中的內容減1,如果不是0,就返回標號為del1的程序,重新給r5賦值0ffh,然后在對r5進(jìn)行減1運算。

  從分析可見(jiàn),如果延時(shí)程序執行完,djnz指令總的執行次數是:02h×0ffh,即2×255=510次。

  可見(jiàn),如果我們知道執行一次djnz指令的時(shí)間,我們就可以算出這個(gè)程序的延時(shí)時(shí)間了。那么執行一次djnz指令需要多少時(shí)間呢?

  的指令執行起來(lái)所花費的時(shí)間是不一樣的,有的指令執行時(shí)間短,只需要1個(gè)機器周期,而有的指令執行時(shí)間長(cháng),需要4個(gè)機器周期。Djnz指令的執行時(shí)間是2個(gè)機器周期。

  每一個(gè)機器周期又是多長(cháng)呢?從相關(guān)教材上,我們知道1個(gè)機器周期是振蕩周期的12倍。

  而振蕩周期T=1/振蕩頻率=1/12MHZ

  所以延時(shí)程序的總的延時(shí)時(shí)間是:2×255×2×12×(1/12MHZ)=1ms

  好啦,現在把上面的程序下載到單片機中,你看到了什么?

  怎么回事,所有的燈都亮啦!

  當然啦,因為我們的延時(shí)太短啦,只有1ms,所以我們的眼睛根本分辨不出來(lái)。我們現在把延時(shí)增加為100ms,程序修改如下:

  org 0000h

  start: clr p1.5

  mov a,#0feh

  loop: mov p0,a

  lcall delay

  rl a

  ajmp loop

  delay: mov r7,#100 ;把1ms延時(shí)子程序執行100次

  del1: mov r6,#02h

  del2: mov r5,#0ffh

  del3: djnz r5,del3

  djnz r6,del2

  djnz r7,del1

  ret

  end

  現在再看看,一切正常啦,ok!

  4、現在來(lái)看看寄存器R的問(wèn)題

  單片機的存儲器結構和常見(jiàn)的微型計算機的配置方式不同,把程序存儲器和數據存儲器分開(kāi)。程序存儲器用來(lái)存放程序,數據存儲器用來(lái)存放程序運行需要的常數和變量。

  單片機的數據存儲器分為內部存儲器和外部存儲器,用mov訪(fǎng)問(wèn)內部數據存儲器,用movx訪(fǎng)問(wèn)外部數據存儲器。

  內部數據存儲器是最靈活的地址空間,一共有256字節。這256個(gè)字節被分為兩組:00h~7fh的低128字節是內部RAM區;80h~ffh的高128字節為特殊功能寄存器區。其中低128字節的地址分配如下圖所示:

  

 

  從圖上可見(jiàn),低128字節中,從00h~1fh共32個(gè)字節是四個(gè)通用的工作寄存器區,每一個(gè)區有8個(gè)工作寄存器,編號均為從R0~R7。

  大家可能會(huì )問(wèn),既然四個(gè)工作寄存器組的名字都叫R0~R7,那么,上面的程序中間用的寄存器到底是哪個(gè)呢?

  當前程序使用的工作寄存器區是有程序狀態(tài)字PSW決定的。

  那么PSW又在哪里呢?

  剛才我們說(shuō)到80h~ffh的高128字節是特殊功能寄存器區,PSW就在這個(gè)區里面。這個(gè)區域還有很多別的特殊功能寄存器,大家可以參考相關(guān)資料。

  PSW是一個(gè)8位的寄存器,它各位的說(shuō)明如下:

  

 

  其中,決定選擇哪個(gè)寄存器區的是RS1和RS0這兩位,為00時(shí),選擇0區;01時(shí)選擇1區;10時(shí)選擇2區;11時(shí)選擇3區。

  大家可能會(huì )問(wèn),程序中間并沒(méi)有給這個(gè)寄存器賦值,那么它到底選擇哪個(gè)區域呢?

  由于單片機被復位后,所有的寄存器請零,所以在本程序中,缺省的使用的是0區的寄存器組。

  5、課后練習

  (1)、學(xué)習該試驗中出現的理論知識,包括程序存儲器,數據存儲器的地址分配,和相關(guān)指令。

  (2)、編寫(xiě)一個(gè)程序,讓二極管從左至右發(fā)光,延遲時(shí)間是1s,即1000ms。注意,可不是把上面程序中的mov r7,#100,改成mov r7,#1000,那么簡(jiǎn)單哦。



關(guān)鍵詞: 單片機 跑馬燈

評論


相關(guān)推薦

技術(shù)專(zhuān)區

關(guān)閉
国产精品自在自线亚洲|国产精品无圣光一区二区|国产日产欧洲无码视频|久久久一本精品99久久K精品66|欧美人与动牲交片免费播放
<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>