單片機(jī)小白學(xué)步(14) 點(diǎn)亮第一個(gè)LED的程序分析
之前我們寫的程序如下:
本文引用地址:http://m.butianyuan.cn/article/201611/318519.htm#include
sbit LED = P1^0;
void main()
{
LED = 0;
while(1);
}
頭文件
第一行包含頭文件,這個(gè)和C語言編寫HelloWorld時(shí)的#include 一樣。頭文件reg52.h中定義了單片機(jī)的一些寄存器,如P0~P3等。至于什么是寄存器,將在原理篇中具體介紹,現(xiàn)在我們只要把它想象成C語言中常說的內(nèi)存就好了。有興趣的讀者可以右擊reg52.h打開頭文件看一看。
C51的變量類型
這里我們使用的語言是C51,和標(biāo)準(zhǔn)C語言相比,最主要的特點(diǎn)就是多出來兩種變量類型:sfr和sbit。sfr和char一樣是一個(gè)8位數(shù)據(jù)類型,表示一個(gè)8位的寄存器。例如頭文件reg52.h中就有一句sfr P1 = 0x90,它定義了寄存器P1。由于P1是IO口寄存器,所以對(duì)P1賦值,則相應(yīng)的, IO口P1將輸出對(duì)應(yīng)的高低電平。而sbit則是一個(gè)1位數(shù)據(jù)類型,只有0和1兩種值,它對(duì)應(yīng)寄存器中的一個(gè)位。
于是在第二行里,我們定義了sbit型變量LED,并設(shè)置LED對(duì)應(yīng)P1的最低位bit0。此時(shí)變量LED就和IO口P1.0關(guān)聯(lián)起來。執(zhí)行賦值語句LED = 0,IO口P1.0就會(huì)輸出低電平,于是我們電路中的LED就會(huì)亮起來了。是不是非常神奇呢?在原理篇中,我會(huì)一步一步講解單片機(jī)是如何實(shí)現(xiàn)這種功能的。
位尋址
在其他的很多單片機(jī)中,我們只能讀寫整個(gè)P1寄存器,而不能直接定義類似sbit這種對(duì)應(yīng)寄存器一位的數(shù)據(jù)類型,另外51單片機(jī)里面有些寄存器也只能整個(gè)8位一起讀寫。這種直接讀寫一個(gè)寄存器位的特性被叫做位尋址功能。
又是一個(gè)很難理解的概念,同樣,還是需要了解原理篇才能很好的理解它,現(xiàn)在完全不用擔(dān)心,我提這個(gè)就是想讓初學(xué)者對(duì)此提前有個(gè)大體印象。畢竟很多知識(shí)都是慢慢積累的,如果把大量這樣的小知識(shí)全部放在原理篇中一并介紹,反而難以接受。
主函數(shù)的特點(diǎn):沒有參數(shù)和返回值
讀者應(yīng)該已經(jīng)看到了無參數(shù)且無返回值的void main()函數(shù),以及倒數(shù)第二行的while(1)語句,并可能疑惑不解。沒錯(cuò),主函數(shù)沒有參數(shù)也沒有返回值,倒數(shù)第二行的這句是一個(gè)死循環(huán),程序永遠(yuǎn)也不會(huì)退出。這和計(jì)算機(jī)上的程序有很大的不同。下面簡單的說明一下這樣做的原因何在,更深入的原因,則需要讀者看完原理篇后才能理解透徹。
在計(jì)算機(jī)中,我們開機(jī)時(shí)看到的啟動(dòng)界面是操作系統(tǒng),如Windows、Linux等,我們編寫的程序則是在操作系統(tǒng)的環(huán)境下運(yùn)行的。程序執(zhí)行時(shí),相當(dāng)于系統(tǒng)調(diào)用main函數(shù),所以系統(tǒng)可以向main函數(shù)傳遞參數(shù),也可以獲取main函數(shù)執(zhí)行結(jié)束時(shí)的返回值,程序執(zhí)行結(jié)束后,會(huì)重新回到操作系統(tǒng)環(huán)境下。而在這里,我們寫的程序是直接運(yùn)行在單片機(jī)上的,不依賴操作系統(tǒng)。我們程序中的main函數(shù)不會(huì)被操作系統(tǒng)調(diào)用,因此通常它不需要參數(shù),也不需要返回值。事實(shí)上,main函數(shù)有些情況下是被啟動(dòng)代碼調(diào)用的,而啟動(dòng)代碼是匯編語言寫的,還記得上一篇中提到的啟動(dòng)代碼么?
主函數(shù)的特點(diǎn):死循環(huán),不會(huì)執(zhí)行結(jié)束
在計(jì)算機(jī)中,我們寫的程序執(zhí)行結(jié)束會(huì)回到操作系統(tǒng)環(huán)境下。而在單片機(jī)中,一旦單片機(jī)上電復(fù)位,就會(huì)執(zhí)行我們寫的main函數(shù),直到斷電。而如果main函數(shù)執(zhí)行結(jié)束,將發(fā)生不可預(yù)知的結(jié)果。
實(shí)際實(shí)驗(yàn)時(shí),STC單片機(jī)會(huì)復(fù)位并重新開始執(zhí)行程序,或許只是個(gè)巧合,因?yàn)楣俜降男酒謨?cè)中并沒有明確說明這一點(diǎn)。本著嚴(yán)謹(jǐn)?shù)目茖W(xué)態(tài)度,我們不利用這種未經(jīng)官方確認(rèn)的特點(diǎn)來開發(fā)我們的程序。程序的可靠性是非常重要的,這一點(diǎn)要引起重視。
試想如果你用單片機(jī)開發(fā)的是醫(yī)療相關(guān)的產(chǎn)品,或者是控制一些大型機(jī)器等,一旦發(fā)生意外,后果難以想象。即使你開發(fā)的是普通的產(chǎn)品,如果總是出現(xiàn)奇怪的故障,也足以讓用戶抓狂。因此這一點(diǎn)要引起讀者注意。所以,單片機(jī)的程序是不應(yīng)該執(zhí)行結(jié)束的,因此最后必然是一個(gè)死循環(huán),這樣才能保證單片機(jī)系統(tǒng)的可靠性。
總結(jié)
于是我們總結(jié)出通常情況下51單片機(jī)程序的幾個(gè)特點(diǎn):
1、包含REG52.H,該文件中定義了P0-P3接口等信息(sfr型和sbit型)。
2、單片機(jī)主函數(shù)沒有參數(shù),沒有返回值(當(dāng)然寫成int型也不會(huì)報(bào)錯(cuò),但是沒必要)。
3、單片機(jī)主函數(shù)末尾會(huì)有個(gè)死循環(huán),不會(huì)退出。
=======================================================
評(píng)論