版權說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權,請進行舉報或認領
文檔簡介
1、單片機c語言教程第一課 建立你的第一個KeilC51項目 隨著單片機技術的不斷發(fā)展,以單片機C語言為主流的高級語言也不斷被更多的單片機愛好者和工程師所喜愛。使用C51肯定要使用到編譯器,以便把寫好的C程序編譯為機器碼,這樣單片機才能執(zhí)行編寫好的程序。KEIL uVISION2 是眾多單片機應用開發(fā)軟件中優(yōu)秀的軟件之一,它支持眾多不一樣公司的MCS51架構的芯片,它集編輯,編譯,仿真等于一體,同時還支持,PLM,匯編和C語言的程序設計,它的界面和常用的微軟 VC+的界面相似,界面友好,易學易用,在調(diào)試程序,軟件仿真方面也有很強大的功能。本站提供的單片機c語言教程都是基于keilc51的。.下面結
2、合8051介紹單片機C語言的優(yōu)越性: 無須懂得單片機的具體硬件,也能夠編出符合硬件實際的專業(yè)水平的程序;不懂得單片機的指令集,也能夠編寫完美的單片機程序;不同函數(shù)的數(shù)據(jù)實行覆蓋,有效利用片上有限的RAM空間;提供auto、static、const等存儲類型和專門針對8051單片機的data、idata、pdata、xdata、code等存儲類型,自動為變量合理地分配地址;C語言提供復雜的數(shù)據(jù)類型(數(shù)組、結構、聯(lián)合、枚舉、指針等),極大地增強了程序處理能力和靈活性;提供small、compact、large等編譯模式,以適應片上存儲器的大小;中斷服務程序的現(xiàn)場保護和恢復,中斷向量表的填寫,是直接
3、與單片機相關的,都由C編譯器代辦;程序具有堅固性:數(shù)據(jù)被破壞是導致程序運行異常的重要因素。C語言對數(shù)據(jù)進行了許多專業(yè)性的處理,避免了運行中間非異步的破壞提供常用的標準函數(shù)庫,以供用戶直接使用;有嚴格的句法檢查,錯誤很少,可容易地在高級語言的水平上迅速地被排掉;可方便地接受多種實用程序的服務:如片上資源的初始化有專門的實用程序自動生成;再如,有實時多任務操作系統(tǒng)可調(diào)度多道任務,簡化用戶編程,提高運行的安全性等等。頭文件中定義宏、說明復雜數(shù)據(jù)類型和函數(shù)原型,有利于程序的移植和支持單片機的系列化產(chǎn)品的開發(fā);以上簡單介紹了 KEILC51 軟件,要使用KEILC51軟件,必需先要安裝它,這也是學習單片
4、機編程語言所要求的第一步建立學習環(huán)境。本站提供無限制版的keil c51下載(此處)(安裝的方法在壓縮包內(nèi)有詳細說明,這里就不做介紹了)安裝好后,您是不是想建立自己的第一個單片機C語言程序項目呢?下面就讓我們一起來建立一個小程序吧,請根據(jù)教程一步步的來,你絕對可以在短時間內(nèi)熟悉c51的。本教程所涉及c51源代碼請點此下載首先當然是運行KEIL軟件,接著按下面的步驟建立您的第一個項目:(1)點擊 Project 菜單,選擇彈出的下拉式菜單中的 New Project,如圖 1-2。接著彈 出一個標準 Windows 文件對話窗口,如圖 1-3。在“文件名”中輸入您的第一個 C 程序項 目名稱,這
5、里我們用“test”?!氨4妗焙蟮奈募U展名為 uv2,這是 KEIL uVision2 項目文件擴展名,以后能直接點擊此文件以打開先前做的項目。圖 1-2 New Project 菜單圖 1-3 文件窗口(2)選擇所要的單片機,這里選擇常用的 Ateml 公司的 AT89c51。而且本單片機c語言教程里的大部分程序都是基于此芯片的,此時屏幕如圖 1-4 所示。AT89c51 有什么功能、特點呢?看圖中右邊有簡單的介紹。完成上面步驟后,就可 以進行程序的編寫了。(3)首先在項目中創(chuàng)建新的程序文件或加入舊程序文件。如果您沒有現(xiàn)成的程序,那 么就要新建一個程序文件。在 KEIL 中有一些程序的 D
6、emo,在這里我們還是以一個 C 程序 為例介紹如何新建一個 C 程序和如何加到您的第一個項目中吧。點擊圖 1-5 中 1 的新建文 件的快捷按鈕,在 2 中出現(xiàn)一個新的文字編輯窗口,這個操作也能通過菜單 File-New 或 快捷鍵 Ctrl+N 來實現(xiàn)。好了,現(xiàn)在能編寫程序了。下面是經(jīng)典的一段程序,呵,如果您看過別的程序書也許也有類似的程序:#include#includevoid main(void)SCON = 0x50; /串行口方式 1,允許接收TMOD = 0x20; /定時器 1 定時方式 2TCON = 0x40; /設定時器 1 開始計數(shù)TH1 = 0xE8; /11.05
7、92MHz 1200 波特率TL1 = 0xE8; TI = 1;TR1 = 1; /啟動定時器while(1)printf (Hello World!n); /顯示 Hello World圖 1-4 選取芯片圖 1-5 新建程序文件這段程序的功能是不斷從串行口輸出“Hello World!”字符,先不管程序的語法和意思吧,先 看看如何把它加入到項目中和如何編譯試運行。(4)點擊圖 1-5 中的 3 保存新建的程序,也能用菜單 File-Save 或快捷鍵 Ctrl+S進行保存。因是新文件所以保存時會彈出類似圖 1-3 的文件操作窗口,把第一個程序命名為 test1.c,保存在項目所在的目錄中
8、,這個時候您會發(fā)現(xiàn)程序單詞有了不一樣的顏色,說明 KEIL的C語言語法檢查生效了。如圖 1-6 鼠標在屏幕左邊的 Source Group1 文件夾圖標上右擊彈出 菜單,在這里能做在項目中增加減少文件等操作。選“Add File to Group Source Group 1” 彈出文件窗口,選擇剛剛保存的文件,按 ADD 按鈕,關閉文件窗,程序文件已加到項目中了。這個時候在 Source Group1 文件夾圖標左邊出現(xiàn)了一個小+號說明,文件組中有了文件,點擊它能展開查看。圖 1-6 把文件加入到項目文件組中(5)C程序文件已被加到了項目中了,下面就剩下編譯運行了。這個項目只是用做學 習新建
9、程序項目和編譯運行仿真的基本方法,所以使用軟件默認的編譯設置,它不會生成用 于芯片燒寫的 HEX 文件。先來看圖 1-7 吧,圖中 1、2、3 都是編譯按鈕,不一樣是 1 是用 于編譯單個文件。2 是編譯鏈接當前項目,如果先前編譯過一次之后文件沒有做動編輯改動, 這個時候再點擊是不會再次重新編譯的。3 是重新編譯,每點擊一次均會再次編譯鏈接一次,不 管程序是否有改動。在 3 右邊的是停止編譯按鈕,只有點擊了前三個中的任一個,停止按鈕 才會生效。5 是菜單中的它們。在 4 中能看到編譯的錯誤信息和使用的系統(tǒng)資源情況等, 以后我們要查錯就靠它了。6 是有一個小放大鏡的按鈕,這就是開啟關閉調(diào)試模式的
10、按鈕, 它也存在于菜單 Debug-StartStop Debug Session,快捷鍵為 Ctrl+F5。圖 1-7 編譯程序(6)進入調(diào)試模式,軟件窗口樣式大致如圖 1-8 所示。圖中 1 為運行,當程序處于停止 狀態(tài)時才有效,2 為停止,程序處于運行狀態(tài)時才有效。3 是復位,模擬芯片的復位,程序 回到最開頭處執(zhí)行。按 4 能打開 5 中的串行調(diào)試窗口,這個窗口能看到從 51 芯片的串 行口輸入輸出的字符,這里的第一個項目也正是在這里看運行結果。這些在菜單中也有。首 先按 4 打開串行調(diào)試窗口,再按運行鍵,這個時候就能看到串行調(diào)試窗口中不斷的打印“Hello World!”。最后要停止程
11、序運行回到文件編輯模式中,就要先按停止按鈕再按開啟關閉調(diào)試 模式按鈕。然后就能進行關閉 KEIL 等相關操作了。圖 1-8 調(diào)試運行程序sylar源于heroslize314于2010-05-06給此貼評了10分 看推薦視頻,得100元卓越禮品券 回復 回復本帖 回到頂端 單片機c語言教程第二課 C51HEX文件的生成和單片機最小系統(tǒng)發(fā)表于 2009-07-30 15:03:51我想評分2樓sylar我是MM 高級會員用戶等級:院士加為好友 發(fā)短消息所有發(fā)言 個人檔案最后登陸時間:2010-06-04 08:20:15狀態(tài):離線 上一篇建立了第一個單片機C語言項目,但為了讓編譯好的程序能通過編
12、程器寫入51芯 片中,要先用編譯器生成HEX文件,下面來看看如何用KEIL uVISION2來編譯生成用于燒寫 芯片的HEX文件。HEX文件格式是Intel公司提出的按地址排列的數(shù)據(jù)信息,數(shù)據(jù)寬度為字 節(jié),所有數(shù)據(jù)使用16進制數(shù)字表示, 常用來保存單片機或其他處理器的目標程序代碼。它保 存物理程序存儲區(qū)中的目標代碼映象。一般的編程器都支持這種格式。我們先來打開第一個 項目,打開它的所在目錄,找到test.Uv2的文件就能打開先前的項目了。然后右擊圖2-1 中的1項目文件夾,彈出項目功能菜單,選Options for TargetTarget1,彈出項目選項設置窗口, 同樣先選中項目文件夾圖標,
13、這個時候在Project菜單中也有一樣的菜單可選。打開項目選項窗口, 轉(zhuǎn)到Output選項頁圖2-2所示,圖中1是選擇編譯輸出的路徑,2是設置編譯輸出生成的文件 名,3則是決定是否要創(chuàng)建HEX文件,選中它就能輸出HEX文件到指定的路徑中。選好了? 好,我們再將它重新編譯一次,很快在編譯信息窗口中就顯示HEX文件創(chuàng)建到指定的路徑 中了,如圖2-3。這樣我們就可用自己的編程器所附帶的軟件去讀取并燒到芯片了,再用實 驗板看結果,至于編程器或仿真器品種繁多具體方法就看它的說明書了,這里也不做討論。(技巧:一、在圖2-1中的1里的項目文件樹形目錄中,先選中對象,再單擊它就可對它進 行重命名操作,雙擊文件
14、圖標便可打開文件。二、在Project下拉菜單的最下方有最近編輯過的項目路徑保存,這里能快速打開最近在編輯的項目。)圖2-1項目功能菜單圖2-2 項目選項窗口圖 2-3 編譯信息窗口或許您已把編譯好的文件燒到了芯片上,如果您購買或自制了帶串行口輸出元件的學習實 驗板,那您就能把串行口和 PC 機串行口相聯(lián)用串行口調(diào)試軟件或 Windows 的超級終端,將其波特 率設為 1200,就能看到不停輸出的“Hello World!”字樣。如果您還沒有實驗板,那這 里先說說 AT89c51 的最小化系統(tǒng),再以一實例程序驗證最小化系統(tǒng)是否在運行,這個最小化 系統(tǒng)也易于自制用于實驗。圖 2-4 便是 AT8
15、9c51 的最小化系統(tǒng),不過為了讓我們能看出它 是在運行的,加了一個電阻和一個 LED,用以顯示它的狀態(tài),晶體震蕩器能根據(jù)自己的情況使用, 一般實驗板上是用 11.0592MHz 或 12MHz,使用前者的好外是能產(chǎn)生標準的串行口波特率,后 者則一個機器周期為 1 微秒,便于做精確定時。在自己做實驗里,注意的是 VCC 是+5V 的, 不能高于此值,不然將損壞單片機,太低則不能正常工作。在 31 腳要接高電平,這樣我們 才能執(zhí)行片內(nèi)的程序,如接低電平則使用片外的程序存儲器。下面建一個新的項目名為 OneLED 來驗證最小化系統(tǒng)是否能工作(所有的例程都可在筆者的主頁下面下載到,網(wǎng)址: 。程序如下
16、:#include /預處理命令void main(void) /主函數(shù)名/這是第一種注釋方式unsigned int a; /定義變量 a 為 int 類型/* 這是第二種注釋方式*/do /do while 組成循環(huán)for (a=0; a50000; a+); /這是一個循環(huán) P1_0 = 0; /設 P1.0 口為低電平,點亮 LED for (a=0; a50000; a+); /這是一個循環(huán) P1_0 = 1; /設 P1.0 口為高電平,熄滅 LEDwhile(1);圖 2-4 AT89c51 最小化系統(tǒng)這里先講講 KEIL C 編譯器所支持的注釋語句。一種是以“/”符號開始的語句
17、,符號之后 的語句都被視為注釋,直到有回車換行。另一種是在“/*”和“*/”符號之內(nèi)的為注釋。注 釋不會被 C 編譯器所編譯。一個 C 應用程序中應有一個 main 主函數(shù),main 函數(shù)能調(diào)用別的功能函數(shù),但其它功能函數(shù)不允許調(diào)用 main 函數(shù)。不論 main 函數(shù)放在程序中的那個位置, 總是先被執(zhí)行。用上面學到的知識編譯寫好的 OneLED 程序,并把它燒到剛做好的最小化系 統(tǒng)中。上電,剛開始時 LED 是不亮的(因為上電復位后所有的 IO 口都置 1 引腳為高電平), 然后延時一段時間(for (a=0; a50000; a+)這句在運行),LED 亮,再延時,LED 熄滅, 然后交替
18、亮、滅。第一個真正的小實驗就做完,如果沒有這樣的效果那么您就要認真檢查一下電路或編譯燒寫的步驟了。sylar源于heros 了解更多電源解決方案 回復 回復本帖 回到頂端 單片機c語言教程第三課 C51數(shù)據(jù)類型發(fā)表于 2009-07-30 15:04:52我想評分3樓sylar我是MM 高級會員用戶等級:院士加為好友 發(fā)短消息所有發(fā)言 個人檔案最后登陸時間:2010-06-04 08:20:15狀態(tài):離線 每寫一個程序,總離不開數(shù)據(jù)的應用,在學習 c51 語言的過程中掌握理解數(shù)據(jù)類型也是 很關鍵的。先看表 31,表中列出了 KEIL uVision2 單片機c語言編譯器所支持的數(shù)據(jù)類型。在標準
19、C語言中基本的數(shù)據(jù)類型為 char,int,short,long,float 和 double,而在c51編譯器中int 和 short 相同,float 和 double 相同,這里就不列出說明了。下面來看看它們的具體定 義:數(shù)據(jù)類型長 度值 域unsigned char單字節(jié)0255signed char單字節(jié)-128+127unsigned int雙字節(jié)065535signed int雙字節(jié)-32768+32767unsigned long四字節(jié)0signed long四字節(jié)-+float四字節(jié)1.E-383.E+38*13 字節(jié)對象的地址bit位0 或 1sfr單字節(jié)0255sfr16
20、雙字節(jié)065535sbit位0 或 1表 31 KEIL uVision2 單片機c語言編譯器所支持的數(shù)據(jù)類型1 char 字符類型char 類型的長度是一個字節(jié),通常用于定義處理字符數(shù)據(jù)的變量或常量。分無符號字 符類型 unsigned char 和有符號字符類型 signed char,默認值為 signed char 類型。 unsigned char 類型用字節(jié)中所有的位來表示數(shù)值,所能表達的數(shù)值范圍是 0255。 signed char 類型用字節(jié)中最高位字節(jié)表示數(shù)據(jù)的符號,“0”表示正數(shù),“1”表示負數(shù), 負數(shù)用補碼表示。所能表示的數(shù)值范圍是-128+127。unsigned ch
21、ar 常用于處理 ASCII 字符或用于處理小于或等于 255 的整型數(shù)。正數(shù)的補碼與原碼相同,負二進制數(shù)的補碼等于它的絕對值按位取反后加 1。2 int 整型int 整型長度為兩個字節(jié),用于存放一個雙字節(jié)數(shù)據(jù)。分有符號 int 整型數(shù) signed int 和無符號整型數(shù) unsigned int,默認值為 signed int 類型。signed int 表示的數(shù)值范 圍是-32768+32767,字節(jié)中最高位表示數(shù)據(jù)的符號,“0”表示正數(shù),“1”表示負數(shù)。 unsigned int 表示的數(shù)值范圍是 065535。先停一下來寫個小程序看看 unsigned char 和 unsigned
22、 int 用于延時的不一樣效果,說 明它們的長度是不一樣的,學習它們的使用方法。依舊用上一篇的最小化系統(tǒng)做實驗,不過要加多 一個電阻和 LED,如圖 31。實驗中用 D1 的點亮表明正在用 unsigned int 數(shù)值延時,用D2 點亮表明正在用 unsigned char 數(shù)值延時。圖 31 第 3 課實驗用電路 把這個項目稱為 TwoLED,實驗程序如下:#include /預處理命令void main(void) /主函數(shù)名unsigned int a; /定義變量 a 為 unsigned int 類型unsigned char b; /定義變量 b 為 unsigned char
23、類型do /do while 組成循環(huán)for (a=0; a65535; a+)P1_0 = 0; /65535 次設 P1.0 口為低電平,點亮 LED P1_0 = 1; /設 P1.0 口為高電平,熄滅 LEDfor (a=0; a30000; a+); /空循環(huán)for (b=0; b255; b+)P1_1 = 0; /255 次設 P1.1 口為低電平,點亮 LED P1_1 = 1; /設 P1.1 口為高電平,熄滅 LEDfor (a=0; a30000; a+); /空循環(huán)while(1);同樣編譯燒寫,上電運行您就能看到結果了。很明顯 D1 點亮的時間長于 D2 點亮的時間。
24、這里必須要講的是,當定義一個變量為特定的數(shù)據(jù)類型時,在程序使用該變量不應使它的值 超過數(shù)據(jù)類型的值域。如本例中的變量 b 不能賦超出 0255 的值,如 for (b=0; b255; b+) 改為 for (b=0; b256; b+),編譯是能通過的,但運行時就會有問題出現(xiàn),就是說 b 的 值永遠都是小于 256 的,所以無法跳出循環(huán)執(zhí)行下一句 P1_1 = 1,從而造成死循環(huán)。同理 a 的值不應超出 065535。3 long 長整型long 長整型長度為四個字節(jié),用于存放一個四字節(jié)數(shù)據(jù)。分有符號 long 長整型 signed long 和無符號長整型 unsigned long,默認
25、值為 signed long 類型。signed int 表示 的數(shù)值范圍是-+,字節(jié)中最高位表示數(shù)據(jù)的符號,“0”表示正 數(shù),“1”表示負數(shù)。unsigned long 表示的數(shù)值范圍是 0。4 float 浮點型float 浮點型在十進制中具有 7 位有效數(shù)字,是符合 IEEE754 標準的單精度浮點型數(shù) 據(jù),占用四個字節(jié)。因浮點數(shù)的結構較復雜在以后的章節(jié)中再做詳細的討論。5* 指針型 指針型本身就是一個變量,在這個變量中存放的指向另一個數(shù)據(jù)的地址。這個指針變量 要占據(jù)一定的內(nèi)存單元,對不一樣的處理器長度也不盡相同,在 c51 中它的長度一般為 13 個字節(jié)。指針變量也具有類型,在以后的課
26、程中有專門一課做探討,這里就不多說了。6 bit 位標量bit 位標量是 c51 編譯器的一種擴充數(shù)據(jù)類型,利用它可定義一個位標量,但不能定義 位指針,也不能定義位數(shù)組。它的值是一個二進制位,不是 0 就是 1,類似一些高級語 言中的 Boolean 類型中的 True 和 False。7 sfr 特殊功能寄存器sfr 也是一種擴充數(shù)據(jù)類型,點用一個內(nèi)存單元,值域為 0255。利用它能訪問 51 單片機內(nèi)部的所有特殊功能寄存器。如用 sfr P1 = 0x90 這一句定 P1 為 P1 端口在片內(nèi) 的寄存器,在后面的語句中用以用 P1 = 255(對 P1 端口的所有引腳置高電平)之類的 語句
27、來操作特殊功能寄存器。8sfr16 16 位特殊功能寄存器sfr16 占用兩個內(nèi)存單元,值域為 065535。sfr16 和 sfr 一樣用于操作特殊功能寄存 器,所不一樣的是它用于操作占兩個字節(jié)的寄存器,如定時器 T0 和 T1。9 sbit 可錄址位sbit 同樣是 單片機c語言 中的一種擴充數(shù)據(jù)類型,利用它能訪問芯片內(nèi)部的 RAM 中的可尋址位或特殊功能寄存器中的可尋址位。如先前定義了sfr P1 = 0x90; /因 P1 端口的寄存器是可位尋址的,所以能定義sbit P1_1 = P11; /P1_1 為 P1 中的 P1.1 引腳/同樣我們能用 P1.1 的地址去寫,如 sbit
28、P1_1 = 0x91; 這樣在以后的程序語句中就能用 P1_1 來對 P1.1 引腳進行讀寫操作了。通常這些能 直接使用系統(tǒng)供給的預處理文件,里面已定義好各特殊功能寄存器的簡單名字,直接引 用能省去一點時間,我自己是一直用的。當然您也能自己寫自己的定義文件,用您 認為好記的名字。sylar源于heros 提高空載性能,降低待機功耗并提升輕載效率 回復 回復本帖 回到頂端 單片機c語言教程第四課 C51常量發(fā)表于 2009-07-30 15:05:41我想評分4樓sylar我是MM 高級會員用戶等級:院士加為好友 發(fā)短消息所有發(fā)言 個人檔案最后登陸時間:2010-06-04 08:20:15狀
29、態(tài):離線 上一篇學習了 KEIL c 單片機c語言 編譯器所支持的數(shù)據(jù)類型。而這些c51數(shù)據(jù)類型又是怎么用在常量和變量的定義中的呢?又有什么要注意的嗎?常量就是在程序運行過程中不能改變值的量,而變量是能在程序運行過程中不斷變化的量。變量的定義能使用所有c51編譯器支持的數(shù)據(jù)類型,而常量的數(shù)據(jù)類型只有整型、浮點型、字符型、字符串型和位標量。這一篇學習常量定義和使用方法,而下一篇則學習單片機c語言的變量。常量的數(shù)據(jù)類型說明是這樣的1 整型常量能表示為十進制如 123,0,89 等。十六進制則以 0x 開頭如 0x34,-0x3B 等。長整型就在數(shù)字后面加字母 L,如 104L,034L,0xF34
30、0 等。2 浮點型常量可分為 十進 制和指數(shù)表示形式 。十 進制由數(shù)字和小數(shù)點組成,如0.888,3345.345,0.0 等,整數(shù)或小數(shù)部分為 0,能省略但必須有小數(shù)點。指數(shù)表 示形式為數(shù)字.數(shù)字e數(shù)字,中的內(nèi)容為可選項,其中內(nèi)容根據(jù)具體情 況可有可無,但其余部分必須有,如125e3,7e9,-3.0e-3。3 字符型常量是單引號內(nèi)的字符,如a,d等,不能顯示的控制字符,能 在該字符前面加一個反斜杠“”組成專用轉(zhuǎn)義字符。常用轉(zhuǎn)義字符表請看表 41。4 字符串型常量由雙引號內(nèi)的字符組成,如“test”,“OK”等。當引號內(nèi)的沒有字 符時,為空字符串。在使用特殊字符時同樣要使用轉(zhuǎn)義字符如雙引號。
31、在 C 中字符 串常量是做為字符類型數(shù)組來處理的,在存儲字符串時系統(tǒng)會在字符串尾部加上o 轉(zhuǎn)義字符以作為該字符串的結束符。字符串常量“A”和字符常量A是不一樣的, 前者在存儲時多占用一個字節(jié)的字間。5 位標量,它的值是一個二進制。轉(zhuǎn)義字符含義ASCII 碼(16/10 進制)o空字符(NULL)00H/0n換行符(LF)0AH/10r回車符(CR)0DH/13t水平制表符(HT)09H/9b退格符(BS)08H/8f換頁符(FF)0CH/12單引號27H/39雙引號22H/34反斜杠5CH/92表 41 常用轉(zhuǎn)義字符表常量可用在不必改變值的場合,如固定的數(shù)據(jù)表,字庫等。常量的定義方式有幾種,下
32、 面來加以說明。#difine False 0x0; /用預定義語句能定義常量#difine True 0x1; /這里定義 False 為 0,True 為 1/在程序中用到 False 編譯時自動用 0 替換,同理 True 替換為 1unsigned int code a=100; /這一句用 code 把 a 定義在程序存儲器中并賦值const unsigned int c=100; /用 const 定義 c 為無符號 int 常量并賦值 以上兩句它們的值都保存在程序存儲器中,而程序存儲器在運行中是不允許被修改的,所以如果在這兩句后面用了類似 a=110,a+這樣的賦值語句,編譯時將
33、會出錯。下面寫個跑馬燈程序來實驗一下典型的常量使用方法。先來看看電路圖吧。它是在上一篇的實驗電路的基礎上增加幾個 LED 組成的,也就是用 P1 口的全部引腳分別驅(qū)動一個 LED,電 路如圖 41 所示。新建一個 RunLED 的項目,主程序如下:#include /預處理文件里面定義了特殊寄存器的名稱如 P1 口定義為 P1void main(void)/定義花樣數(shù)據(jù)const unsigned char design32=0xFF,0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0x7F,0x7F,0xBF,0xDF,0xEF,0xF7,0xFB,0xFD,0xFE,
34、0xFF,0xFF,0xFE,0xFC,0xF8,0xF0,0xE0,0xC0,0x80,0x0,0xE7,0xDB,0xBD,0x7E,0xFF;unsigned int a; /定義循環(huán)用的變量unsigned char b; /在 c51 編程中因內(nèi)存有限盡可能注意變量類型的使用/盡可能使用少字節(jié)的類型,在大型的程序中很受用dofor (b=0; b32; b+)while(1);for(a=0; a30000; a+); /延時一段時間P1 = designb; /讀已定義的花樣數(shù)據(jù)并寫花樣數(shù)據(jù)到 P1 口程序中的花樣數(shù)據(jù)能自以去定義,因這里我們的 LED 要 AT89c51 的 P1
35、 引腳為低電平才 會點亮,所以我們要向 P1 口的各引腳寫數(shù)據(jù) O 對應連接的 LED 才會被點亮,P1 口的八個引 腳剛好對應 P1 口特殊寄存器的八個二進位,如向 P1 口定數(shù)據(jù) 0xFE,轉(zhuǎn)成二進制就是,最低位 D0 為 0 這里 P1.0 引腳輸出低電平,LED1 被點亮。如此類推,大家不難算 出自己想要做的效果了。大家編譯燒寫看看,效果就出來,顯示的速度您能根據(jù)需要調(diào)整 延時 a 的值,不要超過變量類型的值域就很行了。哦,您還沒有實驗板?那如何能知道程 序運行的結果呢?呵,不用急,這就來說說用 KEIL uVision2 的軟件仿真來調(diào)試 IO 口輸出輸入程序。圖 41 八路跑馬燈電
36、路 編譯運行上面的程序,然后按外部設備菜單 PeripheralsI/O PortsPort1 就打開Port1 的調(diào)試窗口了,如圖 43 中的 2。這個時候程序運行了,但我們并不能在 Port1 調(diào)試窗口 上看到有會什么效果,這個時候能用鼠標左擊圖 43 中 1 旁邊綠色的方條,點一下就有一個 小紅方格再點一下又沒有了,哪一句語句前有小方格程序運行到那一句時就停止了,就是設 置調(diào)試斷點,同樣圖 42 中的 1 也是同樣功能,分別是增加/移除斷點、移除所有斷點、允 許/禁止斷點、禁止所有斷點,菜單也有一樣的功能,另外菜單中還有 Breakpoints 可打開 斷點設置窗口它的功能更強大,不過這
37、里先不用它。在“P1 = designb;”這一句設置一 個斷點這個時候程序運行到這里就停住了,再留意一下 Port1 調(diào)試窗口,再按圖 5-2 中的 2 的運 行鍵,程序又運行到設置斷點的地方停住了,這個時候 Port1 調(diào)試窗口的狀態(tài)又不一樣了。也就是說 Port1 調(diào)試窗口模擬了 P1 口的電平狀態(tài),打勾為高電平,不打勾則為低電平,窗口中 P1為 P1 寄存器的狀態(tài),Pins 為引腳的狀態(tài),注意的是如果是讀引腳值之前必須把引腳對應的 寄存器置 1 才能正確讀取。圖 42 中 2 旁邊的樣的按鈕分別為單步入,步越,步出和 執(zhí)行到當前行。圖中 3 為顯示下一句將要執(zhí)行的語句。圖 43 中的
38、3 是 Watches 窗口可查 看各變量的當前值,數(shù)組和字串是顯示其頭一個地址,如本例中的 design 數(shù)組是保存在 code 存儲區(qū)的首地址為 D:0x08,能在圖中 4 Memory 存儲器查看窗口中的 Address 地址中打入 D:0x08 就能查看到 design 各數(shù)據(jù)和存放地址了。如果你的 uVision2 沒有顯示這些窗口, 能在 View 菜單中打開在圖 42 中 3 后面一欄的查看窗口快捷欄中打開。圖 42 調(diào)試用快捷菜單欄圖 43 各調(diào)試窗口sylar源于heros 提高空載性能,降低待機功耗并提升輕載效率 回復 回復本帖 回到頂端 單片機c語言教程第五課 C51變量
39、發(fā)表于 2009-07-30 15:07:49我想評分5樓sylar我是MM 高級會員用戶等級:院士加為好友 發(fā)短消息所有發(fā)言 個人檔案最后登陸時間:2010-06-04 08:20:15狀態(tài):離線 上課所提到變量就是一種在程序執(zhí)行過程中其值能不斷變化的量。要在程序中使用變量必須先用標識符作為變量名,并指出所用的數(shù)據(jù)類型和存儲模式,這樣編譯系統(tǒng)才能為變量分配相應的存儲空間。定義一個變量的格式如下:存儲種類數(shù)據(jù)類型存儲器類型變量名表在定義格式中除了數(shù)據(jù)類型和變量名表是必要的,其它都是可選項。存儲種類有四種:自動(auto),外部(extern),靜態(tài)(static)和寄存器(register),
40、缺省類型為自動(auto)。這些存儲種類的具體含義和使用方法,將在第七課變量的存儲中進一步進行學習。而這里的數(shù)據(jù)類型則是和我們在第四課中學習到的名種數(shù)據(jù)類型的定義是一樣的。說明了一個變量的數(shù)據(jù)類型后,還可選擇說明該變量的存儲器類型。存儲器類型的說明就是指定該變量在單片機c語言硬件系統(tǒng)中所使用的存儲區(qū)域,并在編譯時準確的定位。表61中是KEIL uVision2所能認別的存儲器類型。注意的是在AT89c51芯片中RAM只有低128位,位于80H到FFH的高128位則在52芯片中才有用,并和特殊寄存器地址重疊。特殊寄存器(SFR)的地址表請看附錄二AT89c51特殊功能寄存器列表表61存儲器類型存
41、儲器類型說明data直接訪問內(nèi)部數(shù)據(jù)存儲器(128字節(jié)),訪問速度最快bdata可位尋址內(nèi)部數(shù)據(jù)存儲器(16字節(jié)),允許位與字節(jié)混合訪問idata間接訪問內(nèi)部數(shù)據(jù)存儲器(256字節(jié)),允許訪問全部內(nèi)部地址pdata分頁訪問外部數(shù)據(jù)存儲器(256字節(jié)),用MOVX Ri指令訪問xdata外部數(shù)據(jù)存儲器(64KB),用MOVX DPTR指令訪問code程序存儲器(64KB),用MOVC A+DPTR指令訪問如果省略存儲器類型,系統(tǒng)則會按編譯模式SMALL,COMPACT或LARGE所規(guī)定的默認存儲器類型去指定變量的存儲區(qū)域。無論什么存儲模式都能聲明變量在任何的8051存儲區(qū)范圍,然而把最常用的命令
42、如循環(huán)計數(shù)器和隊列索引放在內(nèi)部數(shù)據(jù)區(qū)能顯著的提高系統(tǒng)性能。還有要指出的就是變量的存儲種類與存儲器類型是完全無關的。. 數(shù)據(jù)存儲模式存儲模式?jīng)Q定了沒有明確指定存儲類型的變量,函數(shù)參數(shù)等的缺省存儲區(qū)域,共三種:1. 1. Small模式所有缺省變量參數(shù)均裝入內(nèi)部RAM,優(yōu)點是訪問速度快,缺點是空間有限,只適用于小程序。2. 2. Compact模式所有缺省變量均位于外部RAM區(qū)的一頁(256Bytes),具體哪一頁可由P2口指定,在STARTUP.A51文件中說明,也可用pdata指定,優(yōu)點是空間較Small為寬裕速度較Small慢,較large要快,是一種中間狀態(tài)。3. 3. large模式所有
43、缺省變量可放在多達64KB的外部RAM區(qū),優(yōu)點是空間大,可存變量多,缺點是速度較慢。提示:存儲模式在單片機c語言編譯器選項中選擇。之前提到簡單提到sfr,sfr16,sbit定義變量的方法,下面我們再來仔細看看。sfr和sfr16能直接對51單片機的特殊寄存器進行定義,定義方法如下:sfr 特殊功能寄存器名= 特殊功能寄存器地址常數(shù);sfr16 特殊功能寄存器名= 特殊功能寄存器地址常數(shù);我們能這樣定義AT89c51的P1口sfr P1 = 0x90; /定義P1 I/O口,其地址90Hsfr關鍵定后面是一個要定義的名字,可任意選取,但要符合標識符的命名規(guī)則,名字最好有一定的含義如P1口能用P
44、1為名,這樣程序會變的好讀好多。等號后面必須是常數(shù),不允許有帶運算符的表達式,而且該常數(shù)必須在特殊功能寄存器的地址范圍之內(nèi)(80HFFH),具體可查看附錄中的相關表。sfr是定義8位的特殊功能寄存器而sfr16則是用來定義16位特殊功能寄存器,如8052的T2定時器,能定義為:sfr16 T2 = 0xCC; /這里定義8052定時器2,地址為T2L=CCH,T2H=CDH用sfr16定義16位特殊功能寄存器時,等號后面是它的低位地址,高位地址一定要位于物理低位地址之上。注意的是不能用于定時器0和1的定義。sbit可定義可位尋址對象。如訪問特殊功能寄存器中的某位。其實這樣應用是經(jīng)常要用的如要訪
45、問P1口中的第2個引腳P1.1。我們能照以下的方法去定義:(1)sbit 位變量名位地址 sbit P1_1 = Ox91;這樣是把位的絕對地址賦給位變量。同sfr一樣sbit的位地址必須位于80H-FFH之間。(2)Sbit 位變量名特殊功能寄存器名位位置sft P1 = 0x90;sbit P1_1 = P1 1; /先定義一個特殊功能寄存器名再指定位變量名所在的位置當可尋址位位于特殊功能寄存器中時可采用這種方法(3)sbit 位變量名字節(jié)地址位位置sbit P1_1 = 0x90 1;這種方法其實和2是一樣的,只是把特殊功能寄存器的位址直接用常數(shù)表示。在單片機c語言存儲器類型中供給有一個
46、bdata的存儲器類型,這個是指可位尋址的數(shù)據(jù)存儲器,位于單片機的可位尋址區(qū)中,能將要求可位錄址的數(shù)據(jù)定義為bdata,如:unsigned char bdata ib; /在可位錄址區(qū)定義ucsigned char類型的變量ibint bdata ab2; /在可位尋址區(qū)定義數(shù)組ab2,這些也稱為可尋址位對象sbit ib7=ib7 /用關鍵字sbit定義位變量來獨立訪問可尋址位對象的其中一位sbit ab12=ab112;操作符后面的位位置的最大值取決于指定的基址類型,char0-7,int0-15,long0-31。下面我們用上一課的電路來實踐一下這一課的知識。同樣是做一下簡單的跑馬燈實
47、驗,項目名為RunLED2。程序如下:sfr P1 = 0x90; /這里沒有使用預定義文件,sbit P1_0 = P1 0; /而是自己定義特殊寄存器sbit P1_7 = 0x90 7; /之前我們使用的預定義文件其實就是這個作用sbit P1_1 = 0x91; /這里分別定義P1端口和P10,P11,P17引腳void main(void)unsigned int a;unsigned char b;dofor (a=0;a50000;a+)P1_0 = 0; /點亮P1_0for (a=0;a50000;a+)P1_7 = 0; /點亮P1_7for (b=0;b255;b+)fo
48、r (a=0;a10000;a+)P1 = b; /用b的值來做跑馬燈的花樣P1 = 255; /熄滅P1上的LEDfor (b=0;b255;b+)for (a=0;a10000;a+) /P1_1閃爍P1_1 = 0;for (a=0;a10000;a+)P1_1 = 1;while(1);. Keil c51指針變量單片機c語言支持一般指針(Generic Pointer)和存儲器指針(Memory_Specific Pointer).1. 1. 一般指針一般指針的聲明和使用均與標準C相同,不過同時還能說明指針的存儲類型,例如:long * state;為一個指向long型整數(shù)的指針,而
49、state本身則依存儲模式存放。char * xdata ptr;ptr為一個指向char數(shù)據(jù)的指針,而ptr本身放于外部RAM區(qū),以上的long,char等指針指向的數(shù)據(jù)可存放于任何存儲器中。一般指針本身用3個字節(jié)存放,分別為存儲器類型,高位偏移,低位偏移量。2. 2. 存儲器指針基于存儲器的指針說明時即指定了存貯類型,例如:char data * str;str指向data區(qū)中char型數(shù)據(jù)int xdata * pow; pow指向外部RAM的int型整數(shù)。這種指針存放時,只需一個字節(jié)或2個字節(jié)就夠了,因為只需存放偏移量。3. 3. 指針轉(zhuǎn)換即指針在上兩種類型之間轉(zhuǎn)化:l 當基于存儲器的
50、指針作為一個實參傳遞給需要一般指針的函數(shù)時,指針自動轉(zhuǎn)化。l 如果不說明外部函數(shù)原形,基于存儲器的指針自動轉(zhuǎn)化為一般指針,導致錯誤,因而請用“include”說明所有函數(shù)原形。l 能強行改變指針類型。變量的存儲類別一、static(靜態(tài)局部)變量。1、靜態(tài)局部變量在程序整個運行期間都不會釋放內(nèi)存。2、對于靜態(tài)局部變量,是在編譯的時候賦初值的,即只賦值一次。如果在程序運行時已經(jīng)有初值,則以后每次調(diào)用的時候不再重新賦值。3、如果定義局部變量的時候不賦值,則編譯的時候自動賦值為0。而對于自動變量而言,定義的時候不賦值,則是一個不確定的值。4、雖然靜態(tài)變量在函數(shù)調(diào)用結束后仍然存在,但是其他函數(shù)不能引用
51、。二、用extern聲明外部變量。用extern聲明外部變量,是為了擴展外部變量的作用范圍。比如一個程序能由多個源程序文件組成。如果一個程序中需要引用另外一個文件中已經(jīng)定義的外部變量,就需要使用extern來聲明。正確的做法是在一個文件中定義外部變量,而在另外一個文件中使用extern對該變量作外部變量聲明。一個文件中: int abc;另外一個文件中: extern abc;例子:用extern將外部變量的作用域擴展到其他文件:文件1:/用extern將外部變量的作用域擴展到其他文件中#include#include#includeunsigned int array10;void fill
52、array();void init_ser()SCON=0X50;TMOD|=0X20;TH1=0XF3;TR1=1;TI=1;void main()unsigned int i;init_ser();fillarray();for(i=0;i10;i+)printf(array%d=%dn,i,arrayi);for(;);文件2:extern int array10;void fillarray()unsigned char i;for(i=0;i10;i+)arrayi=i;在單片機c語言中變量的空間分配幾個方法1、 data區(qū)空間小,所以只有頻繁用到或?qū)\算速度要求很高的變量才放到da
53、ta區(qū)內(nèi),比如for循環(huán)中的計數(shù)值。2、 data區(qū)內(nèi)最好放局部變量。因為局部變量的空間是能覆蓋的某個函數(shù)的局部變量空間在退出該函數(shù)是就釋放,由別的函數(shù)的局部變量覆蓋),能提高內(nèi)存利用率。當然靜態(tài)局部變量除外,其內(nèi)存使用方式與全局變量相同;3、 確保你的程序中沒有未調(diào)用的函數(shù)。在Keil C里遇到未調(diào)用函數(shù),編譯器就將其認為可能是中斷函數(shù)。函數(shù)里用的局部變量的空間是不釋放,也就是同全局變量一樣處理。這一點Keil C做得很愚蠢,但也沒辦法。4、 程序中遇到的邏輯標志變量能定義到bdata中,能大大降低內(nèi)存占用空間。在51系列芯片中有16個字節(jié)位尋址區(qū)bdata,其中能定義8*16=128個邏輯
54、變量。定義方法是: bdata bit LedState;但位類型不能用在數(shù)組和結構體中。5、 其他不頻繁用到和對運算速度要求不高的變量都放到xdata區(qū)。6、 如果想節(jié)省data空間就必須用large模式,將未定義內(nèi)存位置的變量全放到xdata區(qū)。當然最好對所有變量都要指定內(nèi)存類型。7、 當使用到指針時,要指定指針指向的內(nèi)存類型。在單片機c51語言中未定義指向內(nèi)存類型的通用指針占用3個字節(jié);而指定指向data區(qū)的指針只占1個字節(jié);指定指向xdata區(qū)的指針占2個字節(jié)。如指針p是指向data區(qū),則應定義為: char data *p;。還可指定指針本身的存放內(nèi)存類型,如:char data * xdata p;。其含義是指針p指向data區(qū)變量,而其本身存放在xdata區(qū)。sylar源于heros 看推薦視頻,得100元卓越禮品券 回復 回復本帖 回到
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經(jīng)權益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
- 6. 下載文件中如有侵權或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 水粉煙花課件教學課件
- 出游應急預案
- 旅游業(yè)安全規(guī)范解析
- 2024年大型并網(wǎng)風力發(fā)電機組發(fā)電機項目資金需求報告代可行性研究報告
- 物業(yè)小區(qū)危險源識別
- 吉林省2024七年級數(shù)學上冊第1章有理數(shù)1.7有理數(shù)的減法課件新版華東師大版
- 彩色的雨教案反思
- 建筑業(yè)薪酬政策
- 林業(yè)安防施工合同
- 影視制作薪酬管理
- 小學語文古詩詞教學探究的開題報告
- 動靜脈內(nèi)瘺栓塞的原因分析及干預措施課件
- 小學一年級10以內(nèi)加減法口訣表
- 換熱站的安裝調(diào)試
- 幼兒園中班數(shù)學鮮花分一分教案ppt【幼教課件】
- 防洪評價課件
- 普通地質(zhì)學教材
- 我的連衣裙【經(jīng)典繪本】
- 農(nóng)村公路暢通工程質(zhì)量檢測方案第三方檢測及交工驗收
- 急性冠脈綜合征特殊人群抗血小板治療中國專家建議解讀
- 1 220kV外護套電纜試驗報告
評論
0/150
提交評論