C語言51單片機C語言入門教程_第1頁
C語言51單片機C語言入門教程_第2頁
C語言51單片機C語言入門教程_第3頁
C語言51單片機C語言入門教程_第4頁
C語言51單片機C語言入門教程_第5頁
已閱讀5頁,還剩10頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認(rèn)領(lǐng)

文檔簡介

1、此資料由網(wǎng)絡(luò)收集而來,如有侵權(quán)請告知上傳者立即刪除。資料共分享,我們負(fù)責(zé)傳遞知識。PAGE (1小時學(xué)會C語言51單片機)C語言入門教程 Victor Hugo 維克多?雨果相信很多愛好電子的朋友,對單片機這個詞應(yīng)該都不會陌生了吧。不過有些朋友可能只聽說他叫單片機,他的全稱是什么也許并不太清楚, 更不用說他的英文全稱和簡稱了。單片機是一塊在集成電路芯片上集成了一臺有一定規(guī)模的微型計算機。簡稱為:單片微型計算機或單片機 (Single Chip Computer)。單片機的應(yīng)用到處可見,應(yīng)用領(lǐng)域廣泛,主要應(yīng)用在智能儀表、實時控制、通信、家電等方面。不過這一切都沒 什么關(guān)系,因為我(當(dāng)然也包括任何

2、人)都是從不知道轉(zhuǎn)變成知道的,再轉(zhuǎn)變成精通的?,F(xiàn)在我只想把我學(xué)習(xí)單片機的經(jīng)歷,詳細(xì)地講敘給大 家聽聽,可能有些大蝦會笑話我,想:那么簡單的東西還在這里賣弄。但是你錯了,我只是把我個人學(xué)習(xí)的經(jīng)歷講述一遍而已,僅僅對那些想 學(xué)習(xí)單片機,但又找不到好方法或者途徑的朋友,提供一個幫助,使他們在學(xué)習(xí)過程中,盡量少走些彎路而已! 首先,你必須有學(xué)習(xí)單片機的熱情,不是說今天去圖書館看了一個下午關(guān)于單片機的書,而明天玩上半天,后天就不知道那個本書在講什 么東西了。還是先說說我吧,我從大二的第一個學(xué)期期末的時候才開始接觸單片機,但在這之前,正如上面所說的:我知道有種芯片叫單片機, 但是具體長成什么樣子,卻一點也

3、不知道!看到這里很多朋友一定會忍不住發(fā)笑。嘿嘿,你可千萬別笑,有些大四畢業(yè)的人也同樣不知道單片 機長成什么樣子呢!而我對單片機的癡迷更是常人所不能想象的地步,大二的期末考試,我全放棄了復(fù)習(xí),每當(dāng)室友拿著書在埋頭復(fù)習(xí)的時候, 我卻捧著自己從圖書館借的單片機書在那看,雖然有很多不懂,但是我還是堅持了下來,當(dāng)時我就想過,為了單片機值不值得我這樣去付出, 或許這也是在一些三流學(xué)校的好處吧,考試掛科后,明年開學(xué)交上幾十元一門的補考費,應(yīng)該大部分都能過了。于是,我橫下一條心,堅持看 我的單片機書和資料。 當(dāng)你明白了單片機是這么一回事的時候,顯而易見的問題出來了:我要選擇那種語言為單片機編寫程序呢?這個問題

4、,困擾了我好久。具 體選擇C51還是A51呢?匯編在我們大二之前并沒有開過課,雖然看著人家的講解,很容易明白單片機的每一時刻的具體工作情況,但是一合上 書或者資料,自己卻什么也不知道了得花錢,如果不買些芯片回來自己動手焊焊拆拆的(但是在后期會介紹給大家一個很好用的硬件 仿真軟件,并不需要你用實驗板和仿真器了,直接在你的PC上完成,但是軟件畢竟是軟件,從某個特定的意義上來說是并不能代替硬件的),即使 你每天捧著本書,把那本書翻爛,也永遠(yuǎn)學(xué)不會單片機的!剛接觸單片機的朋友,看了資料,一定會對以下幾個詞見的比較多,但是具體的概 念還是比較模糊,現(xiàn)作如下說明: (1)編程器 編程器是用來燒單片機芯片的

5、,是把HEX或者BIN文件燒到單片機ROM里的,供單片機運行的。 (2)實驗板 實驗板是專為初學(xué)者根據(jù)某些要求而特做的板,一般上面就有一個單片機的最小系統(tǒng),使用者只需寫好程序,燒好芯片,放 到上面加以驗證的這么一個工具。有了實驗板,對與初學(xué)者來說,省去了焊個最小系統(tǒng)的麻煩。但是對于電子開發(fā)人員來說,作用并不是很大 (3)仿真器 仿真器是直接把HEX或者BIN文件暫時放在一個芯片里,再通過這個芯片的引腳連接到實驗板或者系統(tǒng)上工作。這樣以來,可 以省去了來回插拔芯片帶來的不必要麻煩。 我一開始也不知道上面3個的概念和作用,嘿嘿,原本想買個實驗板(不想焊板,因為不可能為了點亮幾個流水燈,而去焊個單片

6、機的最小系統(tǒng)) 的,可是結(jié)果,確和我想的正好相反,人家出售的是編程器。等貨物寄到后,才知道自己搞錯了!汗。嘿嘿。現(xiàn)在想想實在是又氣又笑。我花 了160大樣買了個編程器(很不幸的是,這個編程器更本用不了,一燒芯片,芯片就燒壞了)把我給氣的,這個編程器,現(xiàn)在還躺在我的抽屜里 呢不過,現(xiàn)在想想,唯一讓我覺得欣慰的是,那個老板每次能解答我的問題,連那種超級幼稚的問題,他也能不嫌麻煩地盡量幫我解答!這點讓 我很感動! 第三,想學(xué)單片機的必需品-PC。因為寫程序,編譯或者是仿真都是通過PC完成的。如果沒有PC,什么也做不了!有了PC最好還要可 以上網(wǎng),因為如果你沒有可以和你交流單片機的人,遇到自己解決不了

7、的問題,一直都想不通,那么估計你學(xué)習(xí)單片機的熱情就會隨著時間的 推移而慢慢耗盡。如果你能上網(wǎng)通過論壇或者QQ群,問題就很快得到解決。這樣的學(xué)習(xí)效率一定很高!真正的高手是從論壇中泡出來的! 有了上述3個條件后,你就可以開始學(xué)你的單片機了。但是,真的做起來并沒有我所說的那么簡單。你一定會遇到很多很多的問題。比如 為了讓單片機實現(xiàn)某個功能,你可能不知道怎么去寫某個程序?;蚴悄憧炊速Y料上某個相似的程序,你自己卻寫不出來。遇到類似的情況, 記?。呵f不要急噪,就行! (二) 說了這么多了,相信你也看了很多資料了,手頭應(yīng)該也有必備的工具了吧?。ú灰松厦嬷v過幾個條件的哦)。那個單片機究竟有什么 功能和

8、作用呢?先不要著急!接下來讓我們點亮一個LED(搞電子的應(yīng)該知道P1_0引腳,讓它輸出相應(yīng)的電平。那么這樣就能達到了我們預(yù)先的要求了。 while(1)語句只是讓單片機工作在死循環(huán)狀態(tài),即一直輸出低電平。如果我們要試著點亮其他的LED,也類似上述語句。這里就不再講了。 點亮了幾個LED后,是不是讓我們聯(lián)想到了繁華的街區(qū)上流動的彩燈。我們是不是也可以讓幾個LED依次按順序亮呢?答案是肯定的!其 實顯示的原理很簡單,就是讓一個LED滅后,另一個立即亮,依次輪流下去。 假設(shè)我們有8個LED分別接在P1口的8個引腳上。硬igned char a) unsigned char i; while( -a

9、!= 0) for(i = 0; i /i 從0加到125,CPU大概就耗時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;

10、 Delay(250); P1_7 = 1; sbit 定義位變量,unsigned char a 定義無符字符型變量a,以節(jié)省單片機內(nèi)部資源,其有效值為0255。main函數(shù)調(diào)用Delay()函數(shù)。 Delay函數(shù)使單片機空轉(zhuǎn),LED持續(xù)點亮后,再滅,下一個LED亮。while(1)產(chǎn)生循環(huán)。 (三) 上面我們講了如何使LED產(chǎn)生流動,但是你是否發(fā)現(xiàn)一個問題:寫的太冗長了!能不能再簡單點呢?可以!可以使用C51的內(nèi)部函數(shù) INTRINS.H實現(xiàn)。函數(shù)unsigned char _crol_(unsigned char a, unsigned char n) 可以使變量a循環(huán)左移n位,如果我們

11、先給P1口賦 0000 0001那么當(dāng)n為1時,便會產(chǎn)生和上面一樣的效果! #include #include void Delay(unsigned char a) unsigned char i; while( -a != 0) for(i = 0; i 流水燈的花樣很多,我還寫過那種拉幕式的流動等,程序很簡單,有興趣的朋友,可以自己試著寫寫! 對了,講了那么多,有些朋友一定還不知道編譯軟件怎么用?這里給大家介紹幾個吧?WAVE(偉福)大家一定聽說過吧!還有一個 就是KEIL2,我用的就是KEIL2,下面就來講講如何使用KEIL2這個編譯軟件! 1.安裝軟件,這個應(yīng)該不用再講了吧! 2.安

12、裝完后,啟動KEIL軟件左擊Project-New Project-輸入文件名-選擇我們所以使用的芯片(這里我們一般用到Atmel的 AT89C51或AT89C2051,點確定。 3.點File-New-輸入我們編寫的程序,保存為.C文件。(一般情況下,我們保存的文件名和前面的工程名一樣。) 4.展開Target 1 -右擊Source Group 1 -Add Files to Group Source Group 1-選擇剛才保存的.C文件點擊ADD后,關(guān)閉對 話框。這樣.C文件就被加到了Source Group 1 下。 5.右擊Target 1-Options for Target 1

13、 -Target中填寫晶體的大小,Output中,在Create HEX Files 前打上鉤,點確 定。 6.點Project-Rebuild All Traget Files ,若提示 creating hex file from “XXX“. “XXX“ - 0 Error(s), 0 Waring(s). 表示編譯和生成HEX文件成功!接下來的就是把HEX文件燒到單片機中,或是仿真器上,看是否達到預(yù)先的目的! 嘿嘿!現(xiàn)在是否自己好有成就感了,如果讓你去做個流水彩燈,開發(fā)一個簡單的產(chǎn)品,只要加上驅(qū)動電路,就可以做出漂亮的流動彩燈 了!到現(xiàn)在為止,你應(yīng)該知道單片機的功能有多強大了吧,如果單

14、純的用數(shù)字電路或模擬電路的知識去設(shè)計一個流動彩燈,可能要花點工夫 和時間才行,有了單片機,那就不一樣了,你只要寫程序控制他就行!有人說過這樣一句們來講講,如何用單片機讓數(shù)碼管顯示0-9。搶答器的實現(xiàn),我們放到后面再來探討,因為搶答器還涉及了鍵盤的 內(nèi)容。8段數(shù)碼管分為共陰和共陽兩種。8段數(shù)碼管是由8個LED組成(還包括一個小數(shù)點)。若為共陽,則8個LED的陽級是連接在一起的,同理 若為共陰,則陰極連接在一起。8個LED對應(yīng)的標(biāo)號如下:(0 x3f, 0 x06,0 x5b,0 x4f,0 x66,0 x6d,0 x7d,0 x07,0 x7f,0 x6f; /0-9數(shù)字) a 0 1 2 3

15、4 5 6 7 8 9 _ 0011 1111,0000 0110,0100 1111,0101 1011 f | | b |_| |g | c e |_| . dp d 一般情況下,為了計算或取碼的方便,我們把a-dp依次接到單片機某個口上的Px.0-Px.7上。x表示0,1,2,3其中的一個。這樣我們只 要給某個口,賦一個值,則相應(yīng)的LED段就被點亮,但是在硬件連接上要注意了:單片機可能不能直接驅(qū)動LED,所以我們可以通過控制三級管 的導(dǎo)通或截止,來控制LED的亮與滅! 如果我們把共陰的數(shù)碼管的a-dp依次接到單片機的P0.0-P0.7上,注意:P0口需接上拉電阻。何為上拉電阻,簡單的說,

16、就是把電平拉 高,以提高驅(qū)動能力。那么比如:P0 = 0X3F;則顯示為數(shù)字 0 。因為0X3F 即為2進制的 0011 1111 我們低位往高位數(shù),依次為1111 1100, 其I/O的電平分別為高、高、高、高、高、高、低、低,即對應(yīng)的a-dp 為亮、亮、亮、亮、亮、亮、滅、滅,由上圖我們可以看出g和dp段不 亮其他段均亮,即為我們所看到的數(shù)字 0 字樣。其他的數(shù)字或字符,也同理可以得到。但是有些朋友就會問,那我們每取一個字模,豈不是 很麻煩?還有自己考慮高低電平 . /以下顯示數(shù)字2-F,略。 看到這里,想必大家一定可以把0-F顯示出來了吧!但是如果要你顯示兩位數(shù),三位數(shù)呢?或許,有的朋友

17、會這么想:在P0口上接一個 數(shù)碼管,再在P1口上接個數(shù)碼管!但是,如果要顯示4位、5位的數(shù)字呢?那豈不是一塊AT8951都接不過來!難到就不能接4位或5位以上的嗎? 肯定不是的! 說到這里,我們來講講數(shù)碼管的顯示方式,可分為兩種:動態(tài)掃描和靜態(tài)顯示。上面我們所說的即為靜態(tài)顯示。但是如果我們采用動態(tài)掃 描顯示,那么就可以解決上面的問題,即可以顯示多個數(shù)碼管了。上面我們所說的靜態(tài)顯示把數(shù)碼管的COM腳接至VCC或GND端,其他的接至PX 口上,這樣只要PX口上輸出相應(yīng)的高低電平,就可以顯示對應(yīng)的數(shù)字或字符。但是如果我們采用動態(tài)掃描的方法,比如顯示6個數(shù)碼管,硬件 連接可以這樣解決:a-dp還是接至

18、P0.0-P0.7上,還有6個COM腳再接至另外口的P2.0-P2.5。P0口作段選(控制數(shù)字字符)P2口作位選(選 通哪個數(shù)碼管導(dǎo)通)這樣我們控制P0和P2口就說說51單片機的機器周期和時鐘周期等概念。所謂機器周期就是訪問一次存儲器的時間。而1個機器周期包括12個時鐘周期。如果 單片機工作在12M晶體下,那么一個時鐘周期為:1/12微妙。一個機器周期12*1/12 = 1微妙。如果晶體為6M,時鐘周期和機器周期各是多少呢 ?在匯編中,我們還要關(guān)心,指令執(zhí)行的機器周期長短不一,有1個周期、2個周期和4個周期等。 說著說著,跑了這么遠(yuǎn)了.還是回到原來的話題,如果我們把位選的P2也看作上面的“煙”

19、一劃而過,那么我們看(i = 0; i unsigned char code SEG_TAB =0 x3f,0 x06,0 x5b,0 x4f,0 x66,0 x6d,0 x7d,0 x07,0 x7f,0 x6f; /0-9數(shù)字 void Delay(unsigned int a) /unsigned int 定義為無符整形,取值范圍為0-32768 unsigned char i; while( -a != 0) for(i = 0; i unsigned char hour = 12, min = 0, sec = 0; unsigned char code SEG_TAB = 0 x3

20、f,0 x06,0 x5b,0 x4f,0 x66,0 x6d,0 x7d,0 x07,0 x7f,0 x6f; /0-9數(shù)字 void Delay(unsigned char a) unsigned char i; while( -a != 0) for(i = 0; i TMOD = 00 GATE C/T M1 M0 |_ _| |_ _| | T/C1 | | T/C0 | C/T就是counter(記數(shù)器)和timer(定時器)的選擇位,若值為1,則作計數(shù)器用。為0,則為定時期用!GATE為門控位。M1和M0工作方 式的選擇:若M1=0;M0=0 則為方式0:13位定時/記數(shù)器。若M

21、1=0;M0=1則為方式1,16定時/記數(shù)器。若M1=1;M0=0則為方式2,自動裝載8位 定時/記數(shù)器。若M1=1;M0=1則為方式3,只適用于T/C0,2個8位定時/記數(shù)器。 說了一大堆,感到有點困惑了吧。那我們還是來說說上面的。TMOD= 0X01;/至于為什么是0X01,大家看:我們選擇的是定時器0方式0, 所以T/C1全為0,而T/C0的M1為0。M0為1,所以D0-D7為0X01;0X01表示的是16進制數(shù),這個大家應(yīng)該都知592M那么就不是1了,應(yīng)該是1.085了,那么5000 = 1.085 * C,則C就為5000 / 1.085 = ? 具體多少,大家自己去算算吧?同理TL

22、0也是一樣的! 但是,細(xì)心的朋友會發(fā)現(xiàn)網(wǎng)上或者是資料上的 TH0,TL0并不是和上面一樣的,而是直接TH0 = 0XEC;TL0 = 0X78 是不是和上面的一樣的,別忘了單片機也是計算機的一種哦。用C的話,直 接寫上計算公式就行,計算就交給單片機完成。 TR0 = 1;這句就是啟動定時器0,開始記數(shù)!哦,還有一點,有些朋友會問,你是65536是哪里來的呢?呵呵你可別忘了:設(shè)置定時器0 工作方式0是16位的(2的16次方是多少,自己算算就知道了)簡單吧?但是如何和中斷一起使用呢?請繼續(xù)看下面的講解! TMOD = 0X01;/設(shè)置定時器0 工作方式0 TH0 = (65536 - 5000)

23、/ 256;/載入高8位初值 TL0 = (65536 - 5000) % 256;/載入低8位初值 TR0 = 1; /啟動定時器 536 - 50000) #define M 20 /(1000/25) /*/ unsigned hou = 12, min = 0, sec = 0; unsigned char SEG_TAB_B = 0 xc0,0 xf9,0 xa4,0 xb0,0 x99,0 x92,0 x82,0 xf8,0 x80,0 x90; /0-9數(shù)字 unsigned char SEG_TAB_A = 0 x40,0 x79,0 x24,0 x30,0 x19,0 x12

24、,0 x02,0 x78,0 x00,0 x10;/0.-9.數(shù)字 /*/ void Delay(unsigned char a)/延時程序a*1MS unsigned char j; while(a- != 0) for (j = 0; j static unsigned char count = 0; TR0 = 0; TL0 += (_TH0_TL0_ + 9) % 256; TH0 += (_TH0_TL0_ + 9) / 256 + (char)CY; TR0 = 1; count+; 在中斷處理服務(wù)程序中,我們加入上面的代碼。 TR0 = 0; 先關(guān)閉定時器T0,然后重新給TH0和

25、TL0 賦值,再開啟 TR0 = 1;燒入單片 機看看效果,怎么樣,你第一次精確多了吧。但是還是有誤差!郁悶!為什么呢?那是硬件造成的誤差,我們可以用軟件來彌補!我們先 把時鐘點亮,讓他走上幾個小時或者是幾天,看看到底誤差是多少!取個平均值。(這里比如我們10小時快1秒)那么可以通過以下語句 if(hour % 10 = 0) sec-; 來彌補!這樣可能會出現(xiàn)這樣的現(xiàn)象:秒直接跳變!我們可以再通過細(xì)分來實現(xiàn),不要10小時那么大,小些的就行!具體的操作還是留給 朋友們吧! (七) 這回我們來講講鍵盤,大家肯定見過銀行柜員機吧,取錢輸入密碼就要用到鍵盤,超市購物取回寄存物品要輸入密碼,還有你現(xiàn)在

26、在 用的PC機的鍵盤。但是鍵盤的是怎么工作的呢?一般有2種方式:(1)掃描法,不斷掃描鍵盤的狀態(tài),送CPU判斷并處理。如果鍵盤數(shù)目一 大的話,顯然不適合(2)線反轉(zhuǎn)法,通過行列狀態(tài)的改變來判斷有無鍵被按下! 現(xiàn)在我們在P1口接個4*4的鍵盤,P1.0P1.3接行,P1.4P1.7接列,再接4個4K7的上拉電阻至VCC。代碼如下: /鍵盤掃描法程序 /用數(shù)碼管顯示相應(yīng)的鍵值 /P1.0P1.3接行 /P1.4P1.7接列 #include unsigned char code tab =0 x3F,0 x06,0 x5B,0 x4F, 0 x66,0 x6D,0 x7D,0 x07, 0 x7F

27、,0 x6F,0 x77,0 x7C, 0 x39,0 x5E,0 x79,0 x71;/0到F的16個鍵植 /*/ void Delayt(unsigned char t)/延時函數(shù) unsigned char i; for(t=0;i 1.和掃描法相同,把列線置低電平,行置高,讀行狀態(tài) 2.與1相反,把行置低,列置高,讀列狀態(tài) 3.若有鍵按下,則為2次所讀狀態(tài)的結(jié)果即為鍵所在的位置,這樣2次輸出和2次讀入可以完成鍵的識別! 子函數(shù)如下: unsigned char key_vscan(void) unsigned char row, col; P1 = 0 xF0; row = P1&0 xF0; row = row&0 xF0; P1

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論