PIC單片機(jī)C語(yǔ)言編程教程_第1頁(yè)
PIC單片機(jī)C語(yǔ)言編程教程_第2頁(yè)
PIC單片機(jī)C語(yǔ)言編程教程_第3頁(yè)
PIC單片機(jī)C語(yǔ)言編程教程_第4頁(yè)
PIC單片機(jī)C語(yǔ)言編程教程_第5頁(yè)
已閱讀5頁(yè),還剩61頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡(jiǎn)介

1、PIC單片機(jī)c語(yǔ)言編程簡(jiǎn)介用C語(yǔ)言來(lái)開(kāi)發(fā)迪11系統(tǒng)軟件最大的好處是編'弓代碼效率高、軟件調(diào)試直觀、維護(hù)升級(jí)方便、代碼的乘復(fù)利用率商、便于跨平臺(tái)的代碼移植等等,因此C語(yǔ)言編程在單片機(jī)系統(tǒng)設(shè)計(jì)中已得到越來(lái)越廣泛的運(yùn)用。針對(duì)PIC單片機(jī)的軟件開(kāi)發(fā),同樣可以用C語(yǔ)言實(shí)現(xiàn)。但在|1&機(jī)上用C講言寫(xiě)程序和在PC機(jī)上寫(xiě)程序絕對(duì)不能簡(jiǎn)單等同?,F(xiàn)在的PC機(jī)資源卜分豐富,運(yùn)算能力強(qiáng)大,因此程序員在寫(xiě)PC機(jī)的應(yīng)用程序時(shí)兒乎不用關(guān)心編譯后的可執(zhí)行代訝在運(yùn)行過(guò)程中需姜占用多少系統(tǒng)資源,也基本不用擔(dān)心運(yùn)行效率有多商。寫(xiě)匕 的c程序最關(guān)鍵的一點(diǎn)足單左機(jī)內(nèi)的資源非常冇限,控制的實(shí)時(shí)性要求乂很高,因此,如 果沒(méi)

2、冇時(shí)里jfL體系結(jié)構(gòu)和硬件資源作詳盡的了解,以筆者的愚見(jiàn)認(rèn)為足無(wú)法寫(xiě)I礙質(zhì)杲實(shí) 用的c語(yǔ)盍程序。這就足為什么詢而所有策節(jié)中的的示范代碼全部用皐礎(chǔ)的匯編指令實(shí)現(xiàn) 的原因,希望籍此能使讀者對(duì)pic 血辿的指令體系和硬件資源有深入解,在這荃礎(chǔ)之 匕再來(lái)討論c語(yǔ)言編程,就冇水到渠成的感覺(jué)。本書(shū)圍境中檔系列PIC單片機(jī)來(lái)展開(kāi)討論,Microchip公司自己沒(méi)冇針對(duì)中低檔系列PIC單片機(jī)的C語(yǔ)言編譯器,但很多匕業(yè)的第三方公司有眾多支持PIC單片機(jī)的C語(yǔ)言編譯器 提供,常見(jiàn)的有Hitech、CCS、IAR, Bytecraft等公用。其中筆者最常用的是Hitech公用的 PICC編譯器,它穩(wěn)定可筋,編譯生成

3、的代碼效率拓,在用PIC巴辿進(jìn)行系統(tǒng)設(shè)計(jì)和開(kāi)發(fā)的程師群體中得到廣泛認(rèn)可。其正式完全版軟件需要購(gòu)置,但在其網(wǎng)站上冇限時(shí)的試用版供用戶評(píng)佔(zhàn)。另外,Hitech公司針對(duì)廣大PIC的業(yè)余愛(ài)好者和初學(xué)者還提供了完全免費(fèi)的學(xué)習(xí)版PICC-Ute編譯器套件,它的使用方式和完全版相同,只足支持的PIC巧機(jī)型號(hào)限制在PIC16F84. PIC16F877和PIC16F628等兒款。這兒款Flash型的單片機(jī)因其所具備的半富 的片上資源而最適用于血辿學(xué)習(xí)入門(mén),因此筆者建議感興趣的讀者可從PICC-Ute入于學(xué) 握PIC屮片機(jī)的C語(yǔ)言編程。在此列嘰兒個(gè)主要的針對(duì)PIC 訓(xùn)機(jī)的C編譯器相關(guān)連接網(wǎng)址,洪讀者參考:Hit

4、ech-PICC:1, htsoft .comIAR: CCS: ByteCraft: 本章將介紹Hitech-PICC編譯器的一些基本概念,山于篇幅所限將不涉及C語(yǔ)言的標(biāo)準(zhǔn) 語(yǔ)法和爆礎(chǔ)知識(shí)介紹,因?yàn)樵谶@些方而都冇大最的書(shū)籍可以參考。敢點(diǎn)突出針對(duì)PIC單片 機(jī)的特點(diǎn)而所需要特別注意的地方。11.2Hitech-PICC 編譯器PICC用本上符合ANSI標(biāo)陽(yáng) 除了一點(diǎn):它不支持函數(shù)的遞歸訓(xùn)用。其丄要原因是因 為PIC屮出衛(wèi)特殊的堆棧結(jié)構(gòu)。在詢面介紹PIC單片機(jī)架構(gòu)時(shí)己經(jīng)詳細(xì)說(shuō)明了 PIC單片機(jī)中的堆棧是硬件實(shí)現(xiàn)的,其深度已隨芯片而固定,無(wú)法實(shí)現(xiàn)需鑒大帚堆棧操作的遞歸算法; 另外在PIC單i M中

5、實(shí)現(xiàn)軟件堆棧的效率也不足很島,為此,PICC編譯器采用一種叫做"靜 態(tài)覆蓋"的技術(shù)以實(shí)現(xiàn)對(duì) C語(yǔ)言函數(shù)中的局部變眾分配固定的地址空間。經(jīng)這樣處理后產(chǎn) 生出的機(jī)器代碼效率很島,按筆者實(shí)際使用的體會(huì),、氣代碼雖趙過(guò)4K ?后,C語(yǔ)言編譯出 的代碼氏度和全部用匯編代碼實(shí)現(xiàn)時(shí)的差別己經(jīng)不是很大(10%) ,、“|然詢提是在整個(gè)C 代碼編寫(xiě)過(guò)程中須時(shí)時(shí)處處注意所編寫(xiě)語(yǔ)句的效率,而如果沒(méi)冇對(duì)PIC1的內(nèi)孩結(jié)構(gòu)、各功能模塊及其匯編指令深入了解,要做到這點(diǎn)足很難的。11.3MPLAB-IDE 內(nèi)掛接 PICCPICC編譯器可以畝接掛接在MPLAB-IDE集成開(kāi)發(fā)平臺(tái)下,實(shí)現(xiàn)一體化的編譯連接

6、和 原代碼調(diào)試。使用MPLAB-IDE內(nèi)的調(diào)試I具ICE2000. ICD2和軟件模擬器都可以實(shí)現(xiàn)原 代碼級(jí)的程調(diào)試,非常方便。由先必須在你的il算機(jī)中安裝PICC編譯器,無(wú)論是完全版還足學(xué)習(xí)版都可以和MPLABIDE掛接。安裝成功后可以進(jìn)入IDE,選擇菜單項(xiàng)Project Set Language ToolLocations.,打開(kāi)語(yǔ)言匸具掛接設(shè)置對(duì)話框,如圖111所示:圖11-1 MPUkB-IDE語(yǔ)言L具設(shè)置對(duì)話框在對(duì)話框中選擇"HI-TECH PICC Toolsuite"欄.展開(kāi)可執(zhí)行文件'Executables, 列出了將被MPLAB-IDE后臺(tái)調(diào)用的編

7、譯器所用到的所有可執(zhí)行文件,其中有匯編編譯器''PICC Assembler". C 原程序編譯器''PICC Compiler"和連接定位程序"PICC Linker"。同時(shí)在此列表中還顯示了對(duì)應(yīng)的可執(zhí)行程序名,請(qǐng)注意在這里都足"PICC.EXE"。用鼠標(biāo)分別點(diǎn)市選中這三項(xiàng)可執(zhí)行文件,觀察對(duì)話框下iTLocation"-欄中顯茹的文件路徑,用''Browse."按紐,從計(jì)算機(jī)中已經(jīng)安裝的PICC編譯器文件夾中選擇PICC.EXE文件。實(shí)際上PICC.EXE只足一個(gè)調(diào)

8、度管理程序,它會(huì)按照所輸入的文件擴(kuò)展名自動(dòng)調(diào)用對(duì)應(yīng)的編譯器和連接器,用戶要注意的足C語(yǔ)言原程序擴(kuò)展名用”.c",匯編原程序用、'.as"即可。匸具掛接完成后,在建立項(xiàng)目時(shí)可以選擇誑言1-具為、'HITECH PICC",具體步驟可以參閱第三章3.1.3節(jié),此處不再謊復(fù)。項(xiàng)U建立完成后可以加入C或匯編原程序,也可以加 入己有的庫(kù)文件或已經(jīng)編譯的口標(biāo)文件。最泊見(jiàn)的是只加入C脈程序。用C涪言編程的好 處是可以實(shí)現(xiàn)模塊化編程。程序編寫(xiě)者應(yīng)盡疑把相互獨(dú)立的控制任務(wù)用多個(gè)獨(dú)立的C原程序文件實(shí) 現(xiàn),如果程序戰(zhàn)較大,一般不要把所有的代碼寫(xiě)在-個(gè)文件內(nèi)。圖112列出

9、的足筆者建立的個(gè)項(xiàng)LI中所有C原程用模塊,真中主控、數(shù)值計(jì)算、I2C總線操 作、命令按鍵處理和液晶顯示驅(qū)動(dòng)等不同的功能分別在不同的獨(dú)立的原程序模塊中實(shí)現(xiàn)。圖112 C語(yǔ)言多模塊編程11.4 PIC屮片札的C語(yǔ)言原程序某本框架圧于PICC編譯環(huán)境編寫(xiě)PIC門(mén);匚程序的卑本方式和標(biāo)準(zhǔn)C程序類似,程序i般由以F兒個(gè)主要部分紐成:&O1540;在程序的最前面H#include預(yù)處理指令引用包含頭文杵,其中必須包含一個(gè)編譯器提供的pch"文件,實(shí)現(xiàn) 訓(xùn) 機(jī)內(nèi)特殊奇存器和其它特殊符號(hào)的聲外&O1540;用"_CONFIG阪處理捋令定義芯片的配置位:&O1540;

10、聲明本模塊內(nèi)被調(diào)用的所有函數(shù)的類犁,PICC將對(duì)所調(diào)用的函數(shù)進(jìn)行嚴(yán)格的類熨&O1540;定義全局變最或符號(hào)替換;&O1540;實(shí)現(xiàn)函數(shù)(了程序),特別注意main函數(shù)必須是-個(gè)沒(méi)有返回的死循環(huán)。下面的列11-1為 個(gè)C原程序的范例,供大家參考。# include包含單片機(jī)內(nèi)部資源預(yù)定義include npc68.h"包含自定義頭文件定義芯片匸作時(shí)的配遙位_CONFIG (HS & PROTECT & PWRTEN & BOREN & WDTDIS);聲明本模塊中所調(diào)用的函數(shù)類里void SetSFR(void);void Clock(v

11、oid);void KeyScan(void);void Measure(void);void LCD_Test(void);void LCD_Disp(unsigned char);定義變昴unsigned char second, minute, hour;bit flagl,flag2;函數(shù)和了程序void main(void)SetSFR();PORTC = 0x00;TMR1H += TMR1H_CONST;LED1 = LED.OFF;LCD_Test();程序匸作上循環(huán)whileasmf'clrwdn;Clozk();KeyScan();Measure();SetSFR(

12、);淸看門(mén)狗更新時(shí)鐘掃描鍵盤(pán)數(shù)據(jù)測(cè)量刷新特殊功能寄存器11.5PICC中的變杲定義例lli C語(yǔ)言原程序框架舉例11.5.1 PICC中的嚴(yán)本變気類型PICC遵循Uttle-endian標(biāo)準(zhǔn),多7節(jié)變世的低7節(jié)放在存儲(chǔ)空間的低地址,高7節(jié)放在高地址。11.5.2 PICC中的筒級(jí)變量堪于表11-1的荃本變眾,除r bit熨位變杲外,PICC完全支持?jǐn)?shù)組、結(jié)構(gòu)和聯(lián)合等復(fù)合型拓級(jí)變世,這和標(biāo)準(zhǔn)的c說(shuō)言所支持的高級(jí)變暈類型沒(méi)有什么區(qū)別。例如:數(shù)組:unsigned int data10;結(jié)構(gòu):struct commlnData unsigned char inBuff8;unsigned char

13、getPtr, putPtr;聯(lián)合:union int_Byte unsigned char c2;unsigned int i;例112 C語(yǔ)言高級(jí)變武舉例11.5.3 PICC對(duì)數(shù)據(jù)寄存器bank的管理 為了使編譯器產(chǎn)生最高效的機(jī)器碼,PICC把屮呂血中數(shù)據(jù)寄存器的bank問(wèn)題交由編程 員自己管理.因此在定義用戶變雖時(shí)你必須自己決定這些變駅具體放在哪一個(gè)bank中。如 果沒(méi)冇待別指明,所定義的變疑將彼定位在bankO.例如下面所定義的這些變杲: unsigned char buffer32;bit flagl,flag2;float val8;除了 bankO內(nèi)的變眾聲明時(shí)不需特殊處理外,

14、定義在其它bank內(nèi)的變杲前而必須加上 相應(yīng)的bank序號(hào),例如:bankl unsigned char buffer32;變量定位在 bankl 中bank2 bit flagl,flag2;bank3 float val8;變世定位在bank2中變雖定位在bank3中 中檔系列PIC單片機(jī)數(shù)拡寄存益的-個(gè)bank大小為128字節(jié),刨去詢而若T字節(jié)的特 殊功能寄存器區(qū)域,任C語(yǔ)言中某- bank內(nèi)定義的變疑字節(jié)總數(shù)不能趙過(guò)可用RAM字節(jié) 數(shù)。如果超過(guò)bank容疑,在最后連接時(shí)會(huì)報(bào)錯(cuò),大致信息如下:ErrorODO : Can't find 0xl2C words for psect

15、rbss_l in segment BANK1連接器告訴你總共有0xl2C (300)個(gè)字節(jié)準(zhǔn)備放到bankl中但bankl容厳不夠。顯然,只 有把一部分原本定位在bankl中的變懾改放到其它bank中才能解決此問(wèn)題。雖然變吊所在的bank定位必須由編程員自己決定,但在編寫(xiě)原程序時(shí)進(jìn)行變杲存取操作前無(wú)需再特意:編寫(xiě)設(shè)定bank的指令。C編譯器會(huì)根據(jù)所操作的對(duì)象自動(dòng)生成對(duì)應(yīng)bank設(shè) 定的匯編指令。為避免頻繁的bank切換以提高代碼效率,盡雖把實(shí)現(xiàn)同-任務(wù)的變疑定位 在同一個(gè)bank內(nèi):對(duì)不同bank內(nèi)的變最進(jìn)行讀寫(xiě)操作時(shí)也盡吊把位于相同bank內(nèi)的變昴 歸并在-起進(jìn)行連續(xù)操作。11.5.4 P

16、ICC中的局部變駅PICC把所有函數(shù)內(nèi)部定義的auto型局部變吊放在bankOo為節(jié)約寶貴的存儲(chǔ)空間,它采用了一種被叫做''靜態(tài)覆蓋”的技術(shù)來(lái)實(shí)現(xiàn)局部變最的地址分配。其大致的原理足在編譯 器編譯駅代碼時(shí)掃描整個(gè)程序中函數(shù)調(diào)用的嵌套關(guān)系和層次,算出每個(gè)函數(shù)中的崗部變帚7 節(jié)數(shù),憑后為每個(gè)局部變疑分配 個(gè)固定的地址,且按調(diào)用嵌套的層次關(guān)系各變杲的地址可 以相互重況。利用這一技術(shù)后所有的動(dòng)態(tài)局部變斌都可以按己知的閤定地址地進(jìn)行苴接尋 址,用PIC匯編指令實(shí)現(xiàn)的效率最拓,但這時(shí)不能出現(xiàn)函數(shù)遞片謹(jǐn)用。PICC在編譯時(shí)會(huì)嚴(yán) 格檢査遞歸調(diào)用的問(wèn)題并認(rèn)為這足一個(gè)嚴(yán)重錯(cuò)誤而立即終止編譯過(guò)程。既然

17、所有的局部變雖將占用bankO的存儲(chǔ)空間,因此用戶自己定位在bankO內(nèi)的變雖字 節(jié)數(shù)將受到定的限制,在實(shí)際使用時(shí)需注意。11.5.5 PICC中的位變疑bit熨位變杲只能是全局的或靜態(tài)的。PICC將把定位在同 bank內(nèi)的8個(gè)位變駅合并 成一個(gè)7節(jié)存放于一個(gè)固定地址。因此所有針對(duì)位變雖的操作將直接使用pic生迪的位 操作匯編指令奇效實(shí)現(xiàn)。軀于此,位變疑不能足局部自動(dòng)型變最,也無(wú)法將其組合成復(fù)合型PICC對(duì)較個(gè)數(shù)據(jù)存儲(chǔ)空間實(shí)行位編址,0x000單元的第0位是位地址0x0000,以此后 推,每個(gè)7節(jié)有8個(gè)位地址。編制位地址的意義純粹是為了編譯器最后產(chǎn)生匯編級(jí)位操作指 令而用.對(duì)編程人員來(lái)說(shuō)里本可

18、以不管但若能r解位變最的位地址編址方式就可以在最后 程序調(diào)試時(shí)方便地含找自己所定義的位變最,如果一個(gè)位變昴flagl彼編址為0x123,那么 實(shí)際的存儲(chǔ)空間位于:/ 節(jié)地址=0x123/8 = 0x24位偏移 =0xl23%8 = 3即flagl位變宦位于地址為0x24 7節(jié)的第3位。在程序調(diào)試時(shí)如果要觀察flagl的變化,必 須觀察地址為0x24的字節(jié)而不足0x123.PIC的位操作指令是非常高效的.因此,PICC在編譯原代碼時(shí)只要有可能,對(duì)普通變最的操作也將以最簡(jiǎn)單的位操作指令來(lái)實(shí)現(xiàn)。假設(shè)一個(gè)7節(jié)變駅tmp最后被定位在地址0x20,那么tmp |= 0x80tmp &二 0xf7=

19、> bsf=> bcf0x20,70x20,3if (tmp&Oxfe)=> btfsc 0x20,0即所冇只對(duì)變疑中某一位操作的c ifi句代碼將被肖接編譯成匯編的位操作指令。雖然編程 時(shí)可以不用太關(guān)心,但如果能r解編譯器足如何匸作的,那將有助于引導(dǎo)我們寫(xiě)出筒效簡(jiǎn)介 的c語(yǔ)言原程序。在冇些應(yīng)用中需要將一組位變量放在同一個(gè)7節(jié)中以便需要時(shí)一次性地進(jìn)行讀寫(xiě),這一功能可以通過(guò)定義一個(gè)位域結(jié)構(gòu)和一個(gè)7節(jié)變駅的聯(lián)合來(lái)實(shí)現(xiàn),例如:union struct unsigned bO: 1;unsigned bl: 1;unsigned b2: 1;unsigned b3: 1;un

20、signed b4: 1;unsigned b5: 1;unsigned : 2; 最高兩位保留 oneBit;unsigned char allBits; myFlag;例113定義位變駅于同字節(jié)需要存取其中某位時(shí)可以myFlag.oneBit.b3=l; /b3 位置 1一次性將全部位淸零時(shí)可以myFlag.allBits=O;全部位變戢淸0'“I程序中把非位變暈進(jìn)行強(qiáng)制類型轉(zhuǎn)換成位變屋時(shí),要注意編譯器只對(duì)普通變議的最低位做判別:如果顯低位是0,則轉(zhuǎn)換成位變疑0;如果最低位足I.則轉(zhuǎn)換成位變駅1。而標(biāo) 準(zhǔn)的ANSI-C做法足判整個(gè)變駅伯足否為0。另外,函數(shù)可以返回一個(gè)位變最,實(shí)際上

21、此返 回的位變杲將存放于辿也的進(jìn)位位中帶出返回。11.5.6 PICC中的浮點(diǎn)數(shù)PICC中描述浮點(diǎn)數(shù)足以IEEE-754標(biāo)準(zhǔn)格式實(shí)現(xiàn)的。此標(biāo)準(zhǔn)下定義的浮點(diǎn)數(shù)為32位長(zhǎng),在 生札中要用4個(gè)字節(jié)存儲(chǔ).為了節(jié)約單片機(jī)的數(shù)據(jù)空間和程庁空間,PICC $門(mén)提供了種反度為24位的截短型浮點(diǎn)數(shù),它損失了浮點(diǎn)數(shù)的-點(diǎn)梢度,但浮點(diǎn)運(yùn)算的效率得以提尚。在程序中定義的float型標(biāo)準(zhǔn)浮點(diǎn)數(shù)的氏度固定為24位,雙將度double型浮點(diǎn)數(shù)一般 也足24位K,但可以在程序編譯選項(xiàng)中選擇double型浮點(diǎn)數(shù)為32位,以提高計(jì)算的耕度。-般控創(chuàng)系統(tǒng)中關(guān)心的是的運(yùn)行效率,因此在耕度能夠滿足的前提下盡屋選幷24位的浮點(diǎn)數(shù)運(yùn)算.1

22、1.5.7 PICC中變帯的絕對(duì)定位忤先必須強(qiáng)調(diào),在用C語(yǔ)言寫(xiě)程序時(shí)變最般山編譯器和連接器最后定位,在寫(xiě)程序 之時(shí)無(wú)需知道所定義的變僦貝體被放在哪個(gè)地址(除了 bank必須聲明)。真正需要絕對(duì)定位的只足心丿:肌中的那些特殊功能寄存器,而這些寄存器的地址定位在PICC編譯環(huán)境所提供的頭文件中已經(jīng)實(shí)現(xiàn),無(wú)需用戶操心。編程員所要了斛的也就足PICC 足如何定義這些特殊功能寄存器和其中的相關(guān)控制位的名稱。好在PICC的定義標(biāo)準(zhǔn)荃本上 按照芯片的數(shù)據(jù)乎冊(cè)中的名稱描述進(jìn)行,這樣就秉承了變慣命名的一貫性。個(gè)變疑絕對(duì)定 位的例子如下:unsigned char tmpData 0x20; /tmpData 定

23、位在地址 0x20干萬(wàn)注憊,PICC對(duì)絕對(duì)定位的變眾不保留地址空間.換句話說(shuō),上面變晁tmpData的 地址是0x20,但最后0x20處完全有可能乂被分配給了其它變帰使用,這樣就發(fā)生了地址沖 突。因比針對(duì)變尿的絕對(duì)定位要特別小心.從筆者的應(yīng)用經(jīng)驗(yàn)看,在一般的程序設(shè)計(jì)中用戶 自定義的變杲實(shí)在足沒(méi)冇絕對(duì)定位的必要。如果需耍,位變世也可以絕對(duì)定位。但必須遵循上面介紹的位變僦編址的方式。如果-個(gè)普通變雖己經(jīng)被絕對(duì)定位,那么此變呆中的每個(gè)數(shù)據(jù)位就可以用下而的計(jì)算方式實(shí)現(xiàn)位變 駅指派:unsigned char tmpData 0x20; /tmpData 定位在地址 0x20bit tmpBitO tm

24、pData*8+0; /tmpBitO 對(duì)應(yīng)于 tmpData 第 0 位bit tmpBitl tmpData*8+l; /tmpBitO 對(duì)應(yīng)于 tmpData 第 1 位 extern bankl unsigned char varl, var2; 聲明位于 bankl 的外部變駅如果tmpData爭(zhēng)先沒(méi)有被絕對(duì)定位,那就不能用上面的位變眾定位方式。11.5.8 PICC的英它變最修飾關(guān)鍵訶&O1540; extern 外部變杲聲明如果在一個(gè)C程序文件中要使用-些變罐但梵原熨定義寫(xiě)在另外的文件中,那么在本文件中必須將這些變昂聲明成"extern"外部類熨。例如

25、程序文件codel.c中冇如下定義:bankl unsigned char varl, var2;定義了 bankl中的兩個(gè)變懾在另外一個(gè)程序文件code2.c中要對(duì)上而定義的變杲進(jìn)行操作,則必須在程序的開(kāi)頭定義:&O1540; volatile -易變型變眾聲明PICC中還有一個(gè)變最修飾訶在普通的C語(yǔ)言介紹中-般足看不到的,這就足關(guān)鍵訶 "volatile"。顧名思義,它說(shuō)明了一個(gè)變駅的伯足會(huì)隨機(jī)變化的,即使程序沒(méi)冇刻意對(duì)它進(jìn) 行任何賦值操作。在也中,作為輸入的10端口其內(nèi)容將足隨意變化的;在中斷內(nèi)被修 改的變憬相對(duì)主程序流程來(lái)講也是隨意變化的:很多特殊功能寄存器

26、的值也將隨著指令的運(yùn) 行而動(dòng)態(tài)改變。所有這種類型的變量必須將它們明確定義成"volatile"類犁,例如:volatile unsigned char STATUS 0x03;volatile bit commFlag;"volatile"類型定義在匕E也的C涪言編程中是如此的垂要,是因?yàn)樗梢愿嬖V編譯器的優(yōu)化處理器這些變供足實(shí)實(shí)在在存在的,在優(yōu)化過(guò)程中不能無(wú)故消除。假定你的程序定 義了-個(gè)變眾并對(duì)其作了一-次賦值,但隨后就再也沒(méi)冇對(duì)兀進(jìn)行任何讀寫(xiě)操作,如果足非 volatile堆變量,優(yōu)化后的結(jié)果是這個(gè)變眾將有可能被徹底刪除以廿約存儲(chǔ)空間。刃外-種悄形

27、足在使用某-個(gè)變就進(jìn)行連續(xù)的運(yùn)算操作時(shí),這個(gè)變量的值將在第-次操作時(shí)被復(fù)制到中間臨時(shí)變雖中,如果它足非volatile樂(lè)變疑,則緊接其后的其它操作將有可能但接從臨時(shí)變最中収數(shù)以提高運(yùn)行效率,顯然這樣做后對(duì)于那些隨機(jī)變化的參數(shù)就會(huì)HI問(wèn)題。只要將H 定義成volatile類型后,編譯后的代碼就可以保證每次操作時(shí)戌接從變最地址處収數(shù)。&O1540; const 一常數(shù)熨變疑聲明如果變駅定義麗就以”8nst'類型修飾,那么所冇這些變疑就成為常數(shù),程序運(yùn)行過(guò)程中不能對(duì)其修改。除f位變量,其它所有玨本類型的變杲或島級(jí)組合變駅都將被存放在程 序空間(ROM區(qū))以節(jié)約數(shù)據(jù)存儲(chǔ)空間。顯然,被定

28、義在ROM區(qū)的變杲足不能再在程序 中對(duì)其進(jìn)行賦值修改的,這也足"const'的本來(lái)意義。實(shí)際上這些數(shù)列最終都將以''retlw" 的抬令形式存放在程序空間,但PICC會(huì)自動(dòng)編譯生成相關(guān)的附加弋碼從程序空間讀取這些 常數(shù),編程員無(wú)需太多操心。例如:const unsigned char name='This is a demo" 定義個(gè)常気7符串如果定義了 "consT類塑的位變世,那么這些位變議還繪被放置在RAM中,但程序不能對(duì)其賦伯修改.本來(lái),不能修改的位變貳沒(méi)冇什么太多的實(shí)際恵義,相倍大家在實(shí)際編 程時(shí)不會(huì)大最用到。&

29、amp;O1540; persistent 苗初始化變母聲明 按照標(biāo)準(zhǔn)C語(yǔ)言的做法,程序在開(kāi)始運(yùn)行両百先要把所有定義的但沒(méi)有預(yù)置初值的變 吊全部清零。PICC會(huì)在最后生成的機(jī)器碼中加入一小段初始化代碼來(lái)實(shí)現(xiàn)這一變訊淸冬操 作,且這一操作將在main函數(shù)被調(diào)用之前執(zhí)行。問(wèn)題足作為一個(gè)門(mén);機(jī)的控制系統(tǒng)冇很多 變眾足不允許在程序復(fù)位后被清零的。為了達(dá)到這一U的,PICC提供了''persistent7'修飾 訶以聲明此類變世無(wú)需在復(fù)位時(shí)自動(dòng)淸零,編程員應(yīng)該F1己決定程序中的那些變疑是必須聲 明成"persisten啖里,而且須自己判斷什么時(shí)候需要對(duì)其進(jìn)行初始化賦值。

30、例如: persistent unsigned char hour,minute,second; 定義時(shí)分秒變帚經(jīng)常用到的是如果程序經(jīng)上電復(fù)位后開(kāi)始運(yùn)行,那么需要將persistent和的變杲初始化, 如果是氏它形式的復(fù)位,例如看門(mén)狗引發(fā)的復(fù)位,則無(wú)需對(duì)persistent型變戢作任何修改。 PIC勺£也內(nèi)提供了各種復(fù)位的判別標(biāo)志,用戶程序可依貝體設(shè)計(jì)靈活處理不同的復(fù)位悄 形。11.5.9 PICC中的指針PICC中指針的卑本概念和標(biāo)準(zhǔn)C語(yǔ)法沒(méi)有太多的差別。但足在PIC E片機(jī)這-特定的 架構(gòu)h.指針的定義方式還足冇兒點(diǎn)需要持別注意.&O1540; 指向RAM的指針 如果是匯

31、編語(yǔ)言編程,實(shí)現(xiàn)指針尋址的方法疔定就是用FSR寄存齡,PICC也不例外.為了生戎商效的代碼,PICC在編譯C原程序時(shí)將指向RAM的指計(jì)操作最終用FSR來(lái)實(shí)現(xiàn) 間接尋址。這樣就勢(shì)必產(chǎn)生一個(gè)問(wèn)題:FSR能夠戌接連續(xù)尋址的范刃足256 7節(jié)(bankO/1 或bank2/3),要覆蓋最大512字節(jié)的內(nèi)部數(shù)拯存儲(chǔ)空間,乂該如何讓定義指針? PICC還足 將這-訶題留給編程員自己解決:在定義指針時(shí)必須明確指定該指針?biāo)m用的尋址區(qū)域,例 如:unsigned char *ptrO; 定義覆蓋 bankO/1 的指針bank2 unsigned char *ptrl; 定義覆蓋 bank2/3 的指針ban

32、k3 unsigned char *ptr2; 定義覆蓋 bank2/3 的指針上面定義了三個(gè)指針變就,其中指針沒(méi)有任何bank限定,缺省就是指向bankO和bankl: 和一個(gè)指明了 bank2,另一個(gè)指明了 bank3,但實(shí)際上兩者足一樣的,因?yàn)橐粋€(gè)指針可以同時(shí)謖譴兩個(gè)bank的存儲(chǔ)區(qū)域。另外,上而三個(gè)抬針變昂自身都存放在bankO中。我們 將在稍后介紹如何住英它bank中存放指針變尿。既然定義的指針有明確的bank適用區(qū)域,在對(duì)指針變最賦值時(shí)就必須實(shí)現(xiàn)類型匹配,下而的指針賦伯將產(chǎn)生一個(gè)致命錯(cuò)誤:unsigned char *ptrO;bank2 unsigned char buff8;程

33、序語(yǔ)旬:定義指向bankO/1的指針定義bank2中的-個(gè)緩沖區(qū)ptrO = buff; 錯(cuò)誤!試圖將bank2內(nèi)的變最地址賦給指向bankO/1的指針若出現(xiàn)比類錯(cuò)誤的指針操作,PICC在最后連接時(shí)會(huì)告知類似于下而的Fixup overflow in expression ()同樣的道理,若函數(shù)調(diào)用時(shí)用了指針作為傳遞參數(shù),也必須注惹bank作用域的匹配,而這點(diǎn)往往容易被忽視。假定冇下面的函數(shù)實(shí)現(xiàn)發(fā)送一個(gè)7符串的功能:void SendMessage(unsigned char *);那么被發(fā)送的字符串必須位于bankO或bankl中。如果你還要發(fā)送位于bank2或bank3內(nèi)的7符必須再另外單

34、獨(dú)寫(xiě)一個(gè)函數(shù): void SendMessage_2(bank2 unsigned char *); 這兩個(gè)因數(shù)從內(nèi)部代碼的實(shí)現(xiàn)來(lái)看可以模一樣,但傳遞的參數(shù)類型不同。按筆者的應(yīng)用經(jīng)驗(yàn)體會(huì),如果你看到廠Fixup overflow"的錯(cuò)誤指示,兒乎可以肯定 足指針類熨不匹配的賦值所至。請(qǐng)旅點(diǎn)檢査程序中有關(guān)描針的操作。&O1540;指向ROM常數(shù)的指針如果組變眾足已經(jīng)被定義在ROM區(qū)的常數(shù),那么指向它的指針可以這樣定義:const unsigned char company二Mcrochip"const unsigned char *romPtr;程序中可以對(duì)上面的指針

35、變赧賦值和實(shí)現(xiàn)取數(shù)操作:romPtr = company; 指針賦初伯data = *romPtr+; 取指針指向的-個(gè)數(shù),然后指針加1定義ROM中的常數(shù)定義指向ROM的指針 反過(guò)來(lái),下面的操作將是i個(gè)錯(cuò)誤,因?yàn)樵撝羔樦赶虻淖惝?dāng)數(shù)舉變燧,不能賦值。*romPtr = data; 往指針指向的地址寫(xiě)一個(gè)數(shù)&O1540; 指向函數(shù)的指針卩蟲(chóng)札編程時(shí)函數(shù)指針的應(yīng)用相對(duì)較少,但作為標(biāo)準(zhǔn)C語(yǔ)法的-部分,PICC同樣支持 函數(shù)指計(jì)調(diào)用。如果你對(duì)編譯原理有一定的了解,就應(yīng)該明口在PIC即5這一特定的架 構(gòu)上實(shí)現(xiàn)函數(shù)指針調(diào)用的效率足不高的:PICC將在RAM中建立一個(gè)調(diào)用返回表,真正的 調(diào)用和返回過(guò)程

36、足靠戌接修改PC指針來(lái)實(shí)現(xiàn)的。因此,除非特殊瘁法的需要,建議大家盡 杲不要使用函數(shù)指針。&O1540; 指針的類型修飾前而介紹的指針定義都是最堪本的形式。和普通變僦樣,指針定義也可以在前而加上 特殊類型的修飾關(guān)鍵訶,例如"persistent"、''volatile"等??紤]指針本身還要限定其作用域, 因此PICC中的指針定義初看起來(lái)顯得冇點(diǎn)復(fù)雜,但只要了解各部分的貝體含義,理解一個(gè)指針的實(shí)際用圖就變得很苴接.()bank修飾訶的位置含義前而介紹的一些指針冇的作Hl于bankO/1,冇的作用于bank2/3.但它們本身的存放位置 全部在ba

37、nkOo顯然,在一個(gè)程序設(shè)計(jì)中指針變駅將冇可陡彼定位在任何可用的地址空間, 這時(shí),bank修飾詞出現(xiàn)的位置就足個(gè)關(guān)鍵,看下而的例了:定義指向bankO/1的指針,指針變雖為于bankO中unsigned char *ptrO;定義指向bank2/3的指針,指針變耳為于bankO中bank2 unsigned char *ptrO;定義指向bank2/3的抬針,指針變昴:為于bankl中bank2 unsigned char bankl ptrO;從中可以看Hl規(guī)律:前面的bank修飾訶指明了此指針的作用域:后面的bank修飾誠(chéng)定義f 此指針變疑自身的存放位置。只要學(xué)握了這一法則,你就可以定義任

38、何作用域的描針且可以 將指針變昴:放于任何bank中。volatilepersistent和const修飾訶的位置含義如果能理解上而介紹的bank修飾詞的位置含義,實(shí)際上volatile, persistent和const這些關(guān)鍵詞出現(xiàn)在詢后不同位置上的含義規(guī)律足和bank 詞相-致的。例如:定義指向bankO/1易變型7符變錄的指針,指針變杲位于bankO中且自身為非易變住volatile unsigned char *ptrO;定義指向bank2/3非易變塑?符變吊的指針.指針變最位于bankl中且自身為易變期bank2 unsigned char * volatile bankl ptr

39、O;定義指向ROM區(qū)的指針,指針變昴本身也足存放于ROM區(qū)的常數(shù)const unsigned char * const ptrO;亦即出現(xiàn)在詢面的修飾訶英作用對(duì)彖足指針?biāo)柑幍淖儽姡荷浆F(xiàn)在點(diǎn)面的修飾訶X作用對(duì)彖 就是指計(jì)變疑白己。11.6PICC中的程序和函數(shù)中檔系列的PIC也程序空間冇分頁(yè)的概念,但用C講吉編程時(shí)壟本不用太多關(guān)心代碼的分頁(yè)問(wèn)題。因?yàn)樗泻瘮?shù)或了程序調(diào)用時(shí)的頁(yè)而設(shè)定(如果代碼超過(guò)一個(gè)頁(yè)而)都由 編謙器自動(dòng)生成的指令實(shí)現(xiàn)。11.6.1函數(shù)的代碼反度限制PICC決定了 c甌程序中的一個(gè)函數(shù)經(jīng)編譯后生成的機(jī)器碼一定會(huì)放在同-個(gè)程序貝面內(nèi)。中檔系列的PIC丿;門(mén)其一個(gè)程序頁(yè)而的長(zhǎng)度足2

40、K 7,換句話說(shuō),用C語(yǔ)言編寫(xiě)的任 何一個(gè)藥數(shù)最后生成的代碼不能超過(guò)2K 7. 一個(gè)良好的程序設(shè)計(jì)應(yīng)該冇一個(gè)諧晰的組織結(jié) 構(gòu),把不同的功能用不同的函數(shù)實(shí)現(xiàn)足嚴(yán)好的方法,因此-個(gè)函數(shù)2K字長(zhǎng)的限制般不會(huì) 對(duì)程序代碼的編寫(xiě)產(chǎn)生太多影響。如果為實(shí)現(xiàn)特定的功能確實(shí)要連續(xù)編寫(xiě)很長(zhǎng)的程序,這時(shí) 就必須把這些連續(xù)的代碼拆分成若干函數(shù),以保證每個(gè)函數(shù)最后編譯出的代碼不超過(guò)一個(gè)頁(yè) 面空間,11.6.2調(diào)用層次的控制中檔系列PIC 也的硬件堆棧深度為8級(jí),考虔中斷響應(yīng)需片用一級(jí)堆棧,所有函數(shù)調(diào)用嵌套的最大深度不要超過(guò)7級(jí)。編程員必須自己控制了程序調(diào)用時(shí)的嵌套深 度以符合這“限制要求。PICC在最后編譯連接成功后可

41、以生成一個(gè)連接定位映射文件(*.map),在此文件 中冇詳細(xì)的函數(shù)調(diào)用嵌套指示圖"call graph",建議大家要留意一下其信息大致如下(取H于一示范程序的編譯結(jié)果),Call graph:*_main size OZO offset 0_RightShift_C* .Task size 0,1 offset 0Iwtoftftmul size 0,0 offset 0ftunpacklftun pack2ftadd size 0,0 offset 0ftunpacklftun pack2ftdenorm例1V4 C甌數(shù)調(diào)用層次圖上而所舉的信息表明報(bào)個(gè)程序在止常調(diào)用了程序

42、時(shí)嵌套晟多為兩級(jí)(沒(méi)冇考慮中斷)-因?yàn)?main函數(shù)不可能返回,故其不用計(jì)算在嵌套級(jí)數(shù)中。梵中有些函數(shù)調(diào)用是編譯代碼時(shí)自動(dòng) 加入的庫(kù)函數(shù),這些函數(shù)調(diào)用從C原程序中無(wú)法忸接看HI,但在此嵌套指示圖上則一U r 然。11.6.3 函數(shù)類型聲明PICC在編譯時(shí)將嚴(yán)格進(jìn)行函數(shù)調(diào)用時(shí)的類型檢査。-個(gè)良好的習(xí)慣是在編寫(xiě)程序代碼前先聲眄所冇用到的函數(shù)類型例如:void Task(void);unsigned char Temperature(void);void BJN2BCD(unsigned char);void TimeDisplay(unsigned char, unsigned char);這些類

43、型聲明確定了函數(shù)的入口參數(shù)和返回值類型,這樣編譯器在編譯代碼時(shí)就能保證生成1E確的機(jī)器碼。筆者在實(shí)際1一作中有時(shí)碰到些用戶聲稱發(fā)現(xiàn)C編譯器生成了錯(cuò)誤的代碼, 最后究比原因就足因?yàn)闆](méi)有弔先聲明函數(shù)類型所毀。鯉議大家在編寫(xiě)一個(gè)函數(shù)的原代碼時(shí),立即將此函數(shù)的類舉聲明復(fù)制到原文件的起始處,見(jiàn)列11-1;或足復(fù)制到專門(mén)的包含頭文件中,再在每個(gè)原程療模塊中引用。11.6.4中斷函數(shù)的實(shí)現(xiàn)PICC可以實(shí)現(xiàn)C語(yǔ)言的中斷服務(wù)程序。中斷服務(wù)程序有-個(gè)特殊的定義方法:void interrupt ISR(void);英中的函數(shù)名JSRFJ以改成任愆合法的7母或數(shù)7組合,但英入口參數(shù)和返回參數(shù)類型 必須是、oid&q

44、uot;熨,亦即沒(méi)有入口參數(shù)和返回參數(shù),且中間必須有-個(gè)關(guān)鍵述interrupts 中斷函數(shù)可以被放置在原程序的任意位置因?yàn)橐褍雨P(guān)鍵詞"interrupt聲明,PICC在最后進(jìn)廳代碼連接時(shí)會(huì)自動(dòng)將其定位到0x0004中斷入口處,實(shí)現(xiàn)中斷服務(wù)響應(yīng)。編譯器也會(huì)實(shí)現(xiàn)中斷函數(shù)的返回指令"retfie"。個(gè)簡(jiǎn)單的中斷服務(wù)示范函數(shù)如下:void interrupt ISR(void) 中斷服務(wù)程序if (T0IE && T0IF)T0IF = 0;在此加入TMR0中斷服務(wù)判TMR0中斷淸除TMRO中斷標(biāo)志if (TMR1IE && TMR1IF

45、) 判 TMR1 中斷TMR1IFO;在此加入TMR1中斷服務(wù)淸除TMR1中斷標(biāo)志中斷結(jié)束并返回例115 C語(yǔ)言中斷函數(shù)舉例PICC會(huì)白動(dòng)加入代碼實(shí)現(xiàn)中斷現(xiàn)場(chǎng)的保護(hù),并在中斷結(jié)束時(shí)向動(dòng)恢復(fù)現(xiàn)場(chǎng),所以編程 員無(wú)需彖編寫(xiě)匯編程序那樣加入中斷現(xiàn)場(chǎng)保護(hù)和恢復(fù)的額外指令語(yǔ)句。但如果在中斷服務(wù)程 序中需要修改某些全局變錄時(shí),足否需要保護(hù)這些變尿的初值將山編程員自己決定和實(shí)施。用C語(yǔ)言編寫(xiě)中斷服務(wù)程序必須遵循高效的原則:&O1540;代碼盡量簡(jiǎn)短,中斷服務(wù)強(qiáng)調(diào)的是一個(gè)“快"7。&O1540;避免在中斷內(nèi)使用函數(shù)調(diào)用。雖然PICC允許在中斷里調(diào)用其它函數(shù),但為了解決 遞歸調(diào)用的問(wèn)題,

46、此函數(shù)必須為中斷服務(wù)獨(dú)家匕用。既如此,不妨耙原本要寫(xiě)住其它函數(shù)內(nèi)的代碼耳接寫(xiě)在中斷厳務(wù)程序中。&O1540;避免在中斷內(nèi)進(jìn)行數(shù)學(xué)運(yùn)算。數(shù)學(xué)運(yùn)算將很有可能用到庫(kù)函數(shù)和許多中間變昂.就算不出現(xiàn)遞歸調(diào)用的問(wèn)題,光在中斷入口和hi口處為r保護(hù)和恢復(fù)這些中間臨時(shí)變雖就需耍大疑的開(kāi)俏,嚴(yán)審影響中斷服務(wù)的效率。中檔系列PIC的中斷入口只有個(gè),因此林個(gè)稅序中只能有個(gè)中斷服務(wù)函數(shù).11.6.5標(biāo)準(zhǔn)庫(kù)函數(shù)PICC提供了較完舉的C標(biāo)準(zhǔn)庫(kù)函數(shù)支持,其中包括數(shù)學(xué)運(yùn)算函數(shù)和7符串操作函數(shù)。任程用中使用這些現(xiàn)成的庫(kù)函數(shù)時(shí)需要注意的足入口參數(shù)必須在bankO中。如果需姜用到數(shù)學(xué)廚數(shù),則應(yīng)在程序前”#include &

47、quot; 包含頭文件:如果要使用7符串操作函數(shù),就需要包含”#indude "頭文件。在這些頭文件中提供了函數(shù) 類型的由明。通過(guò)克接?xùn)丝催@些頭文件就可以知道PICC提供了哪些標(biāo)準(zhǔn)庫(kù)函數(shù)。C語(yǔ)言中簾用的格式化打印函'printf/sprintrri> Al!-的程序中時(shí)要特別printf/sprintf足一個(gè)非常大的兩數(shù),一旦使用,你的程序代碼2度就會(huì)增加很多。除非是在 編寫(xiě)試臉性質(zhì)的代碼,可以考慮使用格式化打印函數(shù)以簡(jiǎn)化測(cè)試程序;一般的最終產(chǎn)品設(shè)計(jì) 都足自己編寫(xiě)最稍簡(jiǎn)的代碼實(shí)現(xiàn)特定格式的數(shù)據(jù)顯示和輸出。本來(lái),在屮片機(jī)應(yīng)用中輸出的 數(shù)據(jù)格式都相對(duì)簡(jiǎn)單而且固定,實(shí)現(xiàn)起來(lái)應(yīng)

48、該很容易。對(duì)于標(biāo)準(zhǔn)C語(yǔ)育的控制臺(tái)輸入(scanf) /輸也(printf)函數(shù),PICC需要用戶自己編寫(xiě) 共底層函數(shù)getch()和putch()o在 訕M系統(tǒng)中實(shí)現(xiàn)scanf/printf本來(lái)就沒(méi)什么太多意義,如 果一定更丈現(xiàn),只耍編寫(xiě)好特定的getch()和putch()函數(shù),你就可以通過(guò)任何按口輸入或輸出格式化的數(shù)據(jù)。11.7PICC定義特殊區(qū)域值PICC提供了相關(guān)的預(yù)處理指令以實(shí)現(xiàn)在原程序中定義的配置7和標(biāo)記單元.11.7.1定義工作配置7在原程序中定義PIC 占機(jī)一匸作配置7的重要性在就而章節(jié)中已經(jīng)闡述。在用PICC寫(xiě)程序時(shí)司樣可以在c原程序中定義,具體方式如下:_CONFIG (H

49、S & UNPROTECT & PWRTEN & BORDIS & WDTEN);上而的關(guān)鍵詞”_CONFIG"(注意前而冇兩個(gè)下劃線符)&門(mén)用于足芯片配置?的設(shè)定,后而括號(hào)中的各項(xiàng)配置位符號(hào)在特定型號(hào)¥上;川的頭文件中已經(jīng)定義(注意不是pic.h 頭文件),相互之間用邏輯嵌與"操作符組合在一起。這樣定義的配庫(kù)7信息最后將和程序代碼一起放入同一個(gè)HEX文件。在這里列出了適用于16F7X系列丄迪配置位符號(hào)預(yù)定義,英它型號(hào)或系列的單片機(jī)配置7定義方式類似,便用前査閱一下對(duì)應(yīng)的頭文件U卩可。 廣振蕩器配置*/#define RC#

50、define HSOx3FFF / RC 振蕩Ox3FFE / HS 模式#define XT#define LP嚴(yán)看門(mén)狗配置*Ox3FFD / XT 模式Ox3FFC / LP 模式#define WDTEN 0x3FFF / 百門(mén)狗打開(kāi)#define WDTDIS/*上電延時(shí)定時(shí)器配置*/#define PWRTENOx3FFB /看門(mén)狗關(guān)閉0x3FF7 /上電延時(shí)定時(shí)器打開(kāi)#define PWRTDIS0x3FFF /上電延時(shí)定時(shí)器關(guān)閉/低電壓復(fù)位配置”#define BOREN 0x3FFF /低電爪復(fù)位允許希define BORDIS廣代碼慄護(hù)配置5*70X3FBF /低電壓復(fù)位禁止

51、#define UNPROTECT 0x3FFF /沒(méi)有代碼保護(hù)#define PROTECT0x3FEF /程序代碼保護(hù)例11-6頭文件預(yù)定義的配置倍息符號(hào)11.7.2定義芯片標(biāo)記單元PIC il'HJfl中的標(biāo)記單元定義可以用卜而的_IDLOC (注意前而有兩個(gè)卜劃線符)預(yù)處理指令實(shí)現(xiàn),方法如下:_IDLOC (1234);其特殊之處是括號(hào)內(nèi)的值全部為16進(jìn)制數(shù).不需姜用"OxVI導(dǎo)。這樣上面的定義就設(shè)定了標(biāo)記單元內(nèi)容為01020304.11.8MPLAB-IDE中實(shí)現(xiàn)PICC的編譯選項(xiàng)設(shè)置在11.3節(jié)中已經(jīng)介紹了如何實(shí)現(xiàn)PICC和MPLAB-IDE開(kāi)發(fā)平臺(tái)的掛接。一冃項(xiàng)

52、目建龍成功、程序編寫(xiě)完成后即可以通過(guò)MP3B環(huán)境下的項(xiàng)LI管理具實(shí)現(xiàn)程序的編譯、連接和調(diào)試。它們的含義分別是:一項(xiàng)口難護(hù)(Make) : MPLAB檢査項(xiàng)口中的原程序文件,只編譯那些在卜.次編譯后乂披修改過(guò)的原程序,最后進(jìn)行連接:一項(xiàng)口就鋰(Build All):項(xiàng)U中的所有原程序文件,不管是否有修改,都將彼車新編譯次.最后進(jìn)行連接。也可以通過(guò)Project菜單選擇”Make"或''Build All"實(shí)現(xiàn)項(xiàng)LI編譯。不管采用何種方式,在自動(dòng)編譯過(guò)程前一般都要設(shè)定一些編譯選項(xiàng).11.8.1 選擇單丿機(jī)型號(hào)在選擇PICC作為語(yǔ)言匸貝并建立了項(xiàng)LJ后,同樣通過(guò)菜

53、單項(xiàng)Configure&O1616;Select Device 在MPLAB環(huán)境中選擇貝體片機(jī)型號(hào)。請(qǐng)回顧-下例111的代碼,我們?cè)谠绦蛞婚_(kāi)始 使用廠#include "實(shí)現(xiàn)了相關(guān)里M的一些預(yù)定義符號(hào)的直接引用,但沒(méi)冇具體指明足哪-個(gè)型號(hào)。實(shí)際上,''pic.h"頭文件只是一個(gè)簡(jiǎn)單的管理1具(條件判別),它會(huì)按照 MPLAB所選擇的特定型號(hào)的口昭,,把真1E對(duì)應(yīng)的頭文件包含進(jìn)來(lái)。有興趣者可以克接用 文本編輯匚貝打開(kāi)pic.h文件查看苴是如何根據(jù)不同的巴片扭黑號(hào)包含對(duì)應(yīng)的頭文件。這樣對(duì)編程員而直,程序中只需加上句include "即可。11

54、.8.2 PICC普通編譯選項(xiàng)(General)設(shè)定參考第三章3.2.7節(jié)的內(nèi)容和圖3-20的指示說(shuō)明,啟動(dòng)編譯選項(xiàng)設(shè)定對(duì)話框。在使用PICC講古具時(shí)對(duì)話框的內(nèi)容和用MPAMS匯編具相比完全不同.圖11-3為PICC編譯環(huán)境下普通迭項(xiàng)設(shè)定的界面。在此界而中用戶唯-能改變的足編譯器査找頭文件時(shí)的指定路能(Include Path).實(shí)際上如果編譯器安裝沒(méi)冇問(wèn)題,在此界面中這些普通選項(xiàng)的設(shè)定無(wú)需任何改動(dòng),編譯器會(huì)自動(dòng) 到缺省認(rèn)定的路徑中(編譯器安裝后的相關(guān)路徑)E找編譯所需的各類文件。圖113 PICC普通選項(xiàng)設(shè)定圖11-4 PICC全局選項(xiàng)設(shè)定11.8.3 PICC 全局選項(xiàng)設(shè)定(PICC Gl

55、obal)全局選項(xiàng)將影響項(xiàng)目中所冇C和匯編原程序的編譯,詳細(xì)的設(shè)定內(nèi)容見(jiàn)圖11-4»賓中必須關(guān)注的有:&O1540; Compile for MPLAB ICD:如果你準(zhǔn)備用ICD調(diào)試C語(yǔ)言編譯后的代碼,那么此項(xiàng) 就必須打鉤選中。這樣編譯后的結(jié)果就能保證ICD本身使用的芯片資源(一小部分的程字和數(shù)據(jù)空間)不被應(yīng)用程序所占用。&O1540; Treat 'char as signed:為了提高編譯后的代碼效率,PICC缺省認(rèn)定'chaF型變杲也 足無(wú)符號(hào)數(shù)。如果在設(shè)計(jì)中需要使用帶符號(hào)的'chaL世變屋,此項(xiàng)就應(yīng)該被選中。&O1540; F

56、loating point 'double' width:同樣為了提高編譯后的代碼效率,PICC缺省認(rèn)定'double'型的雙粘度浮點(diǎn)數(shù)變最的實(shí)現(xiàn)長(zhǎng)度為24位(等同于普通float型浮點(diǎn)數(shù))。在這里可以選擇使其長(zhǎng)度達(dá)32位。這樣數(shù)值計(jì)算的將度將得到提島,但代碼氏度將增加,計(jì)算速度也會(huì)降低,所以請(qǐng)?jiān)跈?quán)衡利弊后作岀你自己的決定。11.8.4 C編譯器選項(xiàng)設(shè)定(PICC Compiler)項(xiàng)LJ中所冇的C原程序都將通過(guò)C編譯器編譯成機(jī)器碼,這些選項(xiàng)決定了 C編譯器足 如何匸作的。所有選項(xiàng)乂分為兩組:普通選項(xiàng)(General)和高級(jí)選項(xiàng)(Advanced),分別見(jiàn) 圖

57、11-5A 和 11-5B.C編譯器的普通選項(xiàng)最重要的就是針對(duì)代碼優(yōu)化的設(shè)定。如果沒(méi)有峙殊原憫,應(yīng)該設(shè)定全局優(yōu)化級(jí)別為9級(jí)(最高級(jí)別優(yōu)化),同時(shí)使用匯編級(jí)優(yōu)化,這樣最終得到的代碼效率最 高(長(zhǎng)度和執(zhí)行速度兩方而)按筆者的使用經(jīng)驗(yàn),僅從代碼氏度灰比較,使用昴島級(jí)別優(yōu) 化后代馮民度至少可以減少20% (2K字以上的程序)。而且PICC的優(yōu)化器相為可靠,-般(A)常用選項(xiàng)(B) 高級(jí)選項(xiàng)圖115 C編譯器選項(xiàng)設(shè)定不會(huì)因?yàn)槭褂脙?yōu)化從而使生成的程序出現(xiàn)錯(cuò)誤。碰到的一些問(wèn)題也基本都足用戶編寫(xiě)的原程 序有漏洞所導(dǎo)致,例如-些變僦應(yīng)該足volatile熨但編程員沒(méi)有明福定義,在優(yōu)化詢程序可 以正幣運(yùn)行,一耳使用優(yōu)化,程序運(yùn)行就出現(xiàn)異常。顯然,把出現(xiàn)的這些問(wèn)題歸邢到編譯器 足亳無(wú)道理的。使用優(yōu)化后可能對(duì)廉程序級(jí)的調(diào)試帶來(lái)些不便之處。因PICC可能會(huì)歲組編譯后的代 碼,例如多處重復(fù)的代碼可能會(huì)改成同個(gè)/程序調(diào)用以節(jié)約程序空間,這樣在調(diào)試過(guò)程中 跟蹤原程序時(shí)可能會(huì)也現(xiàn)程序亂跳的現(xiàn)象,這咸本是正常的。若為了強(qiáng)調(diào)更自觀的代碼調(diào)試過(guò)程,你可以將優(yōu)化級(jí)別降低其至關(guān)閉所冇優(yōu)化功能,這樣調(diào)試時(shí)程序的運(yùn)行就可以按部就 班了。C編譯器的

溫馨提示

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

最新文檔

評(píng)論

0/150

提交評(píng)論