久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 26312|回復(fù): 1
收起左側(cè)

單片機點亮第一盞燈實驗詳細(xì)教程

[復(fù)制鏈接]
ID:161768 發(fā)表于 2017-5-20 17:30 | 顯示全部樓層 |閱讀模式
第一個實驗:keil軟件使用與點亮人生的第一只發(fā)光二極管

本實驗教程的 pdf完整版下載及配套的的仿真工程文件和源碼下載地址:http://www.zg4o1577.cn/bbs/dpj-85401-1.html
1.001.jpg




本章詳細(xì)介紹單片機程序常用編譯軟件 Keil 的用法,用一個完整的 C51 程序來操作發(fā)光二極管的點亮與熄滅,然后調(diào)用 C51 庫函數(shù)來方 便地實現(xiàn)流水燈,從這一章開始我們將手把手地講解單片機 C 語言編 程。認(rèn)真學(xué)好本章,對于初學(xué)者來說將會是一個非常好的開頭。


用實操點亮一只燈程序來學(xué)會使用編程軟件 keil 的基本功能。

最終目標(biāo):點亮下圖 D8 發(fā)光二極管。

1 電路走線如下:

1.002.jpg



2 元件特性 發(fā)光二極管的原理

1.003.jpg


正極這邊為高電平,負(fù)極為低電平,發(fā)光二極管就行,兩邊為高電平, 發(fā)光二極管就不亮。


3 程序流程:把 P1.1~P1.7 置高電平,P1.0 置低電平即可。

4 程序的書寫與調(diào)試。 我們要書寫程序,需要一個 keil 軟件。


Keil 的操作步驟。 詳細(xì)操作步驟:

1.004.jpg



從圖片中不難看出,我們寫的程序(子項目)都是圍繞總項目轉(zhuǎn)的, 然后從總項目輸出我們想要的單片機程序。



第一步:新建總項目(打開軟件跟著做,熟悉一下)



當(dāng)我們安裝好 Keil Uvision 3 編程軟件后,就點 projec(t
項目)——new



prouect(新項目)來新建項目。

1.005.jpg


點擊完 new project 后,會有如下對話框。

1.006.jpg

從上面不難看出,我們新建的單片機程序項目后綴名字是 uv2,而且

當(dāng) uv2 項目產(chǎn)生的時候,會自動附帶很多其它 uv2 需要的文件,為了 防止我們產(chǎn)生瀏覽混亂,這個時候我們就需要“新建一個文件夾”, 把 uv2 存在里面,那么附帶的文件也會自己存進(jìn)去這個文件夾里面去 方便我們?yōu)g覽和操作了。



1.007.jpg


我命名字為“點亮一只燈”,并且雙擊進(jìn)入這個文件夾里面。

1.008.jpg




1.009.jpg







CPU 選擇是找到 Atmel 并點擊其它+號。



1.010.jpg










往下拉,找到 AT89C52(選擇 51 類型的單片機)

1.011.jpg





選擇后,點確定按鈕。








1.012.jpg




是否復(fù)制 51 標(biāo)準(zhǔn)代碼,這個暫時沒有什么用,點否就可以。

1.013.jpg


這個時候,我們才創(chuàng)建好總項目,從一開始的圖片我們看到,還需要

為總項目“添加子項目”。




下面圖片指針頭指的是,點亮一盞燈的總項目,通過上面的操作,已 經(jīng)創(chuàng)建完成。


1.014.jpg








第二步:為總項目添加子項目




為總項目添加子項目之前,我們需要新建一個文件(程序編輯窗口), 點擊軟件 file 下面那個文本圖標(biāo) create a newfile(創(chuàng)建一個新的文件)




1.015.jpg








得到如下圖的程序編輯窗口,在這里面編寫單片機的程序。

1.016.jpg




現(xiàn)在我們需要的是點亮一只燈的程序。


1.017.jpg




#include Main()

{ P1=0xfe;

} 寫好后,我們還不知道子項目里的程序有沒有錯,現(xiàn)在我們需要把這 個子項目添加到“點亮一只燈.uv2”的總項目里,去讓軟件查錯,方 便我們修正,輸出我們想要的單片機代碼去讓單片機工作,那需要如 何做呢?



很顯然,當(dāng)我們新建一個子項目編輯窗口時(子項目),軟件是沒有

把這個子項目存到總項目當(dāng)中的,而是需要我們?nèi)耸痔砑舆M(jìn)去。










操作方法是:先保存,然后再把這個子項目添加到總項目去。







先保存。

需要點擊如下圖的圖標(biāo) save the active document(保存活動文檔),就 是保存當(dāng)前編輯中的程序編輯窗口(子項目)。





1.018.jpg


或許有些朋友很聰明,看到窗口上的*號就知道還沒有保存的文件。
















默認(rèn)保存在我們創(chuàng)建的“點亮一只燈”文件夾當(dāng)中,還有重要的一點

是,記得文件名后綴必須是“.c”,第二次:文件名后綴必須是“.c” 第三次:文件名后綴必須是“.c”,重要是事情說三遍,這樣后面的 操作就會萬無一失了。





1.019.jpg







保存后,某些字母是有顏色的,這個就是保存好的象征,如下圖所示:


1.020.jpg








保存后,現(xiàn)在我們需要把子項目添加到總項目當(dāng)中。



1.021.jpg







鼠標(biāo)右擊“source              group1”選擇”add file to group ’source group1 ’”(添

加文件到組,根源組 1)


1.022.jpg







默認(rèn)打開的就是“點亮一只燈”文件夾下面的“點亮一點燈”的 C 語

言程序(就是我們剛剛保存的.c 文件) 然后點窗口上的 add(添加),




1.023.jpg




Source group1 下有了“點亮一只燈”的 C 語言程序

1.024.jpg



添加成功后,就退出上面那個添加窗口。





添加子項目到總項目后,我們還不知道我們寫的程序有沒有錯,現(xiàn)在

1.025.jpg 要做的是,讓軟件查錯,那要如何做呢? 如下圖所示。






































如果總項目只有一個子項目的時候(就像點亮一只燈.c),我們就點 built target,如果有二個或以上的子項目,就點 built all target files, 就兩個按鈕就是這樣用,這就為什么叫總項目和子項目的原因,因為 總項目中可以包含多個子項目的。



來看看點擊后的效果。







這里只有一個子項目,只點 build target 就行。

1.026.jpg



1.027.jpg




從上圖可以看到,build 完后,我們看到是 0 error (0 錯誤),0 warning

(0 警告)。




如果我們把 P1=0xff;,后面這個“;”分號去掉,看看是怎么樣。



1.028.jpg






很明顯,它出來了一句,syntax error near (}
語法錯誤在花括號附近),



target not created(目標(biāo)沒創(chuàng)建)。








雙擊 syntax error near }這條語句時,光標(biāo)就會出來在附近,讓你改錯。




1.029.jpg


現(xiàn)在我們把分號加上后,它編譯沒有錯誤,證明程序可以運用,但是

軟件還沒有輸出單片機運行需要的代碼。

1.030.jpg










第三步:輸出單片機運行需要的代碼

鼠標(biāo)右擊“target”點“options for target ‘target 1’”(選項對于目標(biāo) 1)



1.031.jpg








點第三列的 output “輸出”按鈕,然后把 create hex file“創(chuàng)建 16 進(jìn)

制文件”勾上后,點確定。



1.032.jpg




再點 built target

1.033.jpg




這樣在編譯沒有錯誤成功后,它就會產(chǎn)生一個 hex 文件(單片機需要 的代碼),我們就可以用這個 hex 文件讓我們的單片機工作啦!






它在什么位置?就在我們新建的“點亮一只燈”的文件夾里面。


1.034.jpg

需要用的時候,我們需要到這個文件夾找出來,這樣我們 P1.0 口的 發(fā)光二極管就可以點亮了。


1.035.jpg


查找方法:

如果你是用仿真軟件。 先雙擊 89C52

1.036.jpg







再點擊 program file 到點亮一盞燈文件夾里面,把點亮一只燈.hex 文 件,找出來就行。(如下圖)



1.037.jpg




找出來后,再點右上角的 OK 就可以了。




你可以復(fù)制下面程序去編程軟件,熟悉上面的功能,如果想要靠自己 記憶去寫,也可以嘗試一下。


#include

main()

{ P1=0xff;

}




程序講解:


#include     包含這個頭文件,頭文件上面我們講解,就是為

單片機里面的地址命名字,方便我們直接用名字使用(每個程序的開 頭肯定有頭文件的)





main()

{

}

Main()這個是主函數(shù)入口,程序在花括號{ }里面執(zhí)行,之于 main 旁邊 的括號是什么東西,我們以后用到再講解,現(xiàn)在明白它是固定格式 main(),mian 括號就行。





P1=0xfe;

P1=1111 1110,把 P1.0 位置低電平,點亮 D8 發(fā)光二極管。




需要注意的是,這里的 P1 不可隨意寫,P 是大寫,若寫成 p,編譯程 序時將報錯,因為編譯器并不認(rèn)識 p1,它只認(rèn)識 P1,這是因為我們 在頭文件中定義的是“sfr P1= 0x90;”。

P1=0xfe 后面的分號“;”也不要漏掉,不然程序會報錯, 這些也是大多初學(xué)者編寫第一個程序時常犯的錯誤,希望大家留意一
下。

















注釋問題。




知識點:C 語言中注釋的寫法

在 C 語言中,注釋有兩種寫法:

(1)// 兩個斜扛后面跟著的為注釋語句。這種寫法只能注釋一行, 當(dāng)換行時,又必須在新行上重新寫兩個斜扛。


(2)/*…*/ 斜扛與星號結(jié)合使用,這種寫法可以注釋任意行,即斜 扛星號與星號斜扛之間的所有文字都作為注釋。





下圖是第二種。



1.038.jpg







所有注釋都不參與程序編譯,編譯器在編譯過程會自動刪去注釋,注

釋的目的是為了我們讀程序方便,一般在編寫較大的程序時,分段加 入注釋,這樣當(dāng)我們回過頭來再次讀程序時,因為有了注釋,其代碼 的意義便一目了然了。若無注釋,我們不得不特別費力地將程序 重新閱讀一遍方可知道代碼含義。養(yǎng)成良好的書寫代碼格式的習(xí)慣, 經(jīng)常為自己編寫的代碼加入注釋,以后定能方便許多。



練習(xí):

把 P1.1~P1.7 口逐個點亮。

把 P1.0~P1.3 點亮,其它四個不亮。













while語句 通過上面一節(jié)的學(xué)習(xí),想必大家已經(jīng)對點亮實驗板上的任意發(fā)光二極 管非常熟悉了,但是,先不要高興得太早,上面的程序并不完善,任 何一個程序都要有頭有尾才對,而上面我們寫的程序似乎只有頭而無 尾。我們分析一下看,當(dāng)程序運行時,首先進(jìn)入主函數(shù),順序執(zhí)行里 面的所有語句,因為主函數(shù)中只有一條語句,當(dāng)執(zhí)行完這條語句后,

該執(zhí)行什么了?




因為我們沒有給單片機明確指示下一步該做什么,所以單片機在運行 時就很有可能會出錯。




根據(jù)經(jīng)驗,當(dāng) Keil 編譯器遇到這種情況時,它會自動從主函數(shù)開始處 重新執(zhí)行語句,所以單片機在運行上面兩個程序時,實際上是在不斷 地重復(fù)點亮發(fā)光二極管的操作,而我們的意圖是讓單片機點亮二極管 后就結(jié)束,也就是讓程序停止在某處,這樣一個有頭有尾的程序才完



整。



那么如何讓程序停止在某處呢?我們用 while 語句就可以實現(xiàn)。 知識點:while()語句的應(yīng)用

格式:

while(表達(dá)式)

{

內(nèi)部語句(內(nèi)部可為空)


}

特點:先判斷表達(dá)式是真還是假,再執(zhí)行或者不執(zhí)行內(nèi)部語句。 在 C 語言的判斷條件中,1 或以上為真,0 為假。 判斷原則:若表達(dá)式不是 0,即不是 while(0)這樣的形式。這樣說就

是 while(1),while(2),while(3 或以上),即為真,那么執(zhí)行 while 花括 號的內(nèi)部語句,如果是 while(0)即為假,跳過while,不執(zhí)行 while 花 括號的內(nèi)部語句。



while 有兩種形式:

1 如果語句只有一條。 直接用表達(dá)式+執(zhí)行語句+分號結(jié)束就行。 如:


While(1)              表達(dá)式。

P1=0xfe;              執(zhí)行語句+分號。




While(1)是表達(dá)式,用來判斷是真是假。 因為這里是真,所以語句就無限循環(huán)于 P1=0xfe,后面再加上一個分 號表示這是一條結(jié)束。





1.039.jpg










2 如果有兩條以上表達(dá)式。 如:


While(1) P1=0xfe; P1=0xfa;






它也只是無限循環(huán)于 P1=0xfe 這條語句,而不往下執(zhí)行 P1=0xfa,這

樣的程序格式顯然是滿足不了多少功能,沒有什么意義的,那我們要 怎么寫才能讓 while 執(zhí)行多些語句呢?




從上面可以觀察到,我們還有花括號可用。 是的,


while(1)

{

}




“While(1)+花括號”就可以實現(xiàn)我們想要的功能。





While(1)

{ P1=0xfe; P1=0xfa;

}




這樣就可以執(zhí)行完 P1=0xfe,又繼續(xù)執(zhí)行 P1=0xfa,如果后面還有語句

就會接著一條條繼續(xù)執(zhí)行,直到 } 的這個結(jié)尾,繼續(xù)又重新開始到

{ 這個開始繼續(xù)執(zhí)行,無限循環(huán)。





1.040.jpg







現(xiàn)在我們可以了解到,while 有無限循環(huán)執(zhí)行它內(nèi)部語句的用法,如

果只有一條語句,直接在這條語句加分號就行,如果有兩條語句或以 上就需要加{}花括號。







如果 while(0) P1=0xfe; P1=0xfa;




因為現(xiàn)在 while 為假,所以它不會執(zhí)行 P1=0xfe,而往下執(zhí)行 P1=0xfa, 因為 P1=0xfa;是不屬于 while 的內(nèi)部語句。



花括號原理也是一樣。


while(0)

{ P1=0xfe; P1=0xfa;

} P1=0x0f;




不執(zhí)行 while 花括號里面的語句,執(zhí)行 P1=0x0f;










通過這些認(rèn)識 我們來編寫一個完整的點亮第一個發(fā)光二極管的程序。

#include               //52 系列單片機頭文件

void main()              //主函數(shù)

(

P1=0xfe;

while(1);

)




這里的 main 前面多了一個 void,void 有空的意思,在 main 前面加上


void 這個東西,實際意義并不大,只是讓程序具體點,你直接用 main()

也可以。




然后到 P1=0xfe,再停止在 while(1);這里,while 里面,如果有一條語 句就執(zhí)行完這個語句,停止到分號,如果沒有語句就直接在分號這里 無限循環(huán),相當(dāng)于停止標(biāo)記,所以以后一看到 while(1);,就知道是停 止標(biāo)記了。











知識點:for語句 格式:


for(表達(dá)式 1;表達(dá)式 2;表達(dá)式 3)

{

內(nèi)部語句


}




例子:


for(i=0;i<3;i++)

{ P1=0xfe;

}





語句解說:

1.041.jpg







執(zhí)行過程:

1.042.jpg








上圖文字說明:

1 判斷:判斷 i 是否少于 3。

2 執(zhí)行:執(zhí)行 for 內(nèi)部語句。

3              i++:i 自加 1。







從上面圖片可以看到 第一輪:

第 1 步:初始化 i=0(i 賦值等于 0)。 第 2 步:判斷 i 是否少于 3。

第 3 步:現(xiàn)在 i=0 是少于 3,就執(zhí)行 for 花括號的內(nèi)部語句一次。

第 4 步:當(dāng)執(zhí)行完一次內(nèi)部語句后,i++(i++的意思就是 i 自己加 1)。




第二輪:

第 5 步:因為上面 i 從 0 加了一次,現(xiàn)在 i=1。 第 6 步:判斷 i 是否少于 3。

第 7 步:現(xiàn)在 i=1 是少于 3,就執(zhí)行 for 花括號的內(nèi)部語句一次。

第 8 步:當(dāng)執(zhí)行完一次內(nèi)部語句后,i++(i++的意思就是 i 自己加 1)。


第三輪:

第 9 步:因為上面 i 從 1 加了一次,現(xiàn)在 i=2。 第 10 步:判斷 i 是否少于 3。

第 11 步:現(xiàn)在 i=1 是少于 3,就執(zhí)行 for 花括號的內(nèi)部語句一次。 第 12 步:當(dāng)執(zhí)行完一次內(nèi)部語句后,i++(i++的意思就是 i 自己加 1)。




第四輪:

第 13 步:因為上面 i 從 2 加了一次,現(xiàn)在 i=3。 第 14 步:判斷 i 是否少于 3。

第 15 步:現(xiàn)在 i=3 不少于 3,就不執(zhí)行 for 內(nèi)部語句了,退出 for 語 句繼續(xù)往下面執(zhí)行。





1.043.jpg


要點:

1 當(dāng) for 初始化完一次后,就沒有它的事了。

2 因為 i 初始化是 0,從第 0 次開始執(zhí)行,就算 i<3 也是執(zhí)行 3 次(第

0 次,第 1 次,第 2 次,共三次)

3              i++是 i 自加 1 的意思。













如果上面的理解。 那么


for(i=3;i>0;i--)

{ P1=0xfe;

}

也是一樣的原理,這里是 i 首先等于 3,如果 i>0,就執(zhí)行內(nèi)部語句, 然后 i--,這里是 i 自減 1 次。這個也是共執(zhí)行 3 次,執(zhí)行完后就退出 for 語句







通過以上步驟,這個 for 語句就執(zhí)行完了,單片機在執(zhí)行這個 for

語句的時候是需要時間的,上面 i 的初值較小,所以執(zhí)行的步數(shù)就少,


當(dāng)我們給 i 賦的初值越大,它執(zhí)行所需的時間就越長,因此我們就可

以利用單片機執(zhí)行這個 for 語句的時間來作為一個簡單延時語句。







很多初學(xué)者容易犯的錯誤是,想用 for 語句寫一個延時比較長的語句, 那么他可能會這樣寫:





unsigned char i;(unsigned char 無符號字符型,這是是定義 i 為無 符號字符型,數(shù)值范圍是 0~255)








for(i=0;i<3000;i--)

{

;

}




但是結(jié)果卻發(fā)現(xiàn)這樣寫并不能達(dá)到延長時間的效果,因為在這里 i 是 一個字符型變量,它的最大值為 255,當(dāng)你給它賦一個比最大值都大 的數(shù)時,這里 i 賦值是 3000,程序自然就出錯誤了。




因此我們尤其要注意,每次給變量賦初值時,都要首先考慮變量類型, 然后根據(jù)變量類型賦一個合理的值,我們所指的變量類型,就是字符



型(8 位),和整型(16 位),等,而且這兩個在 51 單片機最常用,

理解這兩個,其它的都已收入囊中。




如果我們想用 for 語句做一個秒的延時,我們該怎么寫呢? 秒是我們?nèi)粘S玫臅r間單位,如果單片機也用秒的時間來一句句執(zhí)行 程序語句,這樣就非常沒有效率,還不如直接用人手操作,我們創(chuàng)造 出單片機代替人手的根本原因,就是讓它自動化,而且快速。





那單片機到底有多快?

我們用 s(秒),單片機用的時間是 us(微秒) 而且


1s=1000ms=1000000us

1 秒=1000 毫秒=1 百萬微秒。 很明顯,單片機用的時間是我們的時間的 1 百萬倍。


如果我們知道單片機執(zhí)行一條語句需要多少時間,就可以用 for 語句 編寫出一個一秒的延時程序了。





我們來看看執(zhí)行一個分號需要多少時間。因為晶振是決定時間的,我 們單片機常用的是 11.0592M,想計算準(zhǔn)確的時間,先在軟件里面設(shè) 置一下。



1.044.jpg

右擊 target,點 option for target ,點 target,在 xtal 窗口輸入“11.0592”,

后點確定。







然后通過 keil 軟件——start/stop debug 可以監(jiān)測到程序執(zhí)行流程,進(jìn) 入 debug(調(diào)試)后(看下圖),按鍵盤F10 或者 F11 一步步執(zhí)行, F10 是跨越式執(zhí)行,F(xiàn)11 是細(xì)節(jié)語句執(zhí)行,說的多不如動手試一試, 就會明白很多了。





1.045.jpg














來看看執(zhí)行分號之前的時間。

1.046.jpg




從上圖可以看到,執(zhí)行一個分號之前的時間是,0.00044162 s(左邊 的 sec 那里看到),0.00044162 s=0.00044162s*100 萬=441.62us(小數(shù) 點向右移六位就行)








執(zhí)行一次分號后的時間。



1.047.jpg




從 上 圖 可 以 看 到, 執(zhí) 行 完 一 次 分號 之 后 的 時 間 是: 0.00044596

s=445.96us







分號之前的時間=441.62us 分號之后的時間=445.96us 分號用的時間=445.96us - 441.62us=4.34us。 所以執(zhí)行一次分號的時間是 4.34 微秒。




從我們上面圖片程序可以看到。


For(j=0;j<230;j++)

{

;

}


為什么是執(zhí)行 230 次分號呢?

因為 230*4.34us(一次分號的時間)= 998.2us=0.9982ms 約等于 1ms,

(因為 1s=1000ms,1ms=1000us,牢記這個時間關(guān)系)




現(xiàn)在我們知道。


For(j=0;j<230;j++)

{

;

}




這個 for 語法是執(zhí)行了 1ms(1 毫秒)的時間,但是這還沒有達(dá)到我 們想要的 1S 的時間,或許有些朋友很聰明可以想出,把這個 1ms 執(zhí) 行多 1000 次不就是 1S 的時間了?




好家伙,現(xiàn)在動手。





for(i=0;i<1000;i++)

{

For(j=0;j<230;j++)

{

;

}


}




1.048.jpg




很明顯,C 語言是可以用于內(nèi)嵌語句執(zhí)行的,從上面圖片不難看到, 執(zhí)行完 230 次分號后(花 1ms),還要重復(fù)執(zhí)行 1000 次 1ms 就是 1s 了。



一盞燈的一秒亮與滅

目標(biāo):一盞燈的一秒亮與滅

1 電路流程圖:




2 元件特性 發(fā)光二極管的原理





正極這邊為高電平,負(fù)極為低電平,發(fā)光二極管就行,兩邊為高電平, 發(fā)光二極管就不亮。






3 程序流程的概括

1.049.jpg




從上面圖片可以看到,讓一只燈亮滅的原理還是比如容易的,首先是 點亮一只燈,然后一秒延時,再滅燈,再一秒延時,再回到點亮一只 燈這樣無限循環(huán)的重復(fù)。




來看看程序。

#include                     //頭文件

#define uchar unsigned char   //把 unsigned char 命名字為 uchar


#define uint unsigned int              //把 unsigned int 命名字為 uchar

uint i;              //整型 i 變量

uchar j;              //字符型 j 變量

sbit led=P1^0;              //把 P1 的第 0 個位命名字為 led







main()              //主函數(shù)入口

{




while(1)              //無限循環(huán)入口

{

led=0;              //點亮 P1.0




for(i=0;i<1000;i++)              //延時 1 秒

{

for(j=0;j<230;j++)

{

;

}

}


led=1;              滅燈




for(i=0;i<1000;i++)              延時一秒

{

for(j=0;j<230;j++)

{

;

}

}

}











}







看看這前面部分是什么東西

#include              //頭文件

#define uchar unsigned char              //把 unsigned char 命名字為 uchar

#define uint unsigned int              //把 unsigned int 命名字為 uchar uint i;              //整型 i 變量

uchar j;              //字符型 j 變量


sbit led=P1^0;                          //把 P1 的第 0 個位命名字為 led







#include              //頭文件 頭文件每個程序開頭肯定有的。





#define 也很好理解的,也是作命名字用,因為當(dāng)引入頭文件 reg52

后,單片機也只是知道什么是 unsigned char,unsigned int 等。




而我們覺得太長不好寫,就有了#define uchar unsigned char ,把 unsigned char(無符號字符型)命名字為uchar,#define uint unsigned int 也是同樣的道理,uint(無符號整型)




1.050.jpg




還記得我們上面學(xué)過的 8 位,16 位嗎?8 個位的二進(jìn)制最大的數(shù)是十 進(jìn)制 255,當(dāng)超過 255 后,它就又會回歸到 0重新開始,而我們的 uchar 就是用于表明是 8 個位的水杯(最大十進(jìn)制數(shù)是 255)。



而 uint 是 16 位的水杯,最大的十進(jìn)制數(shù)可以表達(dá)到 65535,6 萬多。




那么現(xiàn)在 uint i,和 uchar j 現(xiàn)在明白了麼?

uint i,聲明一個 16 位的變量 i,方便程序內(nèi)用。I 的數(shù)值范圍在 0~65535

內(nèi)都可以。

uchar j,聲明一個 8 位的變量 j,方便程序內(nèi)用。J 的數(shù)值范圍在 0~255

內(nèi)都可以。




聲明完后,I, j 這些變量位置哪里來?當(dāng)你定義好,單片機 RAM(動 態(tài)存儲器)自動分配的,這不用你操心。


從上面程序你可以看到 I, j 在哪里用嗎? 延時程序
for(i=0;i<1000;i++)              延時一秒

{

for(j=0;j<230;j++)              延時 1 毫秒

{

;

}

}


很明顯,j 少于 255,所以用 uchar 就行,i>255<6 萬用 uint




sbit led=P1^0;              也很好理解的,聲名特殊功能寄存器的位,把 P1.0 這 個位命名字為 led,現(xiàn)在看到^這個符號了吧?很常用。




命名字方式,我們學(xué)過四種。 特殊功能寄存器的位命名:sbit 特殊功能寄存器 8 位地址命名:sfr P1=0x90;

特殊功能寄存器 16 位地址命名:sfr16 TC=0x91;(連續(xù)用 0x91,0x92 這兩個地址,只聲名第一個地址就可以)Define:把什么名字命什么名字(多數(shù)用于英文字母的定義,方便我 們記憶運用)





再看看我們程序編寫時常用的四種(牢記)。

1 特殊功能寄存器位命名:sbit

2 Define:把什么名字命什么名字(多數(shù)用于英文字母的定義,方便 我們記憶運用)


3 Uchar 字符型。

4 Uint 整型。




如何區(qū)分特殊功能寄存器和普通寄存器?原理很簡單的,當(dāng)你這個寄 存器是特殊功能的,比如 P1(廠家告訴你這個寄存器有什么用,就



是特殊功能),如果定義它的位來運用,就用 sbit(特殊功能寄存器

位命名)。




如果廠家沒有告訴你這個寄存器具體有什么用,就是普通寄存器,比 如 uchar i, uint j,等等,當(dāng)你聲明好后,單片機會自動分配寄存器的, 如果你想用普通的位,直接用 bit 就行,如 bit flag,為 flag 這個名字 定義為位功能,這個時候 flag 也是只能在 0~1,這兩個數(shù)內(nèi)變化,現(xiàn) 在稍微了解就行,以后用就的時候你就明白了。








再來看看程序,和我們的流程圖是一模一樣。



1.051.jpg







從上面圖片我們發(fā)現(xiàn),延時程序是一模一樣的,那我們有沒有方法把

同樣的代碼放在別處,需要的時候才調(diào)用出來,這樣就可以減少很多 代碼重寫,不用浪費那么多單片機內(nèi)部資源。




有兩種方式: 第一種是在主程序(main)上面書寫。 第二種是在主程序(main)下面書寫。






來看看第一種,在主程序上面書寫。

1.052.jpg




從上面圖片可以看到,當(dāng)定義好頭文件后和其它相應(yīng)的名字后,子程 序就可以開始書寫了。












延時子程序講解

void del_ms(uint k)                            // 延時子程序

{

for(i=0;i<k;i++)[ size][="" align]
{

for(j=0;j<230;j++)

{

;

}

}

}




Void 是空的意思,相當(dāng)于從這個子程序中,沒有東西(數(shù)值)返回的 意思吧,現(xiàn)在不理解,你可以暫時忽略它,直接書寫就行,以后你見 到有東西(數(shù)值)返回的,對比一下,就一目了然了。

del_ms(uint k)

del_ms 是子程序名字, del 是我們把英文單詞 delay(延時)的縮寫, 加_符號,再加 ms(毫秒),這樣從字面上就可以直接理解到是延時 1


毫秒的子程序,其實這個子程序名字你可以自己定義的,以后慢慢你

就懂。

叫做 ms 的原因是現(xiàn)在我們沒有像上面那樣直接賦值 1000 次的一毫 秒延時,而是把這個 1000 變成可變的數(shù)字,如下圖所示的 uint k:


1.053.jpg

可以看到,現(xiàn)在我們上面的 1000 改變成可變的變量整型 k,uint(無符 號整型)可在 0~65535 之間隨意賦值,定義完后,k 就可以在 0~65535 隨意賦值。


如果是少于 255 的話,用無符號字符型(uchar)就行,這里大于 255, 就用了整型,而且這個 k,只能在延時子程序花括號范圍內(nèi)使用,就 是


del_ms(uint k)

{

K 在這里隨意使用,在這范圍外使用是無效的。


}


你在主程序(main)內(nèi)定義,就是主程序(main)花括號內(nèi)可以使用,其 它范圍無效,如果你是一開頭就定義了,子程序和主程序都可以使用。


就是下面的 uint i 和 ichar j 可以在子程序和主程序的花括號里隨意使 用,理解沒?





1.054.jpg

回歸正傳。


1.055.jpg




del_ms 這名字在英文或符號之間(不是中文就行,因為這軟件不懂

中文),你可以隨你懂的命名字,比如你不太懂英文,直接寫 yan_shi

也行,只要做到一看這名字就知道是什么樣的子程序就行。

延時子程序調(diào)用方法,在主程序內(nèi)調(diào)用。


1.056.jpg

del_ms(多少數(shù)字你定義);

記得后面不要漏了分號,這樣做只要是告訴軟件,你已經(jīng)寫完一條語 句,不然的話,程序會出錯。


第二種:子程序在主程序下面寫。

1.057.jpg

這種方式除了位置不同和加多一句“告訴單片機主程序”下面有子程

序外,其它一樣,如果你在主程序下面寫子程序而沒有首先告訴單片 機,程序編譯中會出錯的,你可以自己試試,試過就知道了。



詳細(xì)請打開編程軟件和仿真軟件瀏覽效果。

本實驗配套的的仿真工程文件和源碼下載地址:http://www.zg4o1577.cn/bbs/dpj-85401-1.html


回復(fù)

使用道具 舉報

ID:185367 發(fā)表于 2017-5-21 17:56 | 顯示全部樓層
很詳細(xì)的帖子,適合初學(xué)者。
回復(fù)

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機教程網(wǎng)

快速回復(fù) 返回頂部 返回列表
主站蜘蛛池模板: 成人高潮片免费视频欧美 | 夜夜骑天天干 | 天堂资源| 日韩视频一区 | 欧美国产日韩一区二区三区 | 国产亚洲一区二区三区 | 成人在线免费视频 | 国产99久久久国产精品下药 | aaaa网站| 国产精品久久久久久吹潮 | 欧美激情欧美激情在线五月 | 成人a视频在线观看 | 天天天天天操 | 成人不卡在线 | 国产一区电影 | 中文字幕视频在线观看 | 日韩亚洲视频 | 国产黄色av网站 | 香蕉国产在线视频 | 欧美一区二区三区精品 | 久久久久久久国产 | 中文字幕国产视频 | 日韩中出 | 网页av| a级免费视频| 秋霞av国产精品一区 | 毛片在线视频 | 欧美激情精品久久久久久变态 | 九九亚洲精品 | 欧美激情视频一区二区三区在线播放 | 精品日韩在线 | 午夜视频一区二区 | 午夜三区 | 国产黄色在线观看 | 中文字幕在线视频精品 | 91高清视频在线观看 | 久久中文字幕一区 | 国产二区在线播放 | 国产精品久久久爽爽爽麻豆色哟哟 | 中文字幕欧美日韩一区 | 日韩色图视频 |