欧美极品高清xxxxhd,国产日产欧美最新,无码AV国产东京热AV无码,国产精品人与动性XXX,国产传媒亚洲综合一区二区,四库影院永久国产精品,毛片免费免费高清视频,福利所导航夜趣136

 找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開始

搜索
查看: 26301|回復(fù): 1
打印 上一主題 下一主題
收起左側(cè)

單片機(jī)點(diǎn)亮第一盞燈實(shí)驗(yàn)詳細(xì)教程

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
第一個(gè)實(shí)驗(yàn):keil軟件使用與點(diǎn)亮人生的第一只發(fā)光二極管

本實(shí)驗(yàn)教程的 pdf完整版下載及配套的的仿真工程文件和源碼下載地址:http://www.raoushi.com/bbs/dpj-85401-1.html




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


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

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

1 電路走線如下:




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



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


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

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


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




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



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



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



prouect(新項(xiàng)目)來新建項(xiàng)目。



點(diǎn)擊完 new project 后,會(huì)有如下對(duì)話框。


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

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





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












CPU 選擇是找到 Atmel 并點(diǎn)擊其它+號(hào)。













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






選擇后,點(diǎn)確定按鈕。












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



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

為總項(xiàng)目“添加子項(xiàng)目”。




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










第二步:為總項(xiàng)目添加子項(xiàng)目




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












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





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






#include Main()

{ P1=0xfe;

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



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

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










操作方法是:先保存,然后再把這個(gè)子項(xiàng)目添加到總項(xiàng)目去。







先保存。

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







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
















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

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












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










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










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

加文件到組,根源組 1)









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

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








Source group1 下有了“點(diǎn)亮一只燈”的 C 語言程序




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





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

要做的是,讓軟件查錯(cuò),那要如何做呢? 如下圖所示。






































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



來看看點(diǎn)擊后的效果。







這里只有一個(gè)子項(xiàng)目,只點(diǎn) build target 就行。








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

(0 警告)。




如果我們把 P1=0xff;,后面這個(gè)“;”分號(hào)去掉,看看是怎么樣。









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



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








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






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

軟件還沒有輸出單片機(jī)運(yùn)行需要的代碼。











第三步:輸出單片機(jī)運(yùn)行需要的代碼

鼠標(biāo)右擊“target”點(diǎn)“options for target ‘target 1’”(選項(xiàng)對(duì)于目標(biāo) 1)











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

制文件”勾上后,點(diǎn)確定。







再點(diǎn) built target





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






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



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




查找方法:

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








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







找出來后,再點(diǎn)右上角的 OK 就可以了。




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


#include

main()

{ P1=0xff;

}




程序講解:


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

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





main()

{

}

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





P1=0xfe;

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




需要注意的是,這里的 P1 不可隨意寫,P 是大寫,若寫成 p,編譯程 序時(shí)將報(bào)錯(cuò),因?yàn)榫幾g器并不認(rèn)識(shí) p1,它只認(rèn)識(shí) P1,這是因?yàn)槲覀?在頭文件中定義的是“sfr P1= 0x90;”。

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

















注釋問題。




知識(shí)點(diǎn):C 語言中注釋的寫法

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

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


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





下圖是第二種。










所有注釋都不參與程序編譯,編譯器在編譯過程會(huì)自動(dòng)刪去注釋,注

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



練習(xí):

把 P1.1~P1.7 口逐個(gè)點(diǎn)亮。

把 P1.0~P1.3 點(diǎn)亮,其它四個(gè)不亮。













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

該執(zhí)行什么了?




因?yàn)槲覀儧]有給單片機(jī)明確指示下一步該做什么,所以單片機(jī)在運(yùn)行 時(shí)就很有可能會(huì)出錯(cuò)。




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



整。



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

格式:

while(表達(dá)式)

{

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


}

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

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



while 有兩種形式:

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


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

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




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















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


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






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

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




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


while(1)

{

}




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





While(1)

{ P1=0xfe; P1=0xfa;

}




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

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

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












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

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







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




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



花括號(hào)原理也是一樣。


while(0)

{ P1=0xfe; P1=0xfa;

} P1=0x0f;




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










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

#include               //52 系列單片機(jī)頭文件

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

(

P1=0xfe;

while(1);

)




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


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

也可以。




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











知識(shí)點(diǎn):for語句 格式:


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

{

內(nèi)部語句


}




例子:


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

{ P1=0xfe;

}





語句解說:








執(zhí)行過程:









上圖文字說明:

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 花括號(hào)的內(nèi)部語句一次。

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




第二輪:

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

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

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


第三輪:

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

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




第四輪:

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

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







要點(diǎn):

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

2 因?yàn)?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 次。這個(gè)也是共執(zhí)行 3 次,執(zhí)行完后就退出 for 語句







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

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


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

以利用單片機(jī)執(zhí)行這個(gè) for 語句的時(shí)間來作為一個(gè)簡(jiǎn)單延時(shí)語句。







很多初學(xué)者容易犯的錯(cuò)誤是,想用 for 語句寫一個(gè)延時(shí)比較長(zhǎng)的語句, 那么他可能會(huì)這樣寫:





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








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

{

;

}




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




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



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

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




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





那單片機(jī)到底有多快?

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


1s=1000ms=1000000us

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


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





我們來看看執(zhí)行一個(gè)分號(hào)需要多少時(shí)間。因?yàn)榫д袷菦Q定時(shí)間的,我 們單片機(jī)常用的是 11.0592M,想計(jì)算準(zhǔn)確的時(shí)間,先在軟件里面設(shè) 置一下。




右擊 target,點(diǎn) option for target ,點(diǎn) target,在 xtal 窗口輸入“11.0592”,

后點(diǎn)確定。







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



















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





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








執(zhí)行一次分號(hào)后的時(shí)間。







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

s=445.96us







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




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


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

{

;

}


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

因?yàn)?230*4.34us(一次分號(hào)的時(shí)間)= 998.2us=0.9982ms 約等于 1ms,

(因?yàn)?1s=1000ms,1ms=1000us,牢記這個(gè)時(shí)間關(guān)系)




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


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

{

;

}




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




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





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

{

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

{

;

}


}








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



一盞燈的一秒亮與滅

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

1 電路流程圖:




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





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






3 程序流程的概括





從上面圖片可以看到,讓一只燈亮滅的原理還是比如容易的,首先是 點(diǎn)亮一只燈,然后一秒延時(shí),再滅燈,再一秒延時(shí),再回到點(diǎn)亮一只 燈這樣無限循環(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 個(gè)位命名字為 led







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

{




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

{

led=0;              //點(diǎn)亮 P1.0




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

{

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

{

;

}

}


led=1;              滅燈




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

{

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 個(gè)位命名字為 led







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





#define 也很好理解的,也是作命名字用,因?yàn)楫?dāng)引入頭文件 reg52

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




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








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



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




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

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

內(nèi)都可以。

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

內(nèi)都可以。




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


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

{

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

{

;

}

}


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




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




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

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





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

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

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


3 Uchar 字符型。

4 Uint 整型。




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



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

位命名)。




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








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










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

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




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






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





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












延時(shí)子程序講解

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

{

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

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

{

;

}

}

}




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

del_ms(uint k)

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


毫秒的子程序,其實(shí)這個(gè)子程序名字你可以自己定義的,以后慢慢你

就懂。

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



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


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


del_ms(uint k)

{

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


}


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


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






回歸正傳。






del_ms 這名字在英文或符號(hào)之間(不是中文就行,因?yàn)檫@軟件不懂

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

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

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



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

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


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


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

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



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

本實(shí)驗(yàn)配套的的仿真工程文件和源碼下載地址:http://www.raoushi.com/bbs/dpj-85401-1.html


分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏2 分享淘帖 頂 踩

相關(guān)帖子

回復(fù)

使用道具 舉報(bào)

沙發(fā)
ID:185367 發(fā)表于 2017-5-21 17:56 | 只看該作者
很詳細(xì)的帖子,適合初學(xué)者。
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

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

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

快速回復(fù) 返回頂部 返回列表