這節(jié)課的標(biāo)題是點(diǎn)亮LED,但是需要大家了解的單片機(jī)基礎(chǔ)知識(shí)的內(nèi)容也非常多,特別是對(duì)于初學(xué)者,剛開始要在頭腦中建立一個(gè)單片機(jī)的概念,課程最后通過點(diǎn)亮一個(gè)LED小燈來增加初學(xué)者對(duì)實(shí)驗(yàn)的好奇心和自信心。
1.1 單片機(jī)的內(nèi)部資源
在這里我所講到的單片機(jī)內(nèi)部資源,和傳統(tǒng)單片機(jī)書籍講單片機(jī)內(nèi)部結(jié)構(gòu)不同,我這里講到的內(nèi)部資源,是指我們作為單片機(jī)用戶,單片機(jī)提供給我們可使用的一些內(nèi)容。總結(jié)起來,主要是三大資源:
1、FLASH(程序存儲(chǔ)空間,早期單片機(jī)是OTPROM)
2、RAM(數(shù)據(jù)存儲(chǔ)空間)
3、SFR(特殊功能寄存器)
在早期的技術(shù)里邊,主要是用OTPROM(One Time Programable Read-Only Memory,即一次可編程只讀存儲(chǔ)器)來存儲(chǔ)單片機(jī)的程序,隨著技術(shù)的發(fā)展,FLASH的以其可重復(fù)擦寫且大容量低成本的優(yōu)點(diǎn)成為絕大多數(shù)單片機(jī)的程序存儲(chǔ)器。對(duì)于單片機(jī)來說FLASH最大的意義是斷電后數(shù)據(jù)不丟失,這個(gè)概念類似于我們電腦的硬盤,你看我們保存了電影、文檔、音樂等文件,我們把電源關(guān)掉后,下次重新開電腦,所有的文件都還照樣存在。
RAM是單片機(jī)的數(shù)據(jù)存儲(chǔ)空間,用來存儲(chǔ)程序運(yùn)行過程中產(chǎn)生的和需要的數(shù)據(jù),和我們電腦的內(nèi)存是一個(gè)概念,其實(shí)最典型的比喻是我們的計(jì)算器,我們用計(jì)算器計(jì)算個(gè)加減法,一些中間的數(shù)據(jù)都會(huì)保存在RAM里邊,關(guān)電后數(shù)據(jù)丟失,所以我們每次打開計(jì)算器,都是從歸零開始計(jì)算。但是他的優(yōu)點(diǎn)第一是讀寫速度非?欤诙抢碚撋鲜可無限次寫入的,即壽命無限,不管程序怎么運(yùn)行怎么讀寫它都不會(huì)壞的。
第三個(gè)資源是SFR,特殊功能寄存器。這個(gè)概念大家可能剛開始理解不了,但是一定要記住。單片機(jī)有很多很多功能,每個(gè)功能都會(huì)配一個(gè)或多個(gè)SFR,我們就是通過對(duì)SFR的讀寫來實(shí)現(xiàn)單片機(jī)的多種多樣的功能的。
講到這里,我們來了解一下51單片機(jī)。通常我們一說到51單片機(jī),指的都是兼容Intel MCS-51體系架構(gòu)的一系列單片機(jī)。全球有眾多的半導(dǎo)體廠商推出了無數(shù)款這一系列的單片機(jī),比如Atmel的AT89C52,NXP(Philips)的P89V51,宏晶科技的STC89C52,具體型號(hào)千差萬別,但他們的基本操作都是一樣的,程序開發(fā)環(huán)境也是一樣的。這里我們要分清楚51這個(gè)統(tǒng)稱和具體的單片機(jī)型號(hào)之間的關(guān)系。
單片機(jī)內(nèi)部資源的三個(gè)主要部分我們清楚了,那么我們選擇STC89C52RC這款單片機(jī)來進(jìn)行學(xué)習(xí)。STC89C52RC單片機(jī)是宏晶科技出品的一款51內(nèi)核的單片機(jī),具有標(biāo)準(zhǔn)的51體系結(jié)構(gòu),全部的51標(biāo)準(zhǔn)功能,程序下載方式簡(jiǎn)單,方便學(xué)習(xí),我們就用它來學(xué)習(xí)單片機(jī)。它的資源呢,Flash程序空間是8K字節(jié)(1K=1024字節(jié),1字節(jié)= 8位),RAM數(shù)據(jù)空間是512字節(jié),SFR我們后邊需要逐一提到并且應(yīng)用。
1.2 單片機(jī)最小系統(tǒng)
為什么稱之為單片機(jī)最小系統(tǒng)呢?單片機(jī)最小系統(tǒng),也叫做單片機(jī)最小應(yīng)用系統(tǒng),是指用最少的原件組成單片機(jī)可以工作的系統(tǒng)。單片機(jī)最小系統(tǒng)的三要素就是電源、晶振、復(fù)位電路,如圖2-1所示。

圖2-1 單片機(jī)最小系統(tǒng)電路
備注:本教材中的大部分電路圖示例都節(jié)選自我們的KST-51開發(fā)板原理圖,但也有部分電路圖示例與KST-51開發(fā)板無關(guān),而僅是用其來說明一些具體問題。讀者可自行對(duì)照KST-51開發(fā)板原理圖,以下不再做特殊說明。
1.2.1 電源
這個(gè)很好理解,電子設(shè)備都需要供電,就連我們的家用電器(手電筒^_^)也不例外。主流單片機(jī)的電源現(xiàn)在是5V和3.3V這兩個(gè)標(biāo)準(zhǔn),當(dāng)然現(xiàn)在還有對(duì)電壓要求更低的單片機(jī)系統(tǒng)。
我們所學(xué)的STC89C52RC,它需要5V的供電系統(tǒng),我們的開發(fā)板是使用USB口出來的5V直流電壓直接供電的。從圖2-1可以看到,供電電路在40腳和20腳的位置上,40腳接的是VCC,代表的是電源正極,20腳接的是GND,代表的是電源的負(fù)極。VCC和GND之間還有個(gè)電容,作用我們下節(jié)課介紹。
這個(gè)地方我們還要普及一個(gè)看原理圖的知識(shí)。電路原理圖是為了表達(dá)這個(gè)電路的工作原理而存在的,很多器件在繪制的時(shí)候更多考慮是方便分析原理,不是表達(dá)各個(gè)器件實(shí)際位置的。比如上邊的單片機(jī)引腳圖,引腳的位置我們是可以隨意放的,但是每個(gè)引腳上有一個(gè)引腳標(biāo)號(hào)(在表示芯片的方框的內(nèi)部),這個(gè)引腳標(biāo)號(hào)代表的才是單片機(jī)真正的引腳位置,如圖2-2所示。一般情況下,這種雙列直插的封裝的芯片,左上角是1腳,逆時(shí)針旋轉(zhuǎn)引腳號(hào)依次增加,一直到右上角是最大腳位,咱們現(xiàn)在選用的單片機(jī)一共40個(gè)引腳,因此右上角就是40。

圖2-2單片機(jī)封裝圖
1.2.2 晶振
晶振,又叫晶體振蕩器,從這個(gè)名字我們就可以看出來,它注定一生都要不停振動(dòng)的。他起到的作用是為單片機(jī)系統(tǒng)提供基準(zhǔn)時(shí)鐘信號(hào),類似于我們部隊(duì)訓(xùn)練時(shí)喊口令的人,單片機(jī)內(nèi)部所有的工作都是以這個(gè)時(shí)鐘信號(hào)為步調(diào)基準(zhǔn)來進(jìn)行工作的。STC89C52RC單片機(jī)的18腳和19腳是晶振的引腳,我們接了一個(gè)11.0592M的晶振(它每秒鐘震蕩11,059,200次),外加兩個(gè)20pF的電容,電容的作用是幫助晶振起振,并維持震蕩信號(hào)的穩(wěn)定。
1.2.3 復(fù)位電路
在圖2-1左側(cè)是一個(gè)復(fù)位電路,接到了單片機(jī)的9腳RST(Reset)復(fù)位引腳上,這個(gè)復(fù)位電路如何起到的作用我們后邊再講,現(xiàn)在著重講一下復(fù)位對(duì)單片機(jī)的作用。單片機(jī)復(fù)位一般是3種情況,上電復(fù)位、手動(dòng)復(fù)位、程序自動(dòng)復(fù)位。
我們假如我們的單片機(jī)程序有100行,當(dāng)某一次運(yùn)行到第50行的時(shí)候,突然停電了,這個(gè)時(shí)候單片機(jī)內(nèi)部有的區(qū)域數(shù)據(jù)會(huì)丟失掉,有的區(qū)域數(shù)據(jù)沒丟失,那么下次打開設(shè)備的時(shí)候,我們希望單片機(jī)能正常運(yùn)行。所以上電后,單片機(jī)要進(jìn)行一個(gè)內(nèi)部的初始化過程,這個(gè)過程就可以理解為上電復(fù)位,上電復(fù)位保證單片機(jī)每次都從一個(gè)固定的相同的狀態(tài)開始工作。這個(gè)過程跟我們打開電腦電源開電腦的過程是一致的。
當(dāng)我們的程序運(yùn)行,遭受到意外干擾而導(dǎo)致程序死機(jī),或者程序跑飛的時(shí)候,我們就可以按下一個(gè)復(fù)位按鍵,讓程序重新初始化重新運(yùn)行,這個(gè)過程就叫做手動(dòng)復(fù)位,最典型的就是我們電腦的重啟按鈕。
當(dāng)我們的程序死機(jī)或者跑飛的時(shí)候,我們的單片機(jī)往往有一套自動(dòng)復(fù)位機(jī)制,比如看門狗,具體應(yīng)用以后再了解。在這種情況下,如果程序長(zhǎng)時(shí)間失去響應(yīng),單片機(jī)看門狗模塊會(huì)自動(dòng)復(fù)位重啟單片機(jī)。還有一些情況是我們程序故意重啟復(fù)位單片機(jī)。
電源、晶振、復(fù)位構(gòu)成了單片機(jī)最小系統(tǒng)的三要素,也就是說,一個(gè)單片機(jī)具備了這三個(gè)條件,就可以運(yùn)行我們下載的程序了,其他的比如LED小燈、數(shù)碼管、液晶等設(shè)備都是屬于單片機(jī)的外設(shè),我們最終完成我們想要的功能就是通過對(duì)單片機(jī)編程來控制這些外設(shè)實(shí)現(xiàn)的。
1.3 LED小燈
LED小燈通常我們也叫做發(fā)光二極管,它的種類很多,參數(shù)也不盡相同,我們板子上用的是最普通的貼片發(fā)光二極管。這種二極管通常的正向?qū)?/span>電壓是1.8V到2.2V之間,工作電流一般在1mA~20mA之間。其中,當(dāng)電流在1mA~5mA之間變化時(shí),隨著通過發(fā)光二極管(LED)的電流越來越大,我們的肉眼會(huì)感覺到這個(gè)小燈越來越亮,當(dāng)電流從5mA~20mA之間變化時(shí),我們看到的發(fā)光二極管的亮度基本上沒有什么太大變化了。當(dāng)電流超過20mA時(shí),LED就會(huì)有燒壞的危險(xiǎn)了,電流越大,燒壞的也就越快。所以我們?cè)谑褂眠^程中應(yīng)該特別注意他在電流參數(shù)上的設(shè)計(jì)要求。
那么下面我們來看一下這個(gè)發(fā)光二極管在我們的開發(fā)板上的設(shè)計(jì)應(yīng)用。
圖2-3 USB接口電路
圖2-3是我們開發(fā)板上的USB接口電路,通過USB線,電腦給我們的開發(fā)板供電和下載程序以及實(shí)現(xiàn)電腦和開發(fā)板之間的通信。從圖上可以看出,USB座共有6個(gè)接口,其中2腳和3腳是數(shù)據(jù)通信引腳,1腳和4腳是電源引腳,1腳是VCC正電源,4腳是GND即地線。5腳和6腳是外殼,我們直接接到了GND上,大家可以觀察一下開發(fā)板上的這個(gè)USB口的座的6個(gè)引腳。
我們現(xiàn)在主要來看1腳VCC和4腳GND。1腳通過F1(自恢復(fù)保險(xiǎn)絲)接到右側(cè),在正常工作的情況下,保險(xiǎn)絲可以直接看成導(dǎo)線,因此左右兩邊都是USB電源+5V,自恢復(fù)保險(xiǎn)絲的作用是,當(dāng)你后級(jí)電路哪個(gè)地方有發(fā)生短路的時(shí)候,保險(xiǎn)絲會(huì)自動(dòng)切斷電路,保護(hù)我們的板子以及電腦的USB口,當(dāng)電路正常后,保險(xiǎn)絲會(huì)恢復(fù)暢通,正常工作。
右側(cè)有2條支路,第一條是在+5V和GND接了一個(gè)470uF的電容,電容是隔離直流的,所以這條支路是沒有電流的,電容的作用,我們下節(jié)課再介紹,這節(jié)課我們主要看第二條支路。我們把第二條支路摘取出來就是這個(gè)樣子了。
圖2-4 Led小燈電路(1)
發(fā)光二極管是二極管中的一種,因此和普通二極管一樣,這個(gè)二極管有陰極和陽極,習(xí)慣上也稱之為正極和負(fù)極,這樣方便在電路上觀察,方向必須接對(duì)了才會(huì)有電流通過讓LED小燈發(fā)光。剛才我提到了我們接入的VCC電壓是5V,發(fā)光二極管自身壓降大概可認(rèn)為是2V,那么在右邊RES這個(gè)電阻上承受的電壓就是3V。那么現(xiàn)在我們要求電流范圍是1~20mA的話,就可以根據(jù)伏安特性,把這個(gè)電阻的上限和下限值求出來。
(VCC - 2)/I= R
當(dāng)電流是1mA的時(shí)候,電阻值是3K;當(dāng)電流是20mA的時(shí)候,電阻值是150歐,也就是RES的取值范圍是150~3000歐姆。這個(gè)電阻值大小的變化,直接可以限制整條通路的電流的大小,因此這個(gè)電阻我們通常稱之為“限流電阻”。在圖2-3中,我們用的電阻是1K,這條支路電流的大小,我想大家可以輕松計(jì)算出來了,而這個(gè)發(fā)光二極管在這里的作用,就是個(gè)電源指示燈,使用USB線將開發(fā)板和電腦連起來,這個(gè)燈就會(huì)亮了。
同理,我們?cè)诎遄雍蠹?jí)開關(guān)控制的地方,又添加了一個(gè)LED10發(fā)光二極管,作用就是當(dāng)我們打開開關(guān)時(shí),這個(gè)二極管才會(huì)亮起。
圖2-5 USB供電電路
大家注意,這里的開關(guān)雖然只有一個(gè),但是是2路的,2路開關(guān)并聯(lián)更能確保給后級(jí)提供更大的電流。電容C19和C10,都是隔離斷開直流的,作用我們下節(jié)課介紹,這里大家可以忽略。
那么下面呢,我們把圖2-4進(jìn)行一下變化,把右側(cè)的GND去掉,改成一個(gè)單片機(jī)的IO口,如圖2-6所示。
圖2-6 LED小燈電路(2)
圖2-4由于電源從正極到負(fù)極有電壓差,并且電路是導(dǎo)通的,所以就會(huì)有電流通過,LED小燈因?yàn)橛辛穗娏魍ㄟ^,所以就會(huì)直接發(fā)光。我們把右側(cè)的原GND處接到單片機(jī)P0.0引腳上,那么如果我們單片機(jī)輸出一個(gè)低電平,也就是跟GND一樣的0V電壓,就可以讓LED小燈和圖2-4一樣發(fā)光。
因?yàn)槲覀兊膯纹瑱C(jī)是可以編程控制的,我們可以讓P0.0這個(gè)引腳輸出一個(gè)高電平,就是跟VCC一樣的5V電壓,那么這個(gè)時(shí)候,左側(cè)VCC電壓和右側(cè)的P0.0的電壓是一致的,那就沒有電壓差,沒有電壓差就不會(huì)產(chǎn)生電流,沒有電流LED小燈就不會(huì)亮,也就是會(huì)處于熄滅狀態(tài)。下面,我們就用我們的編程軟件來實(shí)現(xiàn)控制小燈的亮和滅。
1.4 程序代碼編寫
這是我們第一個(gè)實(shí)驗(yàn)程序,因此大家還是得耐心點(diǎn),先來了解一下一些51單片機(jī)特有的程序語法以及Keil軟件的基本操作步驟。
1.4.1 特殊功能寄存器和位定義
我們主要是用C語言來對(duì)單片機(jī)編程,有的單片機(jī)也有那么幾條很特殊的獨(dú)有的編程語句,51單片機(jī)就有,先介紹2條。
第一條語句是: sfr P0 = 0x80;
SFR這個(gè)關(guān)鍵字,是51單片機(jī)特有的,他的作用是定義一個(gè)單片機(jī)特殊功能寄存器(special function register)。51單片機(jī)內(nèi)部有很多個(gè)小模塊,每個(gè)模塊有8個(gè)開關(guān)。每個(gè)模塊呢,都有一個(gè)房間和唯一的房間號(hào)。那么P0就是一個(gè)功能模塊,就住在了0x80這個(gè)房間里,我們就是通過設(shè)置P0的內(nèi)部這個(gè)模塊的8個(gè)開關(guān),來讓單片機(jī)的P0這8個(gè)IO口輸出高電平或者低電平的。
第二條語句是: sbit LED = P0^0;
這個(gè)sbit,就是對(duì)剛才所說的SFR里邊的8個(gè)開關(guān)其中的一個(gè)進(jìn)行定義。經(jīng)過上邊第二條語句后,以后只要在程序里寫LED,就代表了P0.0口(“^”這個(gè)符號(hào)在數(shù)字鍵6上邊),注意這個(gè)P必須大寫,也就是說我們給P0.0又取了一個(gè)更形象的名字叫做LED。
了解了這兩個(gè)語句后,我們來大概看一下單片機(jī)的特殊功能寄存器。注意,每個(gè)型號(hào)的單片機(jī)都會(huì)配有生產(chǎn)廠商所寫的數(shù)據(jù)手冊(cè)(Datasheet),所以我們來看一下STC89C52RC的數(shù)據(jù)手冊(cè),從21頁到24頁,全部是對(duì)特殊功能寄存器的介紹以及地址映射列表。我們?cè)谑褂眠@個(gè)寄存器之前,必須對(duì)這個(gè)寄存器的地址進(jìn)行說明。是不是花花綠綠的太多了,記不住啊,這個(gè)沒關(guān)系的,不需要你記住,了解一下,后邊大部分我會(huì)慢慢給大家解釋,少部分需要用到的時(shí)候,自己過來查手冊(cè)就可以了,做技術(shù)不是為了應(yīng)付考試,你可以隨時(shí)翻閱手冊(cè)查找你需要的資料。
繼續(xù)往下看,在22頁最下邊有一個(gè)表格

表2-1 IO口特殊功能寄存器
我們來看一下表2-1,其中P4口是擴(kuò)展出來的功能,我們暫時(shí)先不看,只看前邊的P0,P1,P2,P3這4個(gè),每個(gè)Px口本身又有8個(gè)控制端口。大家可以結(jié)合我們的開發(fā)板原理圖或者圖2-1來看,那么這樣就確定了我們的單片機(jī)一共有32個(gè)IO口(IO,Input和Output,分別是輸入和輸出)。
其中P0口所在的地址是0x80,一共有從7到0這8個(gè)IO口控制位,后邊有個(gè)Reset Value(復(fù)位值),這個(gè)很重要,我們看寄存器必看的一個(gè)參數(shù),8個(gè)控制位復(fù)位值全部都是1。這里也就告訴了我們,這個(gè)單片機(jī)上電復(fù)位的時(shí)候,所有的引腳的值默認(rèn)是高電平,我們?cè)谠O(shè)計(jì)電路的時(shí)候也要充分的考慮這個(gè)問題。
那么上邊那2條語句,我們寫sfr的時(shí)候,必須要根據(jù)手冊(cè)里的這個(gè)地址(add)去寫,sbit的時(shí)候,就可以直接將一個(gè)字節(jié)其中某一位取出來。我們編程的時(shí)候,也有現(xiàn)成的寫好寄存器地址的頭文件,我們直接包含該頭文件就可以了,不需要逐一去寫了。
1.4.2 新建一個(gè)工程
對(duì)于單片機(jī)程序來說,每個(gè)功能程序,都必須要有一個(gè)配套的工程文件(Project),即使是點(diǎn)亮LED這樣簡(jiǎn)單的功能程序也不例外,因此我們首先要新建一個(gè)工程,打開我們的Keil軟件后,點(diǎn)擊:Project-->New uVision Project...然后會(huì)出現(xiàn)一個(gè)新建工程的界面,如圖2-7所示。
圖2-7 新建一個(gè)工程
我們首先改一下路徑,改到了我們預(yù)先建立好的LED文件夾內(nèi),這樣方便我們今后管理我們的程序,不同的功能程序放到不同的文件夾下,并且給這個(gè)工程起一個(gè)名字叫做LED,軟件會(huì)自動(dòng)加擴(kuò)展名為.uvproj。
我們直接點(diǎn)保存就可以了,工程會(huì)自動(dòng)保存成LED.uvproj文件,下次你要打開LED這個(gè)工程,可以直接找到文件夾,雙擊這個(gè).uvproj文件就可以直接打開了。
圖2-8 保存工程
保存之后會(huì)彈出一個(gè)對(duì)話框,這個(gè)對(duì)話框讓我們選擇單片機(jī)型號(hào)。因?yàn)?font face="Times New Roman">Keil這軟件是外國人開發(fā)的,所以我們國內(nèi)的STC89C52RC沒有上榜,但是只要選擇同類型號(hào)就可一樣編程和應(yīng)用,因?yàn)?font face="Times New Roman">51內(nèi)核是Intel公司創(chuàng)始的,所以這里我們直接選擇Intel公司名下的80/87C52來代替,這個(gè)選項(xiàng)的選擇對(duì)于我們后邊的編程是沒有什么影響的,所以大家跟著我來選就可以了。
圖2-9 單片機(jī)型號(hào)選擇
點(diǎn)OK之后,會(huì)彈出一個(gè)對(duì)話框,如果2-10所示,這個(gè)地方會(huì)有部分啟動(dòng)代碼,如果點(diǎn)“否”編譯器會(huì)自動(dòng)處理這個(gè)問題,如果點(diǎn)“是”,這部分代碼會(huì)提供給我們用戶,我們用戶就可以自己去處理這部分代碼,那這部分代碼在我們初學(xué)51的這個(gè)時(shí)間段,我們一般是不需要去修改的,但是隨著技術(shù)的提高和知識(shí)的擴(kuò)展,我們有可能會(huì)了解這塊內(nèi)容,因此這個(gè)地方我們選一下“是”,讓這段代碼出現(xiàn),但是我們暫時(shí)不需要修改它,大家知道這么回事就可以了。
圖2-10 初始化文件選擇
這樣工程就建立好了,如圖2-11所示,如果我們點(diǎn)擊Target 1左邊的加號(hào),會(huì)出現(xiàn)我們剛才加入的初始化文件STARTUP.A51,這個(gè)我們先不管。
圖2-11 工程文件
工程有了之后,我們要建立編寫代碼的文件,點(diǎn)擊File-->New,新建一個(gè)文件,也就是我們編寫程序的平臺(tái)。然后點(diǎn)File-->Save或者直接點(diǎn)擊那個(gè)Save的快捷鍵,可以保存文件并且命名為LED.C,這個(gè)地方必須加上.C了,因?yàn)槿绻麑憛R編語言,這個(gè)地方的擴(kuò)展名是.ASM,頭文件就是.H等等,我們編寫的是C語言程序,這個(gè)地方必須自己添加文件的擴(kuò)展名.C,如圖2-13所示。
圖2-12新建文件

圖2-13 保存文件
現(xiàn)在我們就可以在我們建立好的文件中輸入我們編寫的程序了,在編寫之前還有個(gè)工作要做。我們每做一個(gè)功能程序,必須要新建一個(gè)工程,一個(gè)工程代表了單片機(jī)要實(shí)現(xiàn)的一個(gè)功能。但是一個(gè)工程,有時(shí)候我們可以把我們的程序分多個(gè)文件寫,所以每寫一個(gè)文件,我們都要添加到我們所建立的工程中去,鼠標(biāo)右鍵點(diǎn)Source Group 1,點(diǎn)Add Files to Group ‘Source Group 1’,
圖2-14 添加文件(一)
圖2-15 添加文件(二)
單擊LED.C然后點(diǎn)Add,或者雙擊LED.C都可以將文件加入到這個(gè)工程下,然后點(diǎn)Close,關(guān)閉添加。 這個(gè)時(shí)候大家會(huì)看到在Source Group 1下邊又多了一個(gè)LED.C文件。
1.4.3 編寫點(diǎn)亮小燈的程序
忙活了半天,準(zhǔn)備工作做了那么多,終于要編寫我們的代碼了。如果有學(xué)過C語言的話,你應(yīng)該很輕松的跟著我的編程自己寫出來,如果沒學(xué)過C語言也沒關(guān)系,你先照著我的抄,我會(huì)在合適的位置寫出來對(duì)C語言語法的一些解釋,這樣抄幾次后再看看解釋,就應(yīng)該很明確了。
#include <reg52.h> //包含特殊功能寄存器定義的頭文件
sbit LED = P0^0; //位地址聲明,注意:sbit必須小寫、P大寫!
void main() //任何一個(gè)C程序都是從main函數(shù)開始執(zhí)行的
{
LED = 0;
}
按照正常的邏輯,程序這樣寫就可以了,但是在實(shí)際單片機(jī)應(yīng)用中,存在一個(gè)問題。比如我們的程序空間可以寫100行代碼,但是我們程序只有50行代碼,當(dāng)運(yùn)行完了50行,再繼續(xù)運(yùn)行時(shí),第51行的程序不是我們想運(yùn)行的程序,而是不確定的未知內(nèi)容,所以我們通常要在程序中加一個(gè)死循環(huán),讓程序停留在我們希望的這個(gè)狀態(tài)下,不要亂運(yùn)行,有以下兩種寫法可以參考:
參考程序一: 參考程序二:
#include <reg52.h> #include <reg52.h>
sbit LED = P0^0; sbit LED = P0^0;
void main() void main()
{ {
while(1) LED = 0;
{ while(1);
LED = 0; }
}
}
這兩個(gè)程序都可以實(shí)現(xiàn)點(diǎn)亮LED小燈的功能,看起來第二種比較簡(jiǎn)潔一些。針對(duì)于圖2-6,我們這個(gè)程序能夠完全把小燈點(diǎn)亮,但是這個(gè)程序卻點(diǎn)不亮我們板子上的小燈,這是為什么呢?
這里我們大家就要培養(yǎng)一個(gè)意識(shí)了,我們做單片機(jī)編程,實(shí)際上算是硬件底層驅(qū)動(dòng)程序開發(fā),這種程序的開發(fā),是離不開電路圖的,必須根據(jù)我們的電路圖來進(jìn)行程序的編寫。如果我們?cè)O(shè)計(jì)電路板的電路圖和圖2-6一樣的話,我們那個(gè)程序可以成功點(diǎn)亮,但是如果不一樣,就不能點(diǎn)亮小燈。
我們的開發(fā)板上,還有一個(gè)74HC138作為8個(gè)LED小燈的總開關(guān),而P0.0僅僅是個(gè)分開關(guān)。如同我們家里總是有一個(gè)供電總閘,然后每個(gè)電燈又有一個(gè)專門的開關(guān),我們剛才的程序僅僅打開了那個(gè)電燈的開關(guān),但是沒有打開那個(gè)總電閘,所以程序需要加上這部分代碼。因?yàn)檫@節(jié)課要介紹的內(nèi)容比較多,所以我們把74HC138的原理以及為什么要加額外的代碼在下節(jié)課統(tǒng)一介紹,這節(jié)課我們直接加上這部分代碼,大家知道有這么一回事就可以了。
#include <reg52.h> //包含寄存器的庫文件
sbit LED = P0^0; //位地址聲明,注意:sbit必須小寫!
sbit ADDR0 = P1^0;
sbit ADDR1 = P1^1;
sbit ADDR2 = P1^2;
sbit ADDR3 = P1^3;
sbit ENLED = P1^4;
void main()
{
ENLED = 0;
ADDR0 = 0;
ADDR1 = 1;
ADDR2 = 1;
ADDR3 = 1; //74HC138開啟三極管
LED = 0; //點(diǎn)亮小燈
while(1); //程序停止在這里
}
寫了這么多啰嗦的語句,剛開始大家可能覺得很麻煩,為什么有的書上程序很簡(jiǎn)單就可以點(diǎn)亮小燈,我們這里要這樣來做。大家要了解一點(diǎn),就是我們做這個(gè)學(xué)習(xí)板呢,雖然僅僅提供給大家簡(jiǎn)單學(xué)習(xí)使用,但是我們也得按照實(shí)際產(chǎn)品的開發(fā)模式去設(shè)計(jì),所以綜合考慮因素很多,大家學(xué)到后邊就會(huì)明白它的設(shè)計(jì)價(jià)值了,這里大家只要跟著我們?nèi)プ鼍涂梢粤恕?/span>
程序編好了,我們要對(duì)我們的程序編譯進(jìn)行編譯,生成我們需要的可以下載到單片機(jī)里的文件,在編譯之前,我們先要勾選一個(gè)選項(xiàng),Project-->Options for Target‘Target1’...,或者直接點(diǎn)圖2-16中的快捷圖標(biāo):
圖2-16 Options for Target
在彈出的對(duì)話框中,點(diǎn)擊Output選項(xiàng)頁,勾選其中的“Create HEX File”復(fù)選框,然后點(diǎn)OK。
圖2-17 創(chuàng)建HEX選項(xiàng)配置
設(shè)置好以后呢,點(diǎn)擊“Project-->rebuild all target files”,或者鼠標(biāo)點(diǎn)擊圖2-18上的快捷圖標(biāo)。
圖2-18 編譯程序
編譯完成后,在我們的Keil下方的Output窗口會(huì)出現(xiàn)相應(yīng)的提示,大家注意看圖2-19,這個(gè)窗口告訴我們編譯完成后的情況,data=9.0,指的是我們的程序使用了單片機(jī)內(nèi)部的256字節(jié)RAM資源中的9個(gè)字節(jié),code=29的意思是使用了8K代碼Flash資源中的29個(gè)字節(jié)。當(dāng)提示“0 Error, 0 warning”表示我們的程序沒有錯(cuò)誤和警告,就會(huì)出現(xiàn)“creating hex file from “LED”,意思是從當(dāng)前工程生成了一個(gè)HEX文件,我們下載給單片機(jī)的就是這個(gè)HEX文件。如果出現(xiàn)有錯(cuò)誤和警告提示的話,就是Error和warning不是0,那么我們要對(duì)我們的程序進(jìn)行檢查,找出問題,解決好了再進(jìn)行編譯產(chǎn)生HEX才可以。
圖2-19 編譯輸出信息
這樣就編譯好了,下邊我們就可以把我們編譯好的程序文件下載到單片機(jī)里邊了。
1.5 程序下載
首先,我們要把硬件連接好,把板子插到我們的電腦上,通過設(shè)備管理器里找到是哪個(gè)COM口,這些基礎(chǔ)的知識(shí)我在測(cè)試視頻里都介紹過了,就不多說了,說一下STC-ISP下載軟件的設(shè)置,如圖2-20所示。
圖2-20 程序下載設(shè)置
下載軟件一共有5個(gè)步驟:第一步,選擇單片機(jī)型號(hào),我們現(xiàn)在用的單片機(jī)型號(hào)是STC89C52RC,這個(gè)一定不能錯(cuò)了;第二步,點(diǎn)擊“打開程序文件”,找到我們剛才建立工程的那個(gè)LED文件夾下,找到LED.HEX這個(gè)文件,點(diǎn)擊打開;第三步,選擇正確的COM口,這個(gè)COM口在裝好驅(qū)動(dòng)插上板子后,在電腦上的設(shè)備管理器里才會(huì)出現(xiàn),這個(gè)問題大家可以參考“全板子測(cè)試視頻”,波特率我們使用默認(rèn)的就行了;第四步里邊的所有選項(xiàng)我們?nèi)渴褂媚J(rèn),不要隨便改動(dòng),有的選項(xiàng)改錯(cuò)了以后可能會(huì)產(chǎn)生麻煩。第五步,因?yàn)?font face="Times New Roman">STC單片機(jī)要冷啟動(dòng)下載,就是先點(diǎn)下載,然后給單片機(jī)上電,所以我們先關(guān)閉板子上的電源開關(guān),然后點(diǎn)擊“Download/下載”,等待軟件提示你請(qǐng)上電后,如圖2-21所示,然后再打開板子開關(guān),就可以將程序下載到單片機(jī)里邊,當(dāng)軟件顯示“已加密”就表示程序成功下載,如圖2-22所示。
圖2-21 程序下載過程
2-22 程序下載完畢
程序下載完畢后,程序會(huì)自動(dòng)運(yùn)行,大家可以在板子上看到那一排LED最右側(cè)的小燈已經(jīng)發(fā)光了。那現(xiàn)在如果我們把LED = 0改成LED = 1,再編譯程序下載進(jìn)去新的HEX文件,燈就會(huì)熄滅。至此,點(diǎn)亮一個(gè)LED的實(shí)驗(yàn)已經(jīng)完成,終于邁出了第一步,是不是還挺好玩的呢。如有不懂可參考: http://www.torrancerestoration.com/mcuteach/252.html 第2課里面的詳解.
1.6 作業(yè)
1、了解普通發(fā)光二級(jí)管的參數(shù),掌握限流電阻的計(jì)算方法。
2、理解單片機(jī)最小系統(tǒng),單片機(jī)外圍電路,FLASH,RAM和SFR這些概念。
3、了解Keil的基本用法和單片機(jī)編程的基本流程,能夠獨(dú)立完成編程下載等基本操作。