51單片機(jī)學(xué)習(xí)之2-流水燈
講解了74HC573使用方法,我在《51單片機(jī)復(fù)習(xí)筆記1(更新)》有記錄。這里略。
本文引用地址:http://m.butianyuan.cn/article/201611/323852.htm講解了Keil的仿真方法。比較有用的內(nèi)容是可以用它來測試一段代碼所使用的時間,例如延時函數(shù),在需要精確延時又不想使用定時器的時候可以使用該方法。至于其他的,個人認(rèn)為還是直接下載到單片機(jī)中觀察實際情況會比較直觀。
第六集
51最小系統(tǒng)
復(fù)位原理:
51單片機(jī)是高電平脈沖復(fù)位,在RST引腳。復(fù)位脈沖的高電平寬度必須大于2個機(jī)器周期。為了方便計算,我們假設(shè)晶振頻率為12M,那么它的時鐘周期為1/12us(微秒)。它的一個機(jī)器周期是12*(1/12)=1us(微秒)。復(fù)位脈沖高電平寬度必須大于2個機(jī)器周期即2us,那么就要保證RST引腳高電平的時間大于2us單片機(jī)即可自動復(fù)位。
上電復(fù)位:
當(dāng)通電時,開關(guān)是斷開的,那么電流從VCC→電容→RST、R32→GND。剛上電的時候,電容開始充電,充滿電后相當(dāng)于斷路,在電容充電到充滿的過程中電壓逐漸從高到低(從5V到0V)。也就是說一上電,RST端得到就是高電平,當(dāng)這個時間超過2us時單片機(jī)復(fù)位,電容快充滿到充滿后RST得到是低電平,電源不斷那么RST就一直是低電平而不會一直復(fù)位。RST高電平持續(xù)的時間取決于電容充電時間.。(這個電容要取多大?怎么計算的?)
手動復(fù)位:
通電之后,RST會自動復(fù)位一次,當(dāng)單片機(jī)在運(yùn)行的過程中我們需要它復(fù)位時可以斷電使之上電復(fù)位。或者按下SW0開關(guān)也能實現(xiàn)復(fù)位。當(dāng)SW0開關(guān)按下時電流從VCC→R33→RST、R32→GND形成回路。為方便計算R33假設(shè)為300歐即0.3K,我們可以先計算R33得到的電壓是5V*(0.3k/(4.7k+0.3k))=0.3VR32得到的電壓為5V*(4.7k/(4.7k+0.3k))=4.7VRST端的電壓也為4.7V,那么4.7對于單片機(jī)來說也算高電平,當(dāng)按下手動按下SW按鈕到松開肯定超過2us,所以單片機(jī)自動復(fù)位。
晶振電路:
兩個電容一定要相等,取值范圍為20-50pf越大啟動越慢。
自己搭建最小系統(tǒng)要注意的地方:
EA引腳一定要接高電平即VCC,這是最容易忽略的。這個引腳是用來選擇是用片內(nèi)存儲器還是用片外存儲器。51內(nèi)部存儲器一般都夠我們使用。在以前的單片機(jī)需要外擴(kuò)存儲器。我們燒錄的程序就是存在片內(nèi)存儲器。
要將P0組引腳當(dāng)普通IO用時,需要接10K的上拉電阻。P1-P3里面都有上啦電阻。
1做地址/數(shù)據(jù)總線時和做輸入I/O口時,p0口不用接上拉電阻。
2但當(dāng)做輸出I/O口時,p0口必須要接上拉電阻才可以。
P0口是集電極開路輸出,也就是OC門,這種結(jié)構(gòu)沒有輸出高電平的能力就相當(dāng)于一個一端接地的開關(guān),按下去就輸出低電平0V,斷開就沒有電壓,是懸空狀態(tài)。
至于用不用上拉電阻,取決于外部電路,如果要輸出高電平控制一個器件,而這個器件本身又沒有內(nèi)置上拉,就必須自己接一個上拉電阻,如果要用低電平控制一個器件,則可以不用加上拉。
第七集
一、流水燈的設(shè)計
流水燈就是讓八個小Led的依次亮滅。先看看流水燈的電路圖。
這是我的實驗板的流水燈電路圖。其中74HC573的D輸入引腳DB1—DB8接在單片機(jī)的P1組引腳。74HC573的LE接在P2.5引腳。
程序設(shè)計思路:
我實驗板上有8個Led燈,正極接在VCC,負(fù)極接在單片機(jī)的P1引腳(這里不使用74HC573鎖存功能所以LE一直保存高電平,相當(dāng)于Led直接接在單片機(jī)的IO口)。要讓Led燈亮只需要把對應(yīng)的端口設(shè)為低電平,那么Led燈亮。依次讓P1的八個引腳給高低電平那么Led燈也會跟著暗亮。由于51單片機(jī)執(zhí)行的速度很快,所以Led燈的閃爍速度也會很快,我們?nèi)庋蹮o法看到,所以要在電平切換時適當(dāng)?shù)难訒r一下。
流水燈的程序設(shè)計有很多種方法,如按位置位、數(shù)組、函數(shù)_cror_()_crol()等,我本來我是比較喜歡用函數(shù)的方法,但后來看了一下AVR的,貌似用的最多的是與、或、非、異或這些運(yùn)算符來操控IO口,所以我就用這種方式吧,練熟一些方便以后學(xué)習(xí)。
#include"reg52.h"
#defineucharunsignedchar
#defineuintunsignedint
//用來延時
voiddelay(ucharx)
{
uinty;
for(;x>0;x--)
for(y=500;y>0;y--);
}
voidmain()
{
ucharTmp;
uchari;
while(1)
{
Tmp=0xFE;//在流之前先讓第一個燈亮11111110
for(i=0;i<8;i++)
{
P1=Tmp;
Tmp=Tmp<<1;//左移動一位0xFE=11111110<<1=11111100
Tmp=Tmp|0x01;//將最后一位置111111100|00000001=11111101
delay(100); //讓燈亮一段時間
}
}
}
評論