熟女俱乐部五十路二区av,又爽又黄禁片视频1000免费,国产卡一卡二卡三无线乱码新区,中文无码一区二区不卡αv,中文在线中文a

新聞中心

51單片機(jī)入門(mén)1

作者: 時(shí)間:2016-11-23 來(lái)源:網(wǎng)絡(luò) 收藏
我們?cè)?strong>單片機(jī)最小系統(tǒng)上接個(gè)LED,看我們能否點(diǎn)亮它!對(duì)了,上面也有好幾次提到過(guò)單片機(jī)最小系統(tǒng)了,所謂單片機(jī)最小系統(tǒng)就是在單片機(jī)
上接上最少的外圍電路元件讓單片機(jī)工作。一般只須連接晶體、VCC、GND、RST即可,一般情況下,AT89C51的31腳須接高電平。
#include//頭文件定義?;蛴?include其具體的區(qū)別在于:后者定義了更多的地址空間。
//在Keil安裝文件夾中,找到相應(yīng)的文件,比較一下便知!
sbit P1_0 = P1 ^ 0;
void main (void)
{
while(1)
{
P1_0 = 0;//低電平有效,如果把LED反過(guò)來(lái)接那么就是高電平有效
}
}

就那么簡(jiǎn)單,我們就把接在單片機(jī)P1_0上的LED點(diǎn)亮了,當(dāng)然LED是低電平,才能點(diǎn)亮。因?yàn)槲覀儼袻ED的正通過(guò)電阻接至VCC。
P1_0 = 0; 類似與C語(yǔ)言中的賦值語(yǔ)句,即把 0 賦給單片機(jī)的P1_0引腳,讓它輸出相應(yīng)的電平。那么這樣就能達(dá)到了我們預(yù)先的要求了。
while(1)語(yǔ)句只是讓單片機(jī)工作在死循環(huán)狀態(tài),即一直輸出低電平。如果我們要試著點(diǎn)亮其他的LED,也類似上述語(yǔ)句。這里就不再講了。
點(diǎn)亮了幾個(gè)LED后,是不是讓我們聯(lián)想到了繁華的街區(qū)上流動(dòng)的彩燈。我們是不是也可以讓幾個(gè)LED依次按順序亮呢?答案是肯定的!其
實(shí)顯示的原理很簡(jiǎn)單,就是讓一個(gè)LED滅后,另一個(gè)立即亮,依次輪流下去。假設(shè)我們有8個(gè)LED分別接在P1口的8個(gè)引腳上。硬件連接,在
P1_1--P1_7上再接7個(gè)LED即可。例程如下:
#include

sbit P1_0 = P1 ^ 0;
sbit P1_1 = P1 ^ 1;
sbit P1_2 = P1 ^ 2;
sbit P1_3 = P1 ^ 3;
sbit P1_4 = P1 ^ 4;
sbit P1_5 = P1 ^ 5;
sbit P1_6 = P1 ^ 6;
sbit P1_7 = P1 ^ 7;

void Delay(unsigned char a)
{
unsigned char i;
while( --a != 0)
{
for(i = 0; i < 125; i++);//一個(gè) ; 表示空語(yǔ)句,CPU空轉(zhuǎn)。
}//i 從0加到125,CPU大概就耗時(shí)1毫秒
}

void main(void)
{
while(1)
{
P1_0 = 0;
Delay(250);
P1_0 = 1;

P1_1 = 0;
Delay(250);
P1_1 = 1;

P1_2 = 0;
Delay(250);
P1_2 = 1;

P1_3 = 0;
Delay(250);
P1_3 = 1;

P1_4 = 0;
Delay(250);
P1_4 = 1;

P1_5 = 0;
Delay(250);
P1_5 = 1;

P1_6 = 0;
Delay(250);
P1_6 = 1;

P1_7 = 0;
Delay(250);
P1_7 = 1;
}
}


sbit 定義位變量,unsigned char a 定義無(wú)符字符型變量a,以節(jié)省單片機(jī)內(nèi)部資源,其有效值為0~255。main函數(shù)調(diào)用Delay()函數(shù)。
Delay函數(shù)使單片機(jī)空轉(zhuǎn),LED持續(xù)點(diǎn)亮后,再滅,下一個(gè)LED亮。while(1)產(chǎn)生循環(huán)。





(三)

上面我們講了如何使LED產(chǎn)生流動(dòng),但是你是否發(fā)現(xiàn)一個(gè)問(wèn)題:寫(xiě)的太冗長(zhǎng)了!能不能再簡(jiǎn)單點(diǎn)呢?可以!可以使用C51的內(nèi)部函數(shù)
INTRINS.H實(shí)現(xiàn)。函數(shù)unsigned char _crol_(unsigned char a, unsigned char n) 可以使變量a循環(huán)左移n位,如果我們先給P1口賦
0000 0001那么當(dāng)n為1時(shí),便會(huì)產(chǎn)生和上面一樣的效果!
#include
#include

void Delay(unsigned char a)
{
unsigned char i;
while( --a != 0)
{
for(i = 0; i < 125; i++);
}
}

void main(void)
{
unsigned char b, i;
while(1)
{
b = 0xfe;
for(i = 0; i < 8; i++)
{
P1 = _crol_(b, 1);
b = P1;
Delay(250);
}
}
}



INTRINS.H函數(shù)中的unsigned char _cror_(unsigned char a, unsigned char n)右移也可以實(shí)現(xiàn)同樣的效果!這里就不再累述。
流水燈的花樣很多,我還寫(xiě)過(guò)那種拉幕式的流動(dòng)等,程序很簡(jiǎn)單,有興趣的朋友,可以自己試著寫(xiě)寫(xiě)!
對(duì)了,講了那么多,有些朋友一定還不知道編譯軟件怎么用?這里給大家介紹幾個(gè)吧?WAVE(偉福)大家一定聽(tīng)說(shuō)過(guò)吧!還有一個(gè)
就是KEIL2,我用的就是KEIL2,下面就來(lái)講講如何使用KEIL2這個(gè)編譯軟件!
1.安裝軟件,這個(gè)應(yīng)該不用再講了吧!
2.安裝完后,啟動(dòng)KEIL軟件左擊Project-->New Project-->輸入文件名-->選擇我們所以使用的芯片(這里我們一般用到Atmel的
AT89C51或AT89C2051,點(diǎn)確定。
3.點(diǎn)File-->New-->輸入我們編寫(xiě)的程序,保存為.C文件。(一般情況下,我們保存的文件名和前面的工程名一樣。)

4.展開(kāi)Target 1 -->右擊Source Group 1 -->Add Files to Group Source Group 1-->選擇剛才保存的.C文件點(diǎn)擊ADD后,關(guān)閉對(duì)
話框。這樣.C文件就被加到了Source Group 1 下。
5.右擊Target 1-->Optionsfor Target 1 -->Target中填寫(xiě)晶體的大小,Output中,在Create HEX Files 前打上鉤,點(diǎn)確
定。
6.點(diǎn)Project-->Rebuild All Traget Files ,若提示
creating hex file from "XXX"...
"XXX" - 0 Error(s), 0 Waring(s).
表示編譯和生成HEX文件成功!接下來(lái)的就是把HEX文件燒到單片機(jī)中,或是仿真器上,看是否達(dá)到預(yù)先的目的!
嘿嘿!現(xiàn)在是否自己好有成就感了,如果讓你去做個(gè)流水彩燈,開(kāi)發(fā)一個(gè)簡(jiǎn)單的產(chǎn)品,只要加上驅(qū)動(dòng)電路,就可以做出漂亮的流動(dòng)彩燈
了!到現(xiàn)在為止,你應(yīng)該知道單片機(jī)的功能有多強(qiáng)大了吧,如果單純的用數(shù)字電路或模擬電路的知識(shí)去設(shè)計(jì)一個(gè)流動(dòng)彩燈,可能要花點(diǎn)工夫
和時(shí)間才行,有了單片機(jī),那就不一樣了,你只要寫(xiě)程序控制他就行!有人說(shuō)過(guò)這樣一句話,也并不無(wú)道理的,學(xué)單片機(jī),程序思想很重要!






(四)

呵呵,朋友!相信你的流水燈也做的不錯(cuò)了吧,現(xiàn)在能玩出幾種花樣了?你可能會(huì)說(shuō),只要你想得到,想怎么流就怎么流!呵呵,是的。
但是工程師們?cè)O(shè)計(jì)這么一個(gè)單片機(jī),并不是只為了讓它做流水燈的,那樣也太浪費(fèi)點(diǎn)了吧 ... ^_^
學(xué)過(guò)數(shù)字電路的朋友,一定動(dòng)手做過(guò)8路或者6路的搶答器。用純粹的數(shù)字電路知識(shí)來(lái)做,自己設(shè)計(jì)電路,感到比較困難!搶答器上用的顯
示器多為7段數(shù)碼管,這里我們來(lái)講講,如何用單片機(jī)讓數(shù)碼管顯示0-9。搶答器的實(shí)現(xiàn),我們放到后面再來(lái)探討,因?yàn)閾尨鹌鬟€涉及了鍵盤(pán)的
內(nèi)容。8段數(shù)碼管分為共陰和共陽(yáng)兩種。8段數(shù)碼管是由8個(gè)LED組成(還包括一個(gè)小數(shù)點(diǎn))。若為共陽(yáng),則8個(gè)LED的陽(yáng)級(jí)是連接在一起的,同理
若為共陰,則陰極連接在一起。8個(gè)LED對(duì)應(yīng)的標(biāo)號(hào)如下:
a
__
f || b
|__|
|g | c
e |__| . dp
d
一般情況下,為了計(jì)算或取碼的方便,我們把a(bǔ)-dp依次接到單片機(jī)某個(gè)口上的Px.0--Px.7上。x表示0,1,2,3其中的一個(gè)。這樣我們只
要給某個(gè)口,賦一個(gè)值,則相應(yīng)的LED段就被點(diǎn)亮,但是在硬件連接上要注意了:?jiǎn)纹瑱C(jī)可能不能直接驅(qū)動(dòng)LED,所以我們可以通過(guò)控制三級(jí)管
的導(dǎo)通或截止,來(lái)控制LED的亮與滅!
如果我們把共陰的數(shù)碼管的a--dp依次接到單片機(jī)的P0.0--P0.7上,注意:P0口需接上拉電阻。何為上拉電阻,簡(jiǎn)單的說(shuō),就是把電平拉
高,以提高驅(qū)動(dòng)能力。那么比如:P0 = 0X3F;則顯示為數(shù)字 0 。因?yàn)?X3F 即為2進(jìn)制的 0011 1111 我們低位往高位數(shù),依次為1111 1100,
其I/O的電平分別為高、高、高、高、高、高、低、低,即對(duì)應(yīng)的a--dp 為亮、亮、亮、亮、亮、亮、滅、滅,由上圖我們可以看出g和dp段不
亮其他段均亮,即為我們所看到的數(shù)字 0 字樣。其他的數(shù)字或字符,也同理可以得到。但是有些朋友就會(huì)問(wèn),那我們每取一個(gè)字模,豈不是
很麻煩?還有自己考慮高低電平什么的?^-^ 呵呵,其實(shí)網(wǎng)上有很多LED取模軟件,如果有一定計(jì)算機(jī)編程語(yǔ)言的朋友,也可以試著自己寫(xiě)個(gè)
取模的程序,讓計(jì)算機(jī)為我們計(jì)算,諸如上述0X3F的數(shù)值。
#include

void Delay(unsigned char a)
{
unsigned char i;
while( --a != 0)
{
for(i = 0; i < 125; i++);
}
}

void main(void)
{
P0 = 0X3F;//顯示 0
Delay(250);//延時(shí)
P0 = 0X00;//短暫的關(guān)閉顯示,若不關(guān)閉,可能會(huì)造成顯示模糊不清。

P0 = 0X06; //顯示 1
Delay(250);
P0 = 0X00;

...//以下顯示數(shù)字2-F,略。
}

看到這里,想必大家一定可以把0-F顯示出來(lái)了吧!但是如果要你顯示兩位數(shù),三位數(shù)呢?或許,有的朋友會(huì)這么想:在P0口上接一個(gè)
數(shù)碼管,再在P1口上接個(gè)數(shù)碼管!但是,如果要顯示4位、5位的數(shù)字呢?那豈不是一塊AT8951都接不過(guò)來(lái)!難到就不能接4位或5位以上的嗎?
肯定不是的!
說(shuō)到這里,我們來(lái)講講數(shù)碼管的顯示方式,可分為兩種:動(dòng)態(tài)掃描和靜態(tài)顯示。上面我們所說(shuō)的即為靜態(tài)顯示。但是如果我們采用動(dòng)態(tài)掃
描顯示,那么就可以解決上面的問(wèn)題,即可以顯示多個(gè)數(shù)碼管了。上面我們所說(shuō)的靜態(tài)顯示把數(shù)碼管的COM腳接至VCC或GND端,其他的接至PX
口上,這樣只要PX口上輸出相應(yīng)的高低電平,就可以顯示對(duì)應(yīng)的數(shù)字或字符。但是如果我們采用動(dòng)態(tài)掃描的方法,比如顯示6個(gè)數(shù)碼管,硬件
連接可以這樣解決:a--dp還是接至P0.0--P0.7上,還有6個(gè)COM腳再接至另外口的P2.0--P2.5。P0口作段選(控制數(shù)字字符)P2口作位選(選

通哪個(gè)數(shù)碼管導(dǎo)通)這樣我們控制P0和P2口就可以控制6個(gè)數(shù)碼管了。但是,細(xì)心的朋友,會(huì)問(wèn)這樣的問(wèn)題:P2位選,是讓數(shù)碼管一個(gè)一個(gè)亮
的,那還是不能控制6個(gè)一起亮或滅嘛?。?^_^ 想想好象是對(duì)的哦?怎么辦...難道錯(cuò)了?
嘿嘿,問(wèn)你個(gè)問(wèn)題?黑夜里,拿著一支煙,在你面前快速的晃動(dòng),你會(huì)發(fā)現(xiàn)什么樣的現(xiàn)象?是不是原本不連續(xù)的點(diǎn)變成了一條看上去連
續(xù)的曲線或者直線!再回過(guò)頭來(lái),仔細(xì)想想我們的數(shù)碼管!原理是一樣的,你可別忘了,我們的單片機(jī)可是一個(gè)計(jì)算機(jī)哦,計(jì)算機(jī)的運(yùn)算速
度,大家可想而知吧!
這里再說(shuō)說(shuō)51單片機(jī)的機(jī)器周期和時(shí)鐘周期等概念。所謂機(jī)器周期就是訪問(wèn)一次存儲(chǔ)器的時(shí)間。而1個(gè)機(jī)器周期包括12個(gè)時(shí)鐘周期。如果
單片機(jī)工作在12M晶體下,那么一個(gè)時(shí)鐘周期為:1/12微妙。一個(gè)機(jī)器周期12*1/12 = 1微妙。如果晶體為6M,時(shí)鐘周期和機(jī)器周期各是多少呢
?在匯編中,我們還要關(guān)心,指令執(zhí)行的機(jī)器周期長(zhǎng)短不一,有1個(gè)周期、2個(gè)周期和4個(gè)周期等。
說(shuō)著說(shuō)著,跑了這么遠(yuǎn)了...還是回到原來(lái)的話題,如果我們把位選的P2也看作上面的“煙”一劃而過(guò),那么我們看到的是不是6個(gè)一起亮
或一起滅了!^_^哈哈,原來(lái)如此...記住,在任何某一時(shí)刻,有且只有一個(gè)數(shù)碼管能發(fā)光。如果你能把這句話理解了,你是真明白
我的意思了!朋友,現(xiàn)在給你個(gè)任務(wù),讓6個(gè)數(shù)碼管分別顯示1、2、3、4、5、6??茨阕约嚎梢愿愣ú唬磕阕约合仍囍鴮?xiě)寫(xiě)看咯...

#include

void Delay(unsigned char a)
{
unsigned char i;
while( --a != 0)
{
for(i = 0; i < 125; i++);
}
}

void main(void)
{
while(1)
{
P0 = 0x06;//1的碼段
P2 = 0x01;//選通一位,或者P2_0 = 1;
Delay(20);//延時(shí)約20毫秒
P0 = 0X00;//關(guān)閉顯示

P0 = 0x5b;//2的碼段
P2 = 0x02; //選通一位,或者P2_1 = 1;
Delay(20);
P0 = 0X00;

P0 = 0x4f;//3的碼段
P2 = 0x04; //選通一位,或者P2_2 = 1;
Delay(20);
P0 = 0X00;

P0 = 0x66;//4的碼段
P2 = 0x08; //選通一位,或者P2_3 = 1;
Delay(20);
P0 = 0X00;

P0 = 0x6d;//5的碼段
P2 = 0x10;//選通一位,或者P2_4 = 1;
Delay(20);
P0 = 0X00;

P0 = 0x7d;//6的碼段
P2 = 0x20;//選通一位,或者P2_5 = 1;
Delay(20);
P0 = 0X00;
}
}




(五)

相信大家一定見(jiàn)過(guò)數(shù)字時(shí)鐘,教學(xué)樓大廳一定有吧。每次路過(guò),基本上只是隨便瞟上一眼,根本沒(méi)去想過(guò)他的工作原理什么。但是今天
你也可以把他做出來(lái)了,是不是覺(jué)得自己很有成就感呢!呵呵! ^_^
接上面所講的,我們先來(lái)做個(gè)簡(jiǎn)單的實(shí)驗(yàn):在一個(gè)數(shù)碼管上輪流顯示0--9這10個(gè)數(shù)字。還楞著干什么,快動(dòng)手寫(xiě)程序呀!好象有點(diǎn)難哦,
要不先不要往下看了,嘿嘿,關(guān)機(jī)吧,自己先去想想,怎么樣?
#include

unsigned char code SEG_TAB[ ] ={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; //0-9數(shù)字

void Delay(unsigned int a)//unsigned int 定義為無(wú)符整形,取值范圍為0--32768
{
unsigned char i;
while( --a != 0)
{
for(i = 0; i < 125; i++);
}
}

void main(void)
{
unsigned char i;
while(1)
{
for(i = 0; i < 10; i++)
{
P0 = SEG_TAB[ i ];//取SEG_TAB數(shù)組中的值
P2 = 0X01;
Delay(1000);
}
}
}

是不是顯示從0--9,跳動(dòng)顯示,你的心是不是也跟著一起跳呀,離我們的目標(biāo)又邁進(jìn)了一步!不錯(cuò),繼續(xù)努力!
上面只顯示了一個(gè)數(shù)碼管的數(shù)字0--9,但是怎么樣要讓他顯示6個(gè)數(shù)字呢?這樣我們就可以做個(gè)時(shí)鐘出來(lái)玩玩了!還記不記得我們前面
講過(guò)的P2口的位選作用!嘿嘿,沒(méi)忘記就好!
#include

unsigned char hour = 12, min = 0, sec = 0;
unsigned char code SEG_TAB[ ] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; //0-9數(shù)字

void Delay(unsigned char a)
{
unsigned char i;
while( --a != 0)
{
for(i = 0; i < 125; i++);
}
}

void disp(void)
{
P0 = SEG_TAB[ sec % 10 ];//顯示秒的個(gè)位
P2 = 0X01;
Delay(15);
P2 = 0;

P0 = SEG_TAB[ sec / 10 ];//顯示秒的十位
P2 = 0X02;
Delay(15);
P2 = 0;

P0 = SEG_TAB[ min % 10 ];//顯示分的個(gè)位
P2 = 0X04;
Delay(15);
P2 = 0;

P0 = SEG_TAB[ min / 10 ];//顯示分的十位
P2 = 0X08;
Delay(15);
P2 = 0;

P0 = SEG_TAB[ hour % 10 ];//顯示時(shí)的個(gè)位
P2 = 0X10;
Delay(15);
P2 = 0;

P0 = SEG_TAB[ hour / 10 ];//顯示時(shí)的十位
P2 = 0X20;
Delay(15);
P2 = 0;
}

void main(void)
{
while( 1 )
{
disp( );
}
}


關(guān)鍵詞: 51單片機(jī)入

評(píng)論


技術(shù)專區(qū)

關(guān)閉