久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

51單片機(jī)自學(xué)教程(8)

 梅竹修士 2012-07-18

51單片機(jī)自學(xué)教程(8)

[日期:2008-10-29 ] [來源:net 作者:佚名] [字體: (投遞新聞)
程序設(shè)計是單片機(jī)開發(fā)最重要的工作程序設(shè)計就是利用單片機(jī)的指令系統(tǒng)根據(jù)應(yīng)用系統(tǒng)即

目標(biāo)產(chǎn)品的要求編寫單片機(jī)的應(yīng)用程序其實我們前面已經(jīng)開始這樣做過了這一課我們不是講如何

來設(shè)計具體的程序而是教您設(shè)計單片機(jī)程序的基本方法不過在講解之前還是有必要先了解一下單
片機(jī)的程序設(shè)計語言

一.程序設(shè)計語言

    這里的語言與我們通常理解的語言是有區(qū)別的它指的是為開發(fā)單片機(jī)而設(shè)計的程序語言如果

您沒有學(xué)過程序設(shè)計可能不太明白我給大家簡單解釋一下您知道微軟的VB VC VB VC 就是為

某些工程應(yīng)用而設(shè)計的計算機(jī)程序語言通俗地講它是一種設(shè)計工具只不過這種工具是用來設(shè)計計

算機(jī)程序的要想設(shè)計單片機(jī)的程序當(dāng)然也要有這樣一種工具說設(shè)計語言更確切些單片機(jī)的設(shè)計

語言基本上有三類:

1 .完全面向機(jī)器的機(jī)器語言

    機(jī)器語言就是能被單片機(jī)直接識別和執(zhí)行的語言計算機(jī)能識別什么以前我們講過--是數(shù)字0

1 所以機(jī)器語言就是用一連串的0 1 來表示的數(shù)字比如MOV A 40H 用機(jī)器語言來表示就是
11100101 0100000
很顯然用機(jī)器語言來編寫單片機(jī)的程序不太方便也不好記憶我
們必須想辦法
用更好的語言來編寫單片機(jī)的程序于是就有了專門為單片機(jī)開發(fā)而設(shè)計的語言

2. 匯編語言

匯編語言也叫符號化語言它使用助記符來代替二進(jìn)制的0 1 比如剛才的MOV A40H 就是匯編語言
指令顯然用匯編語言寫成的程序比機(jī)器語言好學(xué)也好記所以單片機(jī)的指令普遍采
用匯編指令來編寫
用匯編語言寫成的程序我們就叫它源程序或源代碼可是計算機(jī)不能識別和執(zhí)行用匯編語言寫成的程
序啊怎么辦當(dāng)然有辦法我們可以通過翻譯把源代碼譯成機(jī)器語言這個過程就叫做匯編,匯編工作現(xiàn)在
都是由計算機(jī)借助匯編程序自動完成的不過在很早以前它是靠手工來做的.

值得注意的是:匯編語言也是面向機(jī)器的,它仍是一種低級語言每一類計算機(jī)都有它自己的匯

編語言比如51 系列有它的匯編語言;PIC 系列也有它的匯編語言微機(jī)也有它自己的匯編語言它

們的指令系統(tǒng)是各不相同的也就是說不同的單片機(jī)有不同的指令系統(tǒng)它們之間是不通用的,這就

是為什么世界上有很多單片機(jī)類型的緣故了,為了解決這個問題人們想了很多的辦法設(shè)計了許多的

高級計算機(jī)語言而現(xiàn)在最適合單片機(jī)編程的要數(shù)C 語言.

3 .C 語言高級單片機(jī)語言

C 語言是一種通用的計算機(jī)程序設(shè)計語言,它既可以用來編寫通用計算機(jī)的系統(tǒng)程序也可以用

來編寫一般的應(yīng)用程序,由于它具有直接操作計算機(jī)硬件的功能所以非常適合用來編寫單片機(jī)
程序與其他的計算機(jī)高級程序設(shè)計語言相比它具有以下的特點:

1 .語言規(guī)模小使用簡單

   在現(xiàn)有的計算機(jī)設(shè)計程序中C 語言的規(guī)模是最小的ANSIC 標(biāo)準(zhǔn)的C 語言一共只有32 個關(guān)鍵字

9 種控制語句然而它的書寫形式卻比較靈活表達(dá)方式簡潔使用簡單的方法就可以構(gòu)造出相當(dāng)復(fù)雜

的數(shù)據(jù)類型和程序結(jié)構(gòu)

2 .可以直接操作計算機(jī)硬件

  C 語言能夠直接訪問單片機(jī)的物理空間地址KEIL C51 軟件中的C51 編譯器更具有直接操作51

單片機(jī)內(nèi)部存儲器和I/O 口的能力亦可直接訪問片內(nèi)或片外存儲器還可以進(jìn)行各種位操作

3 .表達(dá)能力強(qiáng)表達(dá)方式靈活

   C 語言有豐富的數(shù)據(jù)結(jié)構(gòu)類型可以采用:整型\實型\字符型\數(shù)組類型\指針類型\結(jié)構(gòu)類型

\聯(lián)合類型\枚舉類型等多種數(shù)據(jù)類型來實現(xiàn)各種復(fù)雜數(shù)據(jù)結(jié)構(gòu)的運(yùn)算,利用C 語言提供的多種運(yùn)算符

我們可以組成各種表達(dá)式還可以采用多種方法來獲得表達(dá)式的值從而使程序設(shè)計具有更大的靈活性,所以
單片機(jī)入門后盡量學(xué)習(xí)C語言,。。,。,。。

二,。單片機(jī)程序設(shè)計的步驟

單片機(jī)的程序設(shè)計通常包括根據(jù)任務(wù)繪制程序流程圖編寫程序及匯編等幾個步驟

繪制流程圖

所謂流程圖就是用各種符號圖形箭頭把程序的流向及過程用圖形表示出來繪制流程圖是

單片機(jī)程序編寫前最重要的工作通常我們的程序就是根據(jù)流程圖的指向采用適當(dāng)?shù)闹噶顏砭帉懙南?/FONT>

面的圖形和箭頭就是我們繪制流程圖用的工具,,

繪制流程圖時首先畫出簡單的功能流程圖粗框圖再對功能流程圖進(jìn)行擴(kuò)充和具體化即對

存儲器標(biāo)志位等單元做具體的分配和說明把功能圖上的每一個粗框圖轉(zhuǎn)化為具體的存儲器或地址單

元從而繪制出詳細(xì)的程序流程圖即細(xì)框圖下面舉個例子給大家演示一下請看下面的程序

主程序

LOOP:SETB P1.0

LCALL DELAY

CLR P1.0

LCALL DELAY

LJMP LOOP

子程序

DELAY MOV R7 #250

D1 MOV R6 #250

D2 DJNZ R6 D2

DJNZ R7 D1

RET END。

下面結(jié)合按鍵在實驗板上做一下:

ORG 0000H

LJMP START

ORG 30H

START MOV SP #5FH

MOV P1 #0FFH

MOV P3 #0FFH

L1 JNB P3.2 L2,; P3.2 上接有一只按鍵它按下時P3.5=0

JNB P3.3 L3 ,;P3.3 上接有一只按鍵它按下時P3.6=0

LJMP L1

L2 CLR P1.0 LED1

LJMP L1

L3 SETB P1.0 LED1

LJMP L1

END

2 分支結(jié)構(gòu)程序的設(shè)計

  所謂分支結(jié)構(gòu)就是利用條件轉(zhuǎn)移指令使程序執(zhí)行某一指令后根據(jù)所給的條件是否滿足來改變

程序執(zhí)行的順序也就是本條指令執(zhí)行完后并不是象順序結(jié)構(gòu)那樣執(zhí)行下一條指令而是看本條指令

所給的條件是否滿足如果滿足條件就跳轉(zhuǎn)到其他的指令如果不滿足就順序執(zhí)行當(dāng)然也可以是滿足

條件順序執(zhí)行而不滿足條件跳轉(zhuǎn)執(zhí)行看十五課實驗程序中的下面兩條

L1 JNB P3.2 L2 ,;P3.2 上接有一只按鍵它按下時P3.2=0

JNB P3.3 L3 ,;P3.3 上接有一只按鍵它按下時P3.3=0

這就是分支結(jié)構(gòu)的程序如果P3.2 0 就轉(zhuǎn)移反之就順序執(zhí)行當(dāng)然也可以改成P3.2=0

順序執(zhí)行而P3.2=1 則轉(zhuǎn)移不過此時的程序就要用JB 指令了在51 系列單片機(jī)中可以直接用于

分支程序的指令有JB JNB JC JNC JZ JNZ CJNE JBC 等這幾條它們可以完成諸如正負(fù)判斷

大小判斷和溢出判斷等等在分支結(jié)構(gòu)的指令設(shè)計中大家必須注意.執(zhí)行一條判斷指令只可以形成

兩路分支如果要形成多路分支就必須進(jìn)行多次判斷也就是多條指令連續(xù)判斷下面給大家舉兩個

例子

A 單分支結(jié)構(gòu)的程序?qū)嵗?/FONT>

假設(shè)有兩個數(shù)在內(nèi)部RAM 單元的40H 41H 中現(xiàn)在要求找出其中較大的一個數(shù)并將較大的數(shù)

存入40H 中而將較小的一個數(shù)存入41H 中根據(jù)程序的要求我們先畫出程序的流程圖

再根據(jù)流程圖寫出程序的源代碼如下

MOV A 40H

CLR C

SUBB A 41H

JNC WAIT

MOV A 41H

XCH A 41H

MOV 40H A

WAIT SJMP WAIT

END

程序的原理請大家自行分析一下接下來再舉一個多分支結(jié)構(gòu)的實例看下面的程序

MOV A 20H 取數(shù)

JZ ZERO ,;A=0 轉(zhuǎn)移A=1 順序執(zhí)行

JB ACC 7 STORE ,;A 為負(fù)數(shù)轉(zhuǎn)移

ADD A #3 ;A 為正數(shù)則加3

SJMP STORE

ZERO MOV A #20

STORE MOV 21H A

自己畫一下本例的流程圖這里有一條指令給大家解釋一下JB ACC.3 STORE ,;ACC.3 表示累加器
中的D3 位這條指令的意思就是看一下累加器中的
D3 位是正還是負(fù)D3 是什么呢,,在這里就是0 20H 
的二進(jìn)制10000000

3 循環(huán)結(jié)構(gòu)程序的設(shè)計

循環(huán)程序是最常用的程序結(jié)構(gòu)形式在單片機(jī)的程序設(shè)計中有時要碰到一段程序需要重復(fù)執(zhí)行

多次的情況此時就要用到循環(huán)結(jié)構(gòu)程序比如前面的實驗--LED 燈閃爍程序的子程序

DELAY MOV R7 #250 ,;1

D1 MOV R6 #250 ;2

D2 DJNZ R6 D2 ,;3

DJNZ R7 D1 ,;4

RET ;5

END

在這段程序中為了延時需要多次執(zhí)行DJNZ 指令此時若用循環(huán)結(jié)構(gòu)程序就可以大大地簡化程序

的設(shè)計減少程序占用的存儲器空間循環(huán)結(jié)構(gòu)指令一般有以下四個部分組成

A 初始化部分

初始化部分主要用來設(shè)置循環(huán)的初始值包括預(yù)值數(shù)計數(shù)器和數(shù)據(jù)指針的初值比如上例中的

#250 就是預(yù)值數(shù)初值

B 循環(huán)處理部分

循環(huán)處理部分是程序的主體部分也稱為程序體通過它可以完成程序處理的任務(wù)

C 循環(huán)控制部分

循環(huán)控制部分可以控制程序循環(huán)的次數(shù)并修改預(yù)值數(shù)或計數(shù)器和指針的值檢查該循環(huán)是否執(zhí)

行了足夠的次數(shù)如果到了足夠的次數(shù)就采用條件轉(zhuǎn)移指令或判斷指令來控制循環(huán)的結(jié)束比如上例

中的3 4 指令就是當(dāng)R6 R7 中的值為0 時就轉(zhuǎn)移

C 循環(huán)結(jié)束部分

循環(huán)結(jié)束后必須返回一般用RET RETI 指令這里注意.以上四個部分中第一和第四部分

只能執(zhí)行一次而第二和第三部分可以執(zhí)行多次

     在循環(huán)程序設(shè)計中循環(huán)控制部分是程序設(shè)計的關(guān)鍵環(huán)節(jié)常用的循環(huán)控制方式有計數(shù)器控制
和條件控制兩種計數(shù)器控制就是把要循環(huán)的次數(shù)即預(yù)值數(shù)放入計數(shù)器中程序每循環(huán)一次計數(shù)器

的值就減1 一直到計數(shù)器的內(nèi)容為零時循環(huán)結(jié)束一般用DJNZ 指令而條件控制方式常預(yù)先不知

道要循環(huán)的次數(shù)只知道循環(huán)的有關(guān)條件此時就可以根據(jù)給定的條件標(biāo)志位來判斷程序是否繼續(xù)一

般參照分支結(jié)構(gòu)方法中的條件來判別指令并執(zhí)行下面舉幾個例子來分別解釋一下希望大家能以此類推

程序一用計數(shù)器控制的單重循環(huán)程序

源程序如下

CLR A

MOV R2 20H

MOV R1 22H

LOOP ADD A @R1

INC R1

DJNZ R2 LOOP

MOV 21H A

這段程序的作用是從22H 單元開始存放一個數(shù)據(jù)塊其長度存放在20H 單元中將數(shù)據(jù)塊求和

要求將和存放入21H 單元中和不超過255 下面再舉一個條件控制的循環(huán)程序

程序二用條件控制的單重循環(huán)程序

設(shè)字符串存放在內(nèi)部RAM 21H 開始的單元中以結(jié)束作標(biāo)志要求計算出該字符串的長度并

將其存放在20H 單元中

源程序如下

CLR A

MOV R0 #21H 將地址指針指向21H 單元

LOOP CJNZ @R0 #24H NEXT SJMP COMP 找到結(jié)束

NEXT INC A 不為0 計數(shù)器加1

INC R0 修改地址指針

SJMP LOOP

COMP MOV 20H A 存放結(jié)果

試試看自己把上面兩段程序的流程圖畫出來下面再看一個例子

DELAY MOV R7 #250

D1 MOV R6 #250

D2 DJNZ R6 D2

DJNZ R7 D1

RET

END

 

這是一段約125mS 的延時程序,比較左右兩邊的

DELAY MOV R7 #250             DELAY MOV R7 #250

D1 MOV R6 #250                D1 MOV R6 #250

D2 DJNZ R6 D2                  D2 MOV R5 #250

DJNZ R7 D1                       D3 DJNZ R5 D3

RET                                DJNZ R6 D2

END                                  DJNZ R7 D1

                                       RET
                                      END

    從這里可以引出一個概念,程序的嵌套:什么是嵌套比如早上我騎自行車從家里到單位去上班

當(dāng)走到半路上時太太叫我去孩子學(xué)校拿點東西到了學(xué)校老師又叫我把學(xué)校的一臺電腦修一下修

好電腦一個朋友又打電話叫我去他那里拿了一本單片機(jī)與嵌入式系統(tǒng)雜志完了之后再去上班

這就是生活中的嵌套在單片機(jī)的程序設(shè)計中也有類似的現(xiàn)象有時為了達(dá)到某個目的往往要在一

段循環(huán)程序中再加入另一段循環(huán)程序這就是單片機(jī)的程序嵌套通常我們把一個循環(huán)體中不再包含循

環(huán)的叫做單重嵌套如果一個循環(huán)體中還包括有循環(huán)則叫做多重嵌套上面的左邊的程序就是

單重嵌套而右邊的程序則是多重嵌套另外須注意.在多重嵌套中不允許各個循環(huán)體互相交叉

也不允許從外循環(huán)跳入內(nèi)循環(huán)否則編譯時會出錯了解了結(jié)構(gòu)化程序的設(shè)計下面再來看子程序的設(shè)

計方法

2 子程序的設(shè)計方法

  什么是子程序,如何設(shè)計子程序要解釋這個問題讓我們先同樣從生活中的一個例子說起請

看下面的數(shù)學(xué)題目28* 33+65 +47* 33+65 +875* 33+65 在這道題中我們一般是怎么算的

也許大家都知道一般總是先把33+65 =98 代出來然后再用28+47+875 *98 來計算最后的結(jié)果

為什么會這樣這是因為在這道題中我們多次用到了33+65 這個中間結(jié)果在單片機(jī)的程序設(shè)計

中有時也有這樣的情況比如下面的程序

主程序

LOOP:SETB P1.0

LCALL DELAY

CLR P1.0

LCALL DELAY

LJMP LOOP

子程序

DELAY:MOV R7,#250

D1:MOV R6,#250

D2:DJNZ R6,D2

DJNZ R7,D1

RET END

    這是大家非常熟悉的LED 燈延時程序在這段程序中兩次調(diào)用到了DELAY 這段程序為了簡

化程序的設(shè)計我們就把DELAY 這段程序單獨地列了出來這段列出的程序我們就叫它子程序而調(diào)

用子程序的程序我們則叫它主程序LOOP 的程序段在主程序執(zhí)行時每當(dāng)要用到子程序時我們

就用LCALL 指令來調(diào)用子程序子程序執(zhí)行完之后必須返回主程序返回就用RET 指令這我們

以前都講過了這里不再重復(fù)

      這里有個問題在子程序的執(zhí)行過程中有時可能要使用到累加器和某些工作寄存器而在調(diào)用

子程序前這些寄存器中可能已經(jīng)存放有主程序的中間結(jié)果它們在子程序返回后仍要使用這樣就需

要在進(jìn)入子程序之前將要使用的累加器和寄存器中的內(nèi)容預(yù)先轉(zhuǎn)移到安全的地方保存起來這叫現(xiàn)場

保護(hù)當(dāng)子程序執(zhí)行完即將返回主程序之前還要將這些內(nèi)容先取出來送回到累加器和原來的工作寄

存器中這個過程叫恢復(fù)現(xiàn)場,,保護(hù)現(xiàn)場和恢復(fù)現(xiàn)場通常使用堆棧即在進(jìn)入子程序之前將需要保護(hù)的
數(shù)據(jù)壓入堆棧在返回之前再將壓入的數(shù)據(jù)彈出到原來的工作單元中恢復(fù)原來的狀態(tài)看下面的例子

LOOP PUSH 03H 03H 單元中的值壓入堆棧保護(hù)

PUSH ACC 將累加器中的值壓入堆棧保護(hù)

POP ACC ACC 中的值從堆棧彈出

POP 03H 恢復(fù)03H 單元中的內(nèi)容

RET 從子程序返回

     由于堆棧的操作是后進(jìn)先出先進(jìn)后出所以編寫指令時必須把后壓入堆棧的數(shù)據(jù)先彈出來

才能保證恢復(fù)到原來的狀態(tài)在實際的程序設(shè)計中由于每個應(yīng)用程序的不同還必須根據(jù)具體的情況

來考慮是否需要保護(hù)哪些數(shù)據(jù)需要保護(hù)等等這就是單片機(jī)的堆棧為什么能夠變化的原因關(guān)于堆棧

的操作先講這些1 2 3 4 5也算是對以前的總結(jié)吧

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點,。請注意甄別內(nèi)容中的聯(lián)系方式,、誘導(dǎo)購買等信息,謹(jǐn)防詐騙,。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報,。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多