單片機(jī)PROTUES仿真c語言_第1頁
單片機(jī)PROTUES仿真c語言_第2頁
單片機(jī)PROTUES仿真c語言_第3頁
單片機(jī)PROTUES仿真c語言_第4頁
單片機(jī)PROTUES仿真c語言_第5頁
已閱讀5頁,還剩193頁未讀, 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

王健帶你征服Pic單片

機(jī)PROTUES仿真C語言部作者多年工作經(jīng)驗的著作講解最全的單片機(jī)C語言程序王健著337884703@前言這個教程最大的特色就是用PROTUES軟件,為讀者省去一大筆開支,真正零開支,所用軟件是MPLABIDE8.63和PICC9.8這本書分為兩部分,雖然是C語言,但是也要講一下單片機(jī)的一些基礎(chǔ)知識,第一部分講單片機(jī)的基礎(chǔ)知識,第二部分講C程序PIC單片機(jī)(PeripheralInterfaceController)是一種用來可開發(fā)的去控制外圍設(shè)備的可編程集成電路(IC)。由美國Microchip(微星)公司推出的PIC單片機(jī)系列產(chǎn)品,首先采用了RISC結(jié)構(gòu)的嵌入式微控制器,其高速度、低電壓、低功耗、大電流LCD驅(qū)動能力和低價位OTP技術(shù)等都體現(xiàn)出單片機(jī)產(chǎn)業(yè)的新趨勢?,F(xiàn)在PIC系列單片機(jī)在世界單片機(jī)市場的份額排名中已逐年升位,尤其在8位單片機(jī)市場,已從1990年的第20位上升到目前的第二位。PIC單片機(jī)從覆蓋市場出發(fā),已有三種(又稱三層次)系列多種型號的產(chǎn)品問世,所以在全球都可以看到PIC單片機(jī)從電腦的外設(shè)、家電控制、電訊通信、智能儀器、汽車電子到金融電子各個領(lǐng)域的廣泛應(yīng)用?,F(xiàn)今的PIC單片機(jī)已經(jīng)是世界上最有影響力的嵌入式微控制器之一。

第一部分認(rèn)識pic單片機(jī)PIC單片機(jī)(PeripheralInterfaceController)是種用來開發(fā)去控制外圍設(shè)備的集成電路(IOo一種具有分散作用(多任務(wù))功能的CPU。與人類相比,大腦就是CPU,PIC共享的部分相當(dāng)于人的神經(jīng)系統(tǒng)。.PIC單片機(jī)是一個小的計算機(jī).PIC單片機(jī)有計算功能和記憶內(nèi)存像CPU并由軟性控制運行。然而,處理能力一般,存儲器容量也很有限,這取決于PIC的類型。但是它們的最高操作頻率大約都在20MHz左右,存儲器容量用做寫程序的大約IK—4K字節(jié)。時鐘頻率與掃描程序的時間和執(zhí)行程序指令的時間有關(guān)系。但不能僅以時鐘頻率來判斷程序處理能力,它還隨處理裝置的體系結(jié)構(gòu)改變(1*)。如果是同樣的體系結(jié)構(gòu),時鐘頻率較高的處理能力會較強。這里用字來解釋程序容量。用一個指令(2*)表示一個字。通常用主芭(3*)來表示存儲器(4*)容量。一個字節(jié)有8位,每位由1或0組成。PIC16F84A單片機(jī)的指令由14位構(gòu)成。當(dāng)把1K個字轉(zhuǎn)換成位為:1xl,024x14

=14,336位。再轉(zhuǎn)換為字節(jié)為:14,336/(8x1,024)=1.75Ko在計算存儲器的容量時,我們規(guī)定1G生苴=1,024M字節(jié),1M字節(jié)=1,024K字節(jié),1K字節(jié)=1,024位.它們不是以1000為倍數(shù),因為這是用二進(jìn)制計算的緣故。1*計算機(jī)的物理結(jié)構(gòu),包括組織結(jié)構(gòu)、容量、該計算機(jī)的CPU、存儲器以及輸入輸出設(shè)備間的互連。經(jīng)常特指CPU的組織結(jié)構(gòu),包括它的寄存器、標(biāo)志、總統(tǒng)、算術(shù)邏輯部件、指令譯碼與執(zhí)行機(jī)制以及定時和控制部件。2*指出某種操作并標(biāo)識其操作數(shù)(如果有操作數(shù)的話)的一種語言構(gòu)造3*作為一個單位來操作(運算)的一個二進(jìn)制字符串,通常比計算機(jī)的一個字短。4*處理機(jī)內(nèi)的所有可尋址存儲空間以及用于執(zhí)行指令的其它內(nèi)存儲器。在計算存儲器的容量時,我們規(guī)定1G字節(jié)=1,024M字節(jié),1M字節(jié)=l,024K字節(jié),1K字節(jié):1,024字節(jié).它們不是以io。。為倍數(shù),因為這是用ma制計算的緣故。用PIC單片機(jī)使電路做的很小巧變得可能。因為PIC單片機(jī)可以把計算部分、內(nèi)存、輸入和輸出等都做在一個芯片內(nèi)。所以她工作起來效率很高、功能也

自由定義還可以靈活的適應(yīng)不同的控制要求,而不必去更換不同的IC。這樣電路才有可能做的很小巧。PIC單片機(jī)型號命名規(guī)則PICXXXXXXXX(X)-XXX/XX12345678.前綴:PICMICROCHIP公司產(chǎn)品代號,特別地:dsPIC為集成DSP功能的新型PIC單片機(jī).系列號:10、12、16、18、24、30、33、32,其中PIC10、PIC12、PIC16、PIC18為8位單片機(jī)PIC24、dsPIC30.dsPIC33為16位單片機(jī)PIC32為32位單片機(jī).器件型號(類型):CCMOS電路CRCMOSROMLC小功率CMOS電路LCS小功率保護(hù)AA1.8VLCR小功率CMOSROMLV低電壓F快閃可編程存儲器HC高速CMOSFRFLEXROM.改進(jìn)類型或選擇54A、58A、61、62、620、621622、63、64、65、71、73、7442、43、44等.晶體標(biāo)不:LP小功率晶體,RC電阻電容,XT標(biāo)準(zhǔn)晶體/振蕩器HS高速晶體.頻率標(biāo)不:-022MHZ,-044MHZ,-1010MHZ,-1616MHZ-2020MHZ,-2525MHZ,-3333MHZ.溫度范圍:空白0℃至70℃,I-45℃至85℃,E-40℃至125℃.封裝形式:LPLCC封裝JW陶瓷熔封雙列直插,有窗口P塑料雙列直插PQ塑料四面引線扁平封裝W大圓片SL14腿微型封裝-150milJN陶瓷熔封雙列直插,無窗口SM8腿微型封裝-207milSN8腿微型封裝-150milVS超微型封裝8mmX13.4mmSO微型封裝-300milST薄型縮小的微型封裝-4.4nunSP橫向縮小型塑料雙列直插CL68腿陶瓷四面引線,帶窗口SS縮小型微型封裝PT薄型四面引線扁平封裝TS薄型微型封裝8mmX20mmTQ薄型四面引線扁平封裝當(dāng)今單片機(jī)廠商琳瑯滿目,產(chǎn)品性能各異。針對具體情況,我們應(yīng)選何種型號呢?首先,我們來弄清兩個概念:集中指令集(CISC)和精簡指令集(RISC)。采用CISC結(jié)構(gòu)的單片機(jī)數(shù)據(jù)線和指令線分時復(fù)用,即所謂馮.諾伊曼結(jié)構(gòu)。它的指令豐富,功能較強,但取指令和取數(shù)據(jù)不能同時進(jìn)行,速度受限,價格亦高。采用RISC結(jié)構(gòu)的單片機(jī)數(shù)據(jù)線和指令線分離,即所謂哈佛結(jié)構(gòu)。這使得取指令和取數(shù)據(jù)可同時進(jìn)行,且由于一般指令線寬于數(shù)據(jù)線,使其指令較同類CISC單片機(jī)指令包含更多的處理信息,執(zhí)行效率更高,速度亦更快。同時,這種單片機(jī)指令多為單字節(jié),程序存儲器的空間利用率大大提高,有利于實現(xiàn)超小型化。屬于CISC結(jié)構(gòu)的單片機(jī)有Intel8051系列、Motorola和M68HC系列、Atmel的AT89系列、臺灣Winbond(華邦)W78系列、荷蘭Pilips的PCF80C51系列等;屬于RISC結(jié)構(gòu)的有Microchip公司的PIC系列、Zilog的Z86系列、Atmel的AT90S系列、韓國三星公司的KS57c系列4位單片機(jī)、臺灣義隆的EM-78系列等。一般來說,控制關(guān)系較簡單的小家電,可以采用RISC型單片機(jī);控制關(guān)系較復(fù)雜的場合,如通訊產(chǎn)品、工業(yè)控制系統(tǒng)應(yīng)采用CISC單片機(jī)。不過,RISC單片機(jī)的迅速完善,使其佼佼者在控制關(guān)系復(fù)雜的場合也毫不遜色。根據(jù)程序存儲方式的不同,單片機(jī)可分為EPROM、OTP(一次可編程)、QTP(掩膜)三種。我國一開始都采用ROMless型單片機(jī)(片內(nèi)無ROM,需片外配EPROM),對單片機(jī)的普及起了很大作用,但這種強調(diào)接口的單片機(jī)無法廣泛應(yīng)用,甚至走入了誤區(qū)。如單片機(jī)的應(yīng)用一味強調(diào)接口,外接I/O及存儲器,便失去了單片機(jī)的特色。目前單片機(jī)大都將程序存儲體置于其內(nèi),給應(yīng)用帶來了極大的方便。值得一提的是,以往OTP型單片機(jī)的價格是QTP的3倍,而現(xiàn)在已降至1.5—L2倍,選用OTP型以免訂貨周期、批量的麻煩是可取的。PIC系列單片機(jī)的優(yōu)勢自從我2006年接觸PIC單片機(jī)以來,便一直熱衷于這種單片機(jī)的開發(fā)與應(yīng)用PIC最大的特點是不搞單純的功能堆積,而是從實際出發(fā),重視產(chǎn)品的性能與價格比,靠發(fā)展多種型號來滿足不同層次的應(yīng)用要求。就實際而言,不同的應(yīng)用對單片機(jī)功能和資源的需求也是不同的。比如,一個摩托車的點火器需要一個I/O較少、RAM及程序存儲空間不大、可靠性較高的小型單片機(jī),若采用40腳且功能強大的單片機(jī),投資大不說,使用起來也不方便。PIC系列從低到高有幾十個型號,可以滿足各種需要。其中,PIC12c508單片機(jī)僅有8個引腳,是世界上最小的單片機(jī)。該型號有512字節(jié)ROM、25字節(jié)RAM、一個8位定時器、一根輸入線、5根I/O線,市面售價在3-6元人人民幣。這樣一款單片機(jī)在象摩托車點火器這樣的應(yīng)用無疑是非常適合。PIC的高檔型號,如PIC16c74(尚不是最高檔型號)有40個引腳,其內(nèi)部資源為ROM共4K、192字節(jié)RAM、8路A/D、3個8位定時器、2個CCP模塊、三個串行口、1個并行口、11個中斷源、33個I/O腳。這樣一個型號可以和其它品牌的高檔型號媲美。精簡指令使其執(zhí)行效率大為提高。PIC系列8位CMOS單片機(jī)具有獨特的RISC結(jié)構(gòu),數(shù)據(jù)總線和指令總線分離的哈佛總線(Harvard)結(jié)構(gòu),使指令具有單字長的特性,且允許指令碼的位數(shù)可多于8位的數(shù)據(jù)位數(shù),這與傳統(tǒng)的采用CISC結(jié)構(gòu)的8位單片機(jī)相比,可以達(dá)到2:1的代碼壓縮,速度提高4倍。產(chǎn)品上市零等待(Zerotimetomarket)0采用PIC的低價OTP型芯片,可使單片機(jī)在其應(yīng)用程序開發(fā)完成后立刻使該產(chǎn)品上市。PIC有優(yōu)越開發(fā)環(huán)境。OTP單片機(jī)開發(fā)系統(tǒng)的實時性是一個重要的指標(biāo),象普通51單片機(jī)的開發(fā)系統(tǒng)大都采用高檔型號仿真低檔型號,其實時性不盡理想。PIC在推出一款新型號的同時推出相應(yīng)的仿真芯片,所有的開發(fā)系統(tǒng)由專用的仿真芯片支持,實時性非常好。就我個人的經(jīng)驗看,還沒有出現(xiàn)過仿真結(jié)果與實際運行結(jié)果不同的情況。其引腳具有防瞬態(tài)能力,通過限流電阻可以接至220V交流電源,可直接與繼電器控制電路相連,無須光電耦合器隔離,給應(yīng)用帶來極大方便。徹底的保密性。PIC以保密熔絲來保護(hù)代碼,用戶在燒入代碼后熔斷熔絲,別人再也無法讀出,除非恢復(fù)熔絲。目前,PIC采用熔絲深埋工藝,恢復(fù)熔絲的可能性極小。自帶看門狗定時器,可以用來提高程序運行的可靠性。睡眠和低功耗模式。雖然PIC在這方面已不能與新型的TI—MSP430相比,但在大多數(shù)應(yīng)用場合還是能滿足需要的。Microchip基于精簡指令集計算(RISC)的PlCmicro系列單片機(jī)是為要求高性能而低價格的用戶設(shè)計的。PlCmicro系列單片機(jī)家族由130多種產(chǎn)品組成,集多種存儲器配置,低電壓低功率,小引腳及易于使用等多種特點于一身。在我們8位MCU引腳的微小空間里封裝有大量的信息。隨著您設(shè)計的復(fù)雜化,您所寫的程序代碼以后可以輕易地轉(zhuǎn)換到具有更多外圍資源的較大的MicrochipMCU中去。PlCmicroMCU家族中的所有產(chǎn)品都是無間隙過渡的,在嵌入式設(shè)計中可完全向上兼容。如果您已經(jīng)知道設(shè)計應(yīng)用產(chǎn)品所需的單片機(jī)規(guī)格,您就可通過Microchip的參數(shù)搜索引擎按照相應(yīng)的條件進(jìn)行搜索并選用相應(yīng)的產(chǎn)品。在您的選擇過程中所需用到的條件為:編程存儲器大小,數(shù)據(jù)RAM,存儲器類型以及封裝類型。如果您對Microchip的PlCmicroMCU還不熟悉的話,以下介紹將幫助您了解。PlCmicroMCU將高性能,低價格,封裝尺寸小,提供最高性價比等特點集于一身,提供5個家族的8位單片機(jī)產(chǎn)品,以最好地滿足您的需要。PIC12CXXX家族:8引腳12/14位程序詞PIC12CXXX家族產(chǎn)品為Microchip功能強大的基于RISC的PlCmicro系列8引腳DIP及SOIC封裝。PIC12CXXX產(chǎn)品具有12或14位寬指令集,2.5V低運行電壓,小封裝引腳,中斷處理,深硬件堆棧,多通道以及EEPR0M數(shù)據(jù)存儲器。這些智能級特性由于價格與尺寸的原因在以前的產(chǎn)品中是不具備的。PIC16c5X家族:12位程序詞PIC16C5X家族具有全套基礎(chǔ)產(chǎn)品,為您提供最有效的價格解決方案。PIC16c5X產(chǎn)品具備12位寬指令集,目前提供14,18,20及28引腳封裝。在選用SOIC與SSOP封裝時,產(chǎn)品的引腳所占據(jù)的空間是最小的。低至2.0V運行的低壓OTPMCU使產(chǎn)品成為電池驅(qū)動應(yīng)用產(chǎn)品的理想選擇。另外,PIC16HV5XX在直接應(yīng)用電池時最高可運行至15VoPIC16CXXX家族:14位程序詞在推出了新的PIC16CXXX家族成員后,Microchip現(xiàn)已在該產(chǎn)業(yè)中具備向單片機(jī)提供最高性能的12位模擬數(shù)字轉(zhuǎn)換器能力的供應(yīng)商。PIC16CXXX家族可提供從18引腳至68引腳封裝,以及由低級至高級的外圍集成的一系列產(chǎn)品。該家族具備14位寬指令集,中斷處理能力及8級硬件深堆棧。PIC16XXX家族提供了高性能及多功能的中檔應(yīng)用產(chǎn)品,以適應(yīng)當(dāng)今市場的價格競爭。PIC17CXXX家族:16位程序詞PIC17CXXX家族將PlCmicroMCU的高性能RISC結(jié)構(gòu)擴(kuò)展為16位指令詞,增強型指令集與強大的矢量中斷處理能力。強大的隊列式精確在片外設(shè)特性提供了能適應(yīng)更多應(yīng)用場合的各種性能。PIC18CXXX家族:增強型16位程序詞PIC18CXXX家族產(chǎn)品具有高性能,CMOS,集成了模擬數(shù)字(A/D)轉(zhuǎn)換器的全靜態(tài)MCU等特點。所有PIC18CXXX的MCU均應(yīng)用了先進(jìn)的RISCoPIC18CXXX具備增強型中心特性,32位深堆棧,以及內(nèi)外多中斷源。Harvard系列中的分離指令與數(shù)據(jù)總線允許16位寬指令詞與獨立8位寬數(shù)據(jù)。兩級指令通道允許所有指令在一個周期內(nèi)執(zhí)行,除非子程序中設(shè)定必須在兩個周期內(nèi)完成。精簡指令集共有77條指令。另外,一個大寄存器組使采用了結(jié)構(gòu)性創(chuàng)新的MCU達(dá)到10MIPS的極高的性能。PIC18CXXX家族具備的特殊特性能減少外部組件以降低成本,增強系統(tǒng)可靠性并降低功耗。這些特性包括可編程低壓檢測(LVD)及可編程Brown-Out檢測(BOD)PIC單片機(jī)C語言編程簡介用C語言來開發(fā)單片機(jī)系統(tǒng)軟件最大的好處是編寫代碼效率高、軟件調(diào)試直觀、維護(hù)升級方便、代碼的重復(fù)利用率高、便于跨平臺的代碼移植等等,因此c語言編程在單片機(jī)系統(tǒng)設(shè)計中已得到越來越廣泛的運用。針對PIC單片機(jī)的軟件開發(fā),同樣可以用C語百實現(xiàn)。但在單片機(jī)上用C語言寫程序和在PC機(jī)上寫程序絕對不能簡單等同?,F(xiàn)在的PC機(jī)資源十分豐富,運算能力強大,因此程序員在寫PC機(jī)的應(yīng)用程序時幾乎不用關(guān)心編譯后的可執(zhí)行代碼在運行過程中需要占用多少系統(tǒng)資源,也基本不用擔(dān)心運行效率有多高。寫單片機(jī)的C程序最關(guān)鍵的一點是單片機(jī)內(nèi)的資源非常有限,控制的實時性要求又很高,因此,如果沒有對單片機(jī)體系結(jié)構(gòu)和硬件資源作詳盡的了解,以筆者的愚見認(rèn)為是無法寫出高質(zhì)量實用的C語言程序。這就是為什么前面所有章節(jié)中的的示范代碼全部用基礎(chǔ)的匯編指令實現(xiàn)的原因,希望籍此能使讀者對PIC單片機(jī)的指令體系和硬件資源有深入了解,在這基礎(chǔ)之上再來討論c語言編程,就有水到渠成的感覺。本書圍繞中檔系列PIC單片機(jī)來展開討論,Microchip公司自己沒有針對中低檔系列PIC單片機(jī)的C語言編譯器,但很多專業(yè)的第三方公司有眾多支持PIC單片機(jī)的C語言編譯器提供,常見的有Hitech、CCS>IAR、Bytecraft等公司。其中筆者最常用的是Hitech公司的PICC編譯器,它穩(wěn)定可靠,編譯生成的代碼效率高,在用PIC單片機(jī)進(jìn)行系統(tǒng)設(shè)計和開發(fā)的工程師群體中得到廣泛認(rèn)可。其正式完全版軟件需要購

置,但在其網(wǎng)站上有限時的試用版供用戶評估。另外,Hitech公司針對廣大PIC的業(yè)余愛好者和初學(xué)者還提供了完全免費的學(xué)習(xí)版PICC-Lite編譯器套件,它的使用方式和完全版相同,只是支持的PIC單片機(jī)型號限制在PIC16F84、PIC16F877和PIC16F628等幾款。這幾款Flash型的單片機(jī)因其所具備的豐富的片上資源而最適用于單片機(jī)學(xué)習(xí)入門,因此筆者建議感興趣的讀者可從PICC-Lite入手掌握PIC單片機(jī)的C語言編程。在此列出幾個主要的針對PIC單片機(jī)的C編譯器相關(guān)連接網(wǎng)址,供讀者參考:Hitech-PICC:Hitech-PICC:IAR:CCS:/picc.shtmlByteCraft:www.bytecraft,com/mpccaps.html本章將介紹Hitech-PICC編譯器的一些基本概念,由于篇幅所限將不涉及C語言的標(biāo)準(zhǔn)語法和基礎(chǔ)知識介紹,因為在這些方面都有大量的書籍可以參考。重點突出針對PIC單片機(jī)的特點而所需要特別注意的地方。11.2Hitech-PICC編譯器PICC基本上符合ANSI標(biāo)準(zhǔn),除了一點:它不支持函數(shù)的遞歸調(diào)用。其主要原因是因為Pic單片機(jī)特殊的堆棧結(jié)構(gòu)。在前面介紹PIC單片機(jī)架構(gòu)時已經(jīng)詳細(xì)說明了PIC單片機(jī)中的堆棧是硬件實現(xiàn)的,其深度已隨芯片而固定,無法實現(xiàn)需要大量堆棧操作的遞歸算法;另外在PIC單片機(jī)中實現(xiàn)軟件堆棧的效率也不是很高,為此,PICC編譯器采用一種叫做“靜態(tài)覆蓋”的技術(shù)以實現(xiàn)對 c語言函數(shù)中的局部變量分配固定的地址空間。經(jīng)這樣處理后產(chǎn)生出的機(jī)器代碼效率很高,按筆者實際使用的體會,當(dāng)代碼量超過4K字后,C語言編譯出的代碼長度和全部用匯編代碼實現(xiàn)時的差別已經(jīng)不是很大(<10%),當(dāng)然前提是在整個C代碼編寫過程中須時時處處注意所編寫語句的效率,而如果沒有對PIC單片機(jī)的內(nèi)核結(jié)構(gòu)、各功能模塊及其匯編指令深入了解,要做到這點是很難的。11.3MPLAB-IDE內(nèi)掛接PICCPICC編譯器可以直接掛接在MPLAB-IDE集成開發(fā)平臺下,實現(xiàn)一體化的編譯連接和原代碼調(diào)試。使用MPLAB-IDE內(nèi)的調(diào)試工具ICE2000>ICD2和軟件模擬器都可以實現(xiàn)原代碼級的程序調(diào)試,非常方便。首先必須在你的計算機(jī)中安裝PICC編譯器,無論是完全版還是學(xué)習(xí)版都可以和MPLAB-IDE掛接。安裝成功后可以進(jìn)入IDE,選擇菜單項ProjectSetLanguageToolLocations…,打開語言工具掛接設(shè)置對話框,如圖11-1所示:圖11-1MPLAB-IDE語言工具設(shè)置對話框在對話框中選擇“HI-TECHPICCToolsuite”欄,展開可執(zhí)行文件組“Executable”后,列出了將被MPLAB-IDE 后臺調(diào)用的編譯器所用到的所有可執(zhí)行文件,其中有匯編編譯器“PPCCAssembler">C原程序編譯器“PICCCompiler”和連接定位程序“PICCLinker”。同時在此列表中還顯示了對應(yīng)的可執(zhí)行程序名,請注意在這里都是都是C.EXE"。用鼠標(biāo)分別點擊選中這三項可執(zhí)行文件,觀察對話框下面“Location”一欄中顯示的文件路徑,用“Browse…”按紐,從計算機(jī)中已經(jīng)安裝的PICC編譯器文件夾中選擇PICC.EXE文件。實際上PICC.EXE只是一個調(diào)度管理程序,它會按照所輸入的文件擴(kuò)展名自動調(diào)用對應(yīng)的編譯器和連接器,用戶要注意的是C語言原程序擴(kuò)展名用“.c”,匯編原程序用“.as”即可。工具掛接完成后,在建立項目時可以選擇語言工具為“HI-TECHPICC”,具體步驟可以參閱第三章3.1.3節(jié),此處不再重復(fù)。項目建立完成后可以加入C或匯編原程序,也可以加入已有的庫文件或已經(jīng)編譯的目標(biāo)文件。最常見的是只加入C原程序。用C語言編程的好處是可以實現(xiàn)模塊化編程。程序編寫者應(yīng)盡量把相互獨立的控制任務(wù)用多個獨立的c原程序文件實現(xiàn),如果程序量較大,一般不要把所有的代碼寫在一個文件內(nèi)。圖11-2列出的是筆者建立的一個項目中所有C原程序模塊,其中主控、數(shù)值計算、12c總線操作、命令按鍵處理和液晶顯示驅(qū)動等不同的功能分別在不同的獨立的原程序模塊中實現(xiàn)。圖11-2C語言多模塊編程PIC單片機(jī)的C語言原程序基本框架基于PICC編譯環(huán)境編寫PIC單片機(jī)程序的基本方式和標(biāo)準(zhǔn)C程序類似,程序一般由以下幾個主要部分組成:&01540; 在程序的最前面用#include預(yù)處理指令引用包含頭文件,其中必須包含一個編譯器提供的“pic.h”文件,實現(xiàn)單片機(jī)內(nèi)特殊寄存器和其它特殊符號的聲明;

&01540;用&01540;用“_CONFIG”預(yù)處理指令定義芯片的配置位;&01540; 聲明本模塊內(nèi)被調(diào)用的所有函數(shù)的類型,PICC將對所調(diào)用的函數(shù)進(jìn)行嚴(yán)格的類型匹配檢查;&01540; 定義全局變量或符號替換;&01540; 實現(xiàn)函數(shù)(子程序),特別注意main函數(shù)必須是一個沒有返回的死循環(huán)。下面的例11-1為一個C原程序的范例,供大家參考。ftinclude 〃包含單片機(jī)內(nèi)部資源預(yù)定義ftinclude“pc68.h”〃包含自定義頭文件〃定義芯片工作時的配置位CONFIG(HS&PROTECT&PWRTEN&BOREN&WDTDIS);〃聲明本模塊中所調(diào)用的函數(shù)類型voidSetSFR(void);voidClock(void);voidKeyScan(void);voidMeasure(void);voidLCDTest(void);voidLCDDisp(unsignedchar);〃定義變量unsignedcharsecond,minute,hour;bitflagl,flag2;〃函數(shù)和子程序voidmain(void){SetSFR();PORTC=0x00;TMR1H+:TMR1H_CONST;LED1=LED_OFF;LCD_Test();〃程序工作主循環(huán)while(1){asm("clrwdt");Clock();KeyScan();Measure();SetSFRO;〃清看門狗〃更新時鐘〃掃描鍵盤〃數(shù)據(jù)測量〃刷新特殊功能寄存器11.5PICC中的變量定義例11-1C語言原程序框架舉例.1PICC中的基本變量類型PICC遵循Little-endian標(biāo)準(zhǔn),多字節(jié)變量的低字節(jié)放在存儲空間的低地址,高字節(jié)放在IW]地址。PICC中的高級變量基于表11-1的基本變量,除了bit型位變量外,PICC完全支持?jǐn)?shù)組、結(jié)構(gòu)和聯(lián)合等復(fù)合型高級變量,這和標(biāo)準(zhǔn)的C語言所支持的高級變量類型沒有什么區(qū)別。例如:數(shù)組:unsignedintdata[10];結(jié)構(gòu):structcommlnData{unsignedcharinBuff[8];unsignedchargetPtr,putPtr;};聯(lián)合:unionintByte{unsignedcharc⑵;unsignedinti;};例11-2C語言高級變量舉例PICC對數(shù)據(jù)寄存器bank的管理為了使編譯器產(chǎn)生最高效的機(jī)器碼,PICC把單片機(jī)中數(shù)據(jù)寄存器的bank問題交由編程員自己管理,因此在定義用戶變量時你必須自己決定這些變量具體放在哪一個bank中。如果沒有特別指明,所定義的變量將被定位在bankO,例如下面所定義的這些變量:unsignedcharbuffer[32];bitflagl,flag2;floatval[8];除了bankO內(nèi)的變量聲明時不需特殊處理外,定義在其它bank內(nèi)的變量前面必須加上相應(yīng)的bank序號,例如:banklunsignedcharbuffer[32]; 〃變量定位在bankl中bank2bitflagl,flag2;bank3floatval[8];〃變量定位在bank2中〃變量定位在bank3中中檔系列PIC單片機(jī)數(shù)據(jù)寄存器的一個bank大小為128字節(jié),刨去前面若干字節(jié)的特殊功能寄存器區(qū)域,在C語言中某一bank內(nèi)定義的變量字節(jié)總數(shù)不能超過可用RAM字節(jié)數(shù)。如果超過bank容量,在最后連接時會報錯,大致信息如下:Error[000] :Can'tfind0xl2Cwordsforpsectrbss_linsegmentBANK1連接器告訴你總共有0xl2C(300)個字節(jié)準(zhǔn)備放到bankl中但bankl容量不夠。顯然,只有把一部分原本定位在bankl中的變量改放到其它bank中才能解決此問題。雖然變量所在的bank定位必須由編程員自己決定,但在編寫原程序時進(jìn)行變量存取操作前無需再特意編寫設(shè)定bank的指令。C編譯器會根據(jù)所操作的對象自動生成對應(yīng)bank設(shè)定的匯編指令。為避免頻繁的bank切換以提高代碼效率,盡量把實現(xiàn)同一任務(wù)的變量定位在同一個bank內(nèi);對不同bank內(nèi)的變量進(jìn)行讀寫操作時也盡量把位于相同bank內(nèi)的變量歸并在一起進(jìn)行連續(xù)操作。PICC中的局部變量PICC把所有函數(shù)內(nèi)部定義的auto型局部變量放在bankOo為節(jié)約寶貴的存儲空間,它采用了一種被叫做“靜態(tài)覆蓋”的技術(shù)來實現(xiàn)局部變量的地址分配。其大致的原理是在編譯器編譯原代碼時掃描整個程序中函數(shù)調(diào)用的嵌套關(guān)系和層次,算出每個函數(shù)中的局部變量字

節(jié)數(shù),然后為每個局部變量分配一個固定的地址,且按調(diào)用嵌套的層次關(guān)系各變量的地址可以相互重疊。利用這一技術(shù)后所有的動態(tài)局部變量都可以按已知的固定地址地進(jìn)行直接尋址,用PIC匯編指令實現(xiàn)的效率最高,但這時不能出現(xiàn)函數(shù)遞歸調(diào)用。PICC在編譯時會嚴(yán)格檢查遞歸調(diào)用的問題并認(rèn)為這是一個嚴(yán)重錯誤而立即終止編譯過程。既然所有的局部變量將占用banko的存儲空間,因此用戶自己定位在bankO內(nèi)的變量字節(jié)數(shù)將受到一定的限制,在實際使用時需注意。11.5.511.5.5PICC中的位變量bit型位變量只能是全局的或靜態(tài)的。PICC將把定位在同一bank內(nèi)的8個位變量合并成一個字節(jié)存放于一個固定地址。因此所有針對位變量的操作將直接使用PIC單片機(jī)的位操作匯編指令高效實現(xiàn)?;诖耍蛔兞坎荒苁蔷植孔詣有妥兞?,也無法將其組合成復(fù)合型高級變量。PICC對整個數(shù)據(jù)存儲空間實行位編址,0x000單元的第0位是位地址0x0000,以此后推,每個字節(jié)有8個位地址。編制位地址的意義純粹是為了編譯器最后產(chǎn)生匯編級位操作指令而用,對編程人員來說基本可以不管。但若能了解位變量的位地址編址方式就可以在最后程序調(diào)試時方便地查找自己所定義的位變量,如果一個位變量flagl被編址為0x123,那么實際的存儲空間位于:字節(jié)地址=0x123/8=0x24位偏移=0xl23%8=3即flagl位變量位于地址為0x24字節(jié)的第3位。在程序調(diào)試時如果要觀察flagl的變化,必須觀察地址為0x24的字節(jié)而不是0xl23oPIC單片機(jī)的位操作指令是非常高效的。因此,PICC在編譯原代碼時只要有可能,對普通變量的操作也將以最簡單的位操作指令來實現(xiàn)。假設(shè)一個字節(jié)變量tmp最后被定位在地址0x20,那么tmp|-0x80tmp&=0xf7=>bsf=>bcf0x20,70x20,3if(tmp&Oxfe)=>btfsc0x20,0即所有只對變量中某一位操作的C語句代碼將被直接編譯成匯編的位操作指令。雖然編程時可以不用太關(guān)心,但如果能了解編譯器是如何工作的,那將有助于引導(dǎo)我們寫出高效簡介的C語言原程序。在有些應(yīng)用中需要將一組位變量放在同一個字節(jié)中以便需要時一次性地進(jìn)行讀寫,這一功能可以通過定義一個位域結(jié)構(gòu)和一個字節(jié)變量的聯(lián)合來實現(xiàn),例如:union{struct{unsignedbO:1;unsignedbl:1;unsignedb2:1;unsignedb3:1;unsignedb4:1;unsignedb5:1;unsigned:2;〃最高兩位保留}oneBit;unsignedcharallBits;}myFlag;例11-3 定義位變量于同一字節(jié)需要存取其中某一位時可以myFlag.oneBit.b3=l;//b3位置1一次性將全部位清零時可以myFlag.allBits=0; 〃全部位變量清0當(dāng)程序中把非位變量進(jìn)行強制類型轉(zhuǎn)換成位變量時,要注意編譯器只對普通變量的最低位做判別:如果最低位是0,則轉(zhuǎn)換成位變量0;如果最低位是1,則轉(zhuǎn)換成位變量lo而標(biāo)準(zhǔn)的ANSI-C做法是判整個變量值是否為0o另外,函數(shù)可以返回一個位變量,實際上此返回的位變量將存放于單片機(jī)的進(jìn)位位中帶出返回。11.5.6PICC中的浮點數(shù)PICC中描述浮點數(shù)是以IEEE-754標(biāo)準(zhǔn)格式實現(xiàn)的。此標(biāo)準(zhǔn)下定義的浮點數(shù)為32位長,在單片機(jī)中要用4個字節(jié)存儲。為了節(jié)約單片機(jī)的數(shù)據(jù)空間和程序空間,PICC專門提供了

一種長度為24位的截短型浮點數(shù),它損失了浮點數(shù)的一點精度,但浮點運算的效率得以提高。在程序中定義的float型標(biāo)準(zhǔn)浮點數(shù)的長度固定為24位,雙精度double型浮點數(shù)一般也是24位長,但可以在程序編譯選項中選擇double型浮點數(shù)為32位,以提高計算的精度。一般控制系統(tǒng)中關(guān)心的是單片機(jī)的運行效率,因此在精度能夠滿足的前提下盡量選擇24位的浮點數(shù)運算。11.5.7PICC11.5.7PICC中變量的絕對定位首先必須強調(diào),在用c語言寫程序時變量一般由編譯器和連接器最后定位,在寫程序之時無需知道所定義的變量具體被放在哪個地址(除了bank必須聲明)。真正需要絕對定位的只是單片機(jī)中的那些特殊功能寄存器,而這些寄存器的地址定位在PICC編譯環(huán)境所提供的頭文件中已經(jīng)實現(xiàn),無需用戶操心。編程員所要了解的也就是PICC是如何定義這些特殊功能寄存器和其中的相關(guān)控制位的名稱。好在PICC的定義標(biāo)準(zhǔn)基本上按照芯片的數(shù)據(jù)手冊中的名稱描述進(jìn)行,這樣就秉承了變量命名的一貫性。一個變量絕對定位的例子如下:unsignedchartmpData@0x20;//tmpData定位在地址0x20千萬注意,PICC對絕對定位的變量不保留地址空間。換句話說,上面變量tmpData的地址是0x20,但最后0x20處完全有可能又被分配給了其它變量使用,這樣就發(fā)生了地址沖突。因此針對變量的絕對定位要特別小心。從筆者的應(yīng)用經(jīng)驗看,在一般的程序設(shè)計中用戶自定義的變量實在是沒有絕對定位的必要。如果需要,位變量也可以絕對定位。但必須遵循上面介紹的位變量編址的方式。如果一個普通變量已經(jīng)被絕對定位,那么此變量中的每個數(shù)據(jù)位就可以用下面的計算方式實現(xiàn)位變

量指派://tmpData定位在地址unsignedchartmpData@0x20//tmpData定位在地址0x20bittmpBitO@tmpData*8+0;//tmpBitObittmpBitO@tmpData*8+0;//tmpBitO對應(yīng)于tmpData第0位//tmpBitO對應(yīng)于//tmpBitO//tmpBitO對應(yīng)于//tmpBitO對應(yīng)于tmpData第1位bittmpBit2@tmpData*8+2;tmpData第2位如果tmpData事先沒有被絕對定位,那就不能用上面的位變量定位方式。

11.5.8PICC11.5.8PICC的其它變量修飾關(guān)鍵詞&01540;extern一外部變量聲明如果在一個C程序文件中要使用一些變量但其原型定義寫在另外的文件中,那么在本文件中必須將這些變量聲明成"extern”外部類型。例如程序文件codel.c中有如下定義:banklunsignedcharvarl,var2;〃定義了bankl中的兩個變量在另外一個程序文件code2.c中要對上面定義的變量進(jìn)行操作,則必須在程序的開頭定義:externbanklunsignedcharvarl,var2; 〃聲明位于bankl的外部變量&01540;volatile一易變型變量聲明PICC中還有一個變量修飾詞在普通的C語言介紹中一般是看不到的,這就是關(guān)鍵詞"volatile"o顧名思義,它說明了一個變量的值是會隨機(jī)變化的,即使程序沒有刻意對它進(jìn)行任何賦值操作。在單片機(jī)中,作為輸入的10端口其內(nèi)容將是隨意變化的;在中斷內(nèi)被修改的變量相對主程序流程來講也是隨意變化的;很多特殊功能寄存器的值也將隨著指令的運行而動態(tài)改變。所有這種類型的變量必須將它們明確定義成“volatile”類型,例如:volatileunsignedcharSTATUS@0x03;volatilebitcommFlag;"volatile"類型定義在單片機(jī)的 C語言編程中是如此的重要,是因為它可以告訴編譯器的優(yōu)化處理器這些變量是實實在在存在的,在優(yōu)化過程中不能無故消除。假定你的程序定義了一個變量并對其作了一次賦值,但隨后就再也沒有對其進(jìn)行任何讀寫操作,如果是非volatile型變量,優(yōu)化后的結(jié)果是這個變量將有可能被徹底刪除以節(jié)約存儲空間。另外一種情形是在使用某一個變量進(jìn)行連續(xù)的運算操作時,這個變量的值將在第一次操作時被復(fù)制到中間臨時變量中,如果它是非volatile型變量,則緊接其后的其它操作將有可能直接從臨時變量中取數(shù)以提高運行效率,顯然這樣做后對于那些隨機(jī)變化的參數(shù)就會出問題。只要將其定義成volatile類型后,編譯后的代碼就可以保證每次操作時直接從變量地址處取數(shù)。

&01540;const&01540;const—常數(shù)型變量聲明如果變量定義前冠以“const”類型修飾,那么所有這些變量就成為常數(shù),程序運行過程中不能對其修改。除了位變量,其它所有基本類型的變量或高級組合變量都將被存放在程序空間(ROM區(qū))以節(jié)約數(shù)據(jù)存儲空間。顯然,被定義在ROM區(qū)的變量是不能再在程序中對其進(jìn)行賦值修改的,這也是“const”的本來意義。實際上這些數(shù)據(jù)最終都將以“retlw”的指令形式存放在程序空間,但PICC會自動編譯生成相關(guān)的附加代碼從程序空間讀取這些常數(shù),編程員無需太多操心。例如:constunsignedcharname口=“Thisisademo";//定義一個常量字符串如果定義了“const”類型的位變量,那么這些位變量還是被放置在RAM中,但程序不能對其賦值修改。本來,不能修改的位變量沒有什么太多的實際意義,相信大家在實際編程時不會大量用到。&01540;persistent一 非初始化變量聲明按照標(biāo)準(zhǔn)C語言的做法,程序在開始運行前首先要把所有定義的但沒有預(yù)置初值的變量全部清零。PICC會在最后生成的機(jī)器碼中加入一小段初始化代碼來實現(xiàn)這一變量清零操作,且這一操作將在main函數(shù)被調(diào)用之前執(zhí)行。問題是作為一個單片機(jī)的控制系統(tǒng)有很多變量是不允許在程序復(fù)位后被清零的。為了達(dá)到這一目的,PICC提供了“persistent”修飾詞以聲明此類變量無需在復(fù)位時自動清零,編程員應(yīng)該自己決定程序中的那些變量是必須聲明成“persisten”類型,而且須自己判斷什么時候需要對其進(jìn)行初始化賦值。例如:persistentunsignedcharhour,minute,second;〃定義時分秒變量經(jīng)常用到的是如果程序經(jīng)上電復(fù)位后開始運行,那么需要將persistent型的變量初始化,如果是其它形式的復(fù)位,例如看門狗引發(fā)的復(fù)位,則無需對persistent型變量作任何修改。PIC單片機(jī)內(nèi)提供了各種復(fù)位的判別標(biāo)志,用戶程序可依具體設(shè)計靈活處理不同的復(fù)位情形。11.5.9PICC中的指針PICC中指針的基本概念和標(biāo)準(zhǔn)C語法沒有太多的差別。但是在PIC單片機(jī)這一特定的架構(gòu)上,指針的定義方式還是有幾點需要特別注意。&01540;指向RAM的指針如果是匯編語言編程,實現(xiàn)指針尋址的方法肯定就是用FSR寄存器,PICC也不例外。為了生成高效的代碼,PICC在編譯C原程序時將指向RAM的指針操作最終用FSR來實現(xiàn)間接尋址。這樣就勢必產(chǎn)生一個問題:FSR能夠直接連續(xù)尋址的范圍是256字節(jié)(bankO/1或bank2/3),要覆蓋最大512字節(jié)的內(nèi)部數(shù)據(jù)存儲空間,又該如何讓定義指針?PICC還是將這一問題留給編程員自己解決:在定義指針時必須明確指定該指針?biāo)m用的尋址區(qū)域,例如:unsignedchar*ptrO;〃①定義覆蓋bankO/1的指針bank2unsignedchar*ptrl;〃②定義覆蓋bank2/3的指針bank3unsignedchar*ptr2;〃③定義覆蓋bank2/3的指針上面定義了三個指針變量,其中①指針沒有任何bank限定,缺省就是指向bankO和bankl;②和③一個指明了bank2,另一個指明了bank3,但實際上兩者是一樣的,因為一個指針可以同時覆蓋兩個bank的存儲區(qū)域。另外,上面三個指針變量自身都存放在bankO中。我們將在稍后介紹如何在其它bank中存放指針變量。既然定義的指針有明確的bank適用區(qū)域,在對指針變量賦值時就必須實現(xiàn)類型匹配,F(xiàn)面的指針賦值將產(chǎn)生一個致命錯誤:unsignedchar*ptrO;bank2unsignedcharbuff[8];程序語句:〃定義指向bankO/1的指針〃定義bank2中的一個緩沖區(qū)ptrO二buff;〃錯誤!試圖將bank2內(nèi)的變量地址賦給指向bankO/1的指針若出現(xiàn)此類錯誤的指針操作,PICC在最后連接時會告知類似于下面的信息:Fixupoverflowinexpression(...)同樣的道理,若函數(shù)調(diào)用時用了指針作為傳遞參數(shù),也必須注意bank作用域的匹配,而這點往往容易被忽視。假定有下面的函數(shù)實現(xiàn)發(fā)送一個字符串的功能:voidSendMessage(unsignedchar*);那么被發(fā)送的字符串必須位于bankO或bankl中。如果你還要發(fā)送位于bank2或bank3內(nèi)的字符串,必須再另外單獨寫一個函數(shù):voidSendMessage_2(bank2unsignedchar*);這兩個函數(shù)從內(nèi)部代碼的實現(xiàn)來看可以一模一樣,但傳遞的參數(shù)類型不同。按筆者的應(yīng)用經(jīng)驗體會,如果你看到了“Fixupoverflow"的錯誤指示,幾乎可以肯定是指針類型不匹配的賦值所至。請重點檢查程序中有關(guān)指針的操作。&01540;指向ROM常數(shù)的指針如果一組變量是已經(jīng)被定義在ROM區(qū)的常數(shù),那么指向它的指針可以這樣定義:constunsignedcharcompany[]=vMicrochipvconstunsignedchar*romPtr;程序中可以對上面的指針變量賦值和實現(xiàn)取數(shù)操作:romPtr=company;〃指針賦初值data=*romPtr++;〃取指針指向的一個數(shù),然后指針加1〃定義ROM中的常數(shù)〃定義指向ROM的指針反過來,下面的操作將是一個錯誤,因為該指針指向的是常數(shù)型變量,不能賦值。*romPtr=data;〃往指針指向的地址寫一個數(shù)&01540; 指向函數(shù)的指針單片機(jī)編程時函數(shù)指針的應(yīng)用相對較少,但作為標(biāo)準(zhǔn)C語法的一部分,PICC同樣支持函數(shù)指針調(diào)用。如果你對編譯原理有一定的了解,就應(yīng)該明白在PIC單片機(jī)這一特定的架構(gòu)上實現(xiàn)函數(shù)指針調(diào)用的效率是不高的:PICC將在RAM中建立一個調(diào)用返回表,真正的調(diào)用和返回過程是靠直接修改PC指針來實現(xiàn)的。因此,除非特殊算法的需要,建議大家盡量不要使用函數(shù)指針。&01540; 指針的類型修飾前面介紹的指針定義都是最基本的形式。和普通變量一樣,指針定義也可以在前面加上特殊類型的修飾關(guān)鍵詞,例如“persistent”、"volatile"等??紤]指針本身還要限定其作用域,因此PICC中的指針定義初看起來顯得有點復(fù)雜,但只要了解各部分的具體含義,理解一個指針的實際用圖就變得很直接。㈠bank修飾詞的位置含義前面介紹的一些指針有的作用于bankO/1,有的作用于bank2/3,但它們本身的存放位置全部在bankOo顯然,在一個程序設(shè)計中指針變量將有可能被定位在任何可用的地址空間,這時,bank修飾詞出現(xiàn)的位置就是一個關(guān)鍵,看下面的例子:〃定義指向bankO/1的指針,指針變量為于bankO中unsignedchar*ptrO;〃定義指向bank2/3的指針,指針變量為于bankO中bank2unsignedchar*ptrO;〃定義指向bank2/3的指針,指針變量為于bankl中bank2unsignedchar*banklptrO;從中可以看出規(guī)律:前面的bank修飾詞指明了此指針的作用域;后面的bank修飾詞定義了此指針變量自身的存放位置。只要掌握了這一法則,你就可以定義任何作用域的指針且可以將指針變量放于任何bank中。㈡volatile、persistent和const修飾詞的位置含義如果能理解上面介紹的bank修飾詞的位置含義,實際上volatile>persistent和const這些關(guān)鍵詞出現(xiàn)在前后不同位置上的含義規(guī)律是和bank一詞相一致的。例如:〃定義指向bankO/1易變型字符變量的指針,指針變量位于bankO中且自身為非易變型volatileunsignedchar*ptrO;〃定義指向bank2/3非易變型字符變量的指針,指針變量位于bankl中且自身為易變型bank2unsignedchar*volatilebanklptrO;〃定義指向ROM區(qū)的指針,指針變量本身也是存放于ROM區(qū)的常數(shù)constunsignedchar*constptrO;亦即出現(xiàn)在前面的修飾詞其作用對象是指針?biāo)柑幍淖兞浚怀霈F(xiàn)在后面的修飾詞其作用對象就是指針變量自己。11.6PICC中的子程序和函數(shù)中檔系列的PIC單片機(jī)程序空間有分頁的概念,但用C語言編程時基本不用太多關(guān)心代碼的分頁問題。因為所有函數(shù)或子程序調(diào)用時的頁面設(shè)定(如果代碼超過一個頁面)都由編譯器自動生成的指令實現(xiàn)。11.6.1函數(shù)的代碼長度限制PICC決定了C原程序中的一個函數(shù)經(jīng)編譯后生成的機(jī)器碼一定會放在同一個程序頁面內(nèi)。中檔系列的PIC單片機(jī)其一個程序頁面的長度是2K字,換句話說,用C語言編寫的任何一個函數(shù)最后生成的代碼不能超過2K字。一個良好的程序設(shè)計應(yīng)該有一個清晰的組織結(jié)構(gòu),把不同的功能用不同的函數(shù)實現(xiàn)是最好的方法,因此一個函數(shù)2K字長的限制一般不會對程序代碼的編寫產(chǎn)生太多影響。如果為實現(xiàn)特定的功能確實要連續(xù)編寫很長的程序,這時就必須把這些連續(xù)的代碼拆分成若干函數(shù),以保證每個函數(shù)最后編譯出的代碼不超過一個頁面空間。11.6.2調(diào)用層次的控制中檔系列PIC單片機(jī)的硬件堆棧深度為8級,考慮中斷響應(yīng)需占用一級堆棧,所有函數(shù)調(diào)用嵌套的最大深度不要超過7級。編程員必須自己控制子程序調(diào)用時的嵌套深度以符合這一限制要求。PICC在最后編譯連接成功后可以生成一個連接定位映射文件(*.map),在此文件中有詳細(xì)的函數(shù)調(diào)用嵌套指示圖“callgraph”,建議大家要留意一下。其信息大致如下(取自于一示范程序的編譯結(jié)果):Callgraph:mainsize0,0offset0RightShiftC_Tasksize0,1offset0Iwtoftftmulsize0,0offset0ftunpacklftunpack2ftaddsize0,0offset0ftunpacklftunpack2ftdenorm例11-4C函數(shù)調(diào)用層次圖上面所舉的信息表明整個程序在正常調(diào)用子程序時嵌套最多為兩級(沒有考慮中斷)。因為main函數(shù)不可能返回,故其不用計算在嵌套級數(shù)中。其中有些函數(shù)調(diào)用是編譯代碼時自動加入的庫函數(shù),這些函數(shù)調(diào)用從C原程序中無法直接看出,但在此嵌套指示圖上則一目了然。11.6.3 函數(shù)類型聲明PICC在編譯時將嚴(yán)格進(jìn)行函數(shù)調(diào)用時的類型檢查。一個良好的習(xí)慣是在編寫程序代碼前先聲明所有用到的函數(shù)類型。例如:voidTask(void);unsignedcharTemperature(void);voidBIN2BCD(unsignedchar);voidTimeDisplay(unsignedchar,unsignedchar);這些類型聲明確定了函數(shù)的入口參數(shù)和返回值類型,這樣編譯器在編譯代碼時就能保證生成正確的機(jī)器碼。筆者在實際工作中有時碰到一些用戶聲稱發(fā)現(xiàn)C編譯器生成了錯誤的代碼,最后究其原因就是因為沒有事先聲明函數(shù)類型所致。建議大家在編寫一個函數(shù)的原代碼時,立即將此函數(shù)的類型聲明復(fù)制到原文件的起始處,見例11T;或是復(fù)制到專門的包含頭文件中,再在每個原程序模塊中引用。

11.6.4中斷函數(shù)的實現(xiàn)11.6.4中斷函數(shù)的實現(xiàn)PICC可以實現(xiàn)C語言的中斷服務(wù)程序。中斷服務(wù)程序有一個特殊的定義方法:voidinterruptISR(void);其中的函數(shù)名“ISR”可以改成任意合法的字母或數(shù)字組合,但其入口參數(shù)和返回參數(shù)類型必須是“void”型,亦即沒有入口參數(shù)和返回參數(shù),且中間必須有一個關(guān)鍵詞"interrupt”。中斷函數(shù)可以被放置在原程序的任意位置。因為已有關(guān)鍵詞uinterruptn聲明,PICC在最后進(jìn)行代碼連接時會自動將其定位到0x0004中斷入口處,實現(xiàn)中斷服務(wù)響應(yīng)。編譯器也會實現(xiàn)中斷函數(shù)的返回指令“retfie"。一個簡單的中斷服務(wù)示范函數(shù)如下:voidinterruptISR(void)〃中斷服務(wù)程序if(TOIE&&TOIF)TOIF二0;〃在此加入TMR0中斷服務(wù)〃判TMRO中斷〃清除TMRO中斷標(biāo)志if(TMR1IE&&TMR1IF)〃判TMR1中斷TMR1IFO;〃在此加入TMR1中斷服務(wù)//清除TMR1中斷標(biāo)志〃中斷結(jié)束并返回例11-5C語言中斷函數(shù)舉例Pice會自動加入代碼實現(xiàn)中斷現(xiàn)場的保護(hù),并在中斷結(jié)束時自動恢復(fù)現(xiàn)場,所以編程員無需象編寫匯編程序那樣加入中斷現(xiàn)場保護(hù)和恢復(fù)的額外指令語句。但如果在中斷服務(wù)程序中需要修改某些全局變量時,是否需要保護(hù)這些變量的初值將由編程員自己決定和實施。用C語言編寫中斷服務(wù)程序必須遵循高效的原則:&01540; 代碼盡量簡短,中斷服務(wù)強調(diào)的是一個“快”字。&01540; 避免在中斷內(nèi)使用函數(shù)調(diào)用。雖然PICC允許在中斷里調(diào)用其它函數(shù),但為了解決

遞歸調(diào)用的問題,此函數(shù)必須為中斷服務(wù)獨家專用。既如此,不妨把原本要寫在其它函數(shù)內(nèi)的代碼直接寫在中斷服務(wù)程序中。&01540; 避免在中斷內(nèi)進(jìn)行數(shù)學(xué)運算。數(shù)學(xué)運算將很有可能用到庫函數(shù)和許多中間變量,就算不出現(xiàn)遞歸調(diào)用的問題,光在中斷入口和出口處為了保護(hù)和恢復(fù)這些中間臨時變量就需要大量的開銷,嚴(yán)重影響中斷服務(wù)的效率。中檔系列PIC單片機(jī)的中斷入口只有一個,因此整個程序中只能有一個中斷服務(wù)函數(shù)。11.6.5標(biāo)準(zhǔn)庫函數(shù)11.6.5標(biāo)準(zhǔn)庫函數(shù)PICC提供了較完整的C標(biāo)準(zhǔn)庫函數(shù)支持,其中包括數(shù)學(xué)運算函數(shù)和字符串操作函數(shù)。在程序中使用這些現(xiàn)成的庫函數(shù)時需要注意的是入口參數(shù)必須在bankO中。如果需要用到數(shù)學(xué)函數(shù),則應(yīng)在程序前 “include”包含頭文件;如果要使用字符串操作函數(shù),就需要包含“include”頭文件。在這些頭文件中提供了函數(shù)類型的聲明。通過直接查看這些頭文件就可以知道PICC提供了哪些標(biāo)準(zhǔn)庫函數(shù)。C語言中常用的格式化打印函數(shù)“printf/sprintf”用在單片機(jī)的程序中時要特別謹(jǐn)慎。printf/sprintf是一個非常大的函數(shù),一旦使用,你的程序代碼長度就會增加很多。除非是在編寫試驗性質(zhì)的代碼,可以考慮使用格式化打印函數(shù)以簡化測試程序;一般的最終產(chǎn)品設(shè)計都是自己編寫最精簡的代碼實現(xiàn)特定格式的數(shù)據(jù)顯示和輸出。本來,在單片機(jī)應(yīng)用中輸出的數(shù)據(jù)格式都相對簡單而且固定,實現(xiàn)起來應(yīng)該很容易。對于標(biāo)準(zhǔn)C語言的控制臺輸入(scanf)/輸出(printf)函數(shù),PICC需要用戶自己編寫其底層函數(shù)getch()和putchOo在單片機(jī)系統(tǒng)中實現(xiàn)scanf/printf本來就沒什么太多意義,如果一定要實現(xiàn),只要編寫好特定的getch()和putchO函數(shù),你就可以通過任何接口輸入或輸

出格式化的數(shù)據(jù)。11.7PICC定義特殊區(qū)域值PICC提供了相關(guān)的預(yù)處理指令以實現(xiàn)在原程序中定義單片機(jī)的配置字和標(biāo)記單元。.1定義工作配置字在原程序中定義PIC單片機(jī)工作配置字的重要性在前面章節(jié)中已經(jīng)闡述。在用PICC寫程序時同樣可以在C原程序中定義,具體方式如下:—CONFIG(HS&UNPROTECT&PWRTEN&BORDIS&WDTEN);上面的關(guān)鍵詞“_CONFIG”(注意前面有兩個下劃線符)專門用于是芯片配置字的設(shè)定,后面括號中的各項配置位符號在特定型號單片機(jī)的頭文件中已經(jīng)定義(注意不是pic.h頭文件),相互之間用邏輯“與”操作符組合在一起。這樣定義的配置字信息最后將和程序代碼一起放入同一個HEX文件。在這里列出了適用于16F7x系列單片機(jī)配置位符號預(yù)定義,其它型號或系列的單片機(jī)配置字定義方式類似,使用前查閱一下對應(yīng)的頭文件即可。/*振蕩器配置*/ftdefineRCttdefineHS0x3FFF//RC振蕩0x3FFE//HS模式ttdefineXT#defineLP/*看門狗配置*/0x3FFD//XT模式0x3FFC//LP模式

ttdefineWDTDIS/*上電延時定時器配置*/#definePWRTEN0x3FFB//看門狗關(guān)閉0x3FF7//上電延時定時器打開#definePWRTDIS延時定時器關(guān)閉0x3FFF//上電/*低電壓復(fù)位配置*/#defineBOREN0x3FFF#defineBOREN0x3FFF//低電壓復(fù)位允許ttdefineBORDIS/*代碼保護(hù)配置*/0x3FBF//低電壓復(fù)位禁止沒有代碼保護(hù)ttdefineUNPROTECT0x3FFF//沒有代碼保護(hù)^definePROTECT代碼保護(hù)0x3FEF//程序例11-6頭文件預(yù)定義的配置信息符號11.7.2定義芯片標(biāo)記單元PIC單片機(jī)中的標(biāo)記單元定義可以用下面的_IDLOC(注意前面有兩個下劃線符)預(yù)處理指令實現(xiàn),方法如下:_IDLOC(1234);其特殊之處是括號內(nèi)的值全部為16進(jìn)制數(shù),不需要用“Ox”引導(dǎo)。這樣上面的定義就設(shè)定了標(biāo)記單元內(nèi)容為01020304。11.8MPLAB-IDE中實現(xiàn)PICC的編譯選項設(shè)置在H.3節(jié)中已經(jīng)介紹了如何實現(xiàn)PICC和MPLAB-IDE開發(fā)平臺的掛接。一旦項目建立成功、程序編寫完成后即可以通過MPLAB環(huán)境下的項目管理工具實現(xiàn)程序的編譯、連接和調(diào)試。它們的含義分別是:一項目維護(hù)(Make):MPLAB檢查項目中的原程序文件,只編譯那些在上次編譯后又被修改過的原程序,最后進(jìn)行連接;一項目重建(BuildAll):項目中的所有原程序文件,不管是否有修改,都將被重新編譯一次,最后進(jìn)行連接。也可以通過Project菜單選擇“Make”或“BuildAU”實現(xiàn)項目編譯。不管采用何種方式,在啟動編譯過程前一般都要設(shè)定一些編譯選項。11.8.1 選擇單片機(jī)型號在選擇PICC作為語言工具并建立了項目后,同樣通過菜單項Configure&01616;SelectDevice在MPLAB環(huán)境中選擇具體單片機(jī)型號。請回顧一下例11-1的代碼,我們在原程序一開始使用了“include”實現(xiàn)了相關(guān)單片機(jī)的一些預(yù)定義符號的直接引用,但沒有具體指明是哪一個型號。實際上,“Pic.h”頭文件只是一個簡單的管理工具(條件判別),它會按照MPLAB所選擇的特定型號的單片機(jī),把真正對應(yīng)的頭文件包含進(jìn)來。有興趣者可以直接用文本編輯工具打開pic.h文件查看其是如何根據(jù)不同的單片機(jī)型號包含對應(yīng)的頭文件。這樣對編程員而言,程序中只需加上一句"include”即可。參考第三章3.2.7節(jié)的內(nèi)容和圖3-20的指示說明,啟動編譯選項設(shè)定對話框。在使用PICC語言工具時對話框的內(nèi)容和用MPAMS匯編工具相比完全不同。圖11-3為PICC編譯環(huán)境下普通選項設(shè)定的界面。在此界面中用戶唯一能改變的是編譯器查找頭文件時的指定路徑(IncludePath),實際上如果編譯器安裝沒有問題,在此界面中這些普通選項的設(shè)定無需任何改動,編譯器會自動到缺省認(rèn)定的路徑中(編譯器安裝后的相關(guān)路徑)查找編譯所需的各類文件。圖11-3PICC普通選項設(shè)定 圖11-4PICC全局選項設(shè)定3PICC全局選項設(shè)定(PICCGlobal)全局選項將影響項目中所有C和匯編原程序的編譯,詳細(xì)的設(shè)定內(nèi)容見圖11-4。其中必須關(guān)注的有:&01540;CompileforMPLABICD:如果你準(zhǔn)備用ICD調(diào)試C語言編譯后的代碼,那么此項就必須打鉤選中。這樣編譯后的結(jié)果就能保證ICD本身使用的芯片資源(一小部分的程序和數(shù)據(jù)空間)不被應(yīng)用程序所占用。&01540;Treat'char'assigned:為了提高編譯后的代碼效率,PICC缺省認(rèn)定‘char'型變量也是無符號數(shù)。如果在設(shè)計中需要使用帶符號的‘char,型變量,此項就應(yīng)該被選中。&01540;Floatingpoint'double'width:同樣為了提高編譯后的代碼效率,PICC 缺省認(rèn)定?double,型的雙精度浮點數(shù)變量的實現(xiàn)長度為24位(等同于普通float型浮點數(shù))。在這里可以選擇使其長度達(dá)32位。這樣數(shù)值計算的精度將得到提高,但代碼長度將增加,計算速度也會降低,所以請在權(quán)衡利弊后作出你自己的決定。項目中所有的C原程序都將通過C編譯器編譯成機(jī)器碼,這些選項決定了C編譯器是如何工作的。所有選項又分為兩組:普通選項(General)和高級選項(Advanced),分別見圖11-5A和ll-5BoC編譯器的普通選項最重要的就是針對代碼優(yōu)化的設(shè)定。如果沒有特殊原因,應(yīng)該設(shè)定全局優(yōu)化級別為9級(最高級別優(yōu)化),同時使用匯編級優(yōu)化,這樣最終得到的代碼效率最高(長度和執(zhí)行速度兩方面)。按筆者的使用經(jīng)驗,僅從代碼長度去比較,使用最高級別優(yōu)化后代碼長度至少可以減少20%(2K字以上的程序)。而且PICC的優(yōu)化器相當(dāng)可靠,一般(A) 常用選項(B)高級選項圖11-5C編譯器選項設(shè)定不會因為使用優(yōu)化從而使生成的程序出現(xiàn)錯誤。碰到的一些問題也基本都是用戶編寫的原程序有漏洞所導(dǎo)致,例如一些變量應(yīng)該是volatile型但編程員沒有明確定義,在優(yōu)化前程序可以正常運行,一旦使用優(yōu)化,程序運行就出現(xiàn)異常。顯然,把出現(xiàn)的這些問題歸罪到編譯器是毫無道理的。使用優(yōu)化后可能對原程序級的調(diào)試帶來一些不便之處。因PICC可能會重組編譯后的代碼,例如多處重復(fù)的代碼可能會改成同一個子程序調(diào)用以節(jié)約程序空間,這樣在調(diào)試過程中跟蹤原程序時可能會出現(xiàn)程序亂跳的現(xiàn)象,這基本是正常的。若為了強調(diào)更直觀的代碼調(diào)試過程,你可以將優(yōu)化級別降低甚至關(guān)閉所有優(yōu)化功能,這樣調(diào)試時程序的運行就可以按部就班了。C編譯器的高級選項設(shè)定基本都是針對診斷信息輸出的,和生成的代碼無關(guān)。用得相對較多的選項有:&01540;Generateassemblylistfile:編譯器生成C原程序的匯編列表文件(*.1st)。在此文件中列出了每一行c原代碼對應(yīng)的匯編指令,但這些都是優(yōu)化前的代碼。簡單的一條C語句被翻譯成匯編指令后可能有好幾條。有時匯編列表文件可以作為解決問題的輔助手段。如果你懷疑編譯器生成的代碼有錯誤,不妨先產(chǎn)生對應(yīng)的匯編列表文件,看看在優(yōu)化前一條c語句被編譯后的匯編碼到底是什么。&01540;Compiletoassemblyonly:這一選項的作用是把&n,bsp;C原程序編譯成匯編指令文件(*.as),此時將不生成目標(biāo)文件,也不進(jìn)行最后的連接定位。這一選項在C和匯編混合編程時特別有用。通過解讀C程序?qū)?yīng)的匯編指令,可以掌握c程序中存取變量的具體方法,然后用在自己編寫的匯編指令中。我們將在稍后專門做介紹。11.8.5 連接器選項設(shè)定(PICCLinker)連接器PICCLinker的選項基本不用作太多的改變,在圖11-6的對話框中顯示了可設(shè)定的各類項目。其中有兩項有用的信息輸出可以考慮加以利用:&01540;Generatemapfile:生成連接定位映射文件。在此映射文件中詳細(xì)列出了所有程序用到的變量的具體物理地址;所有函數(shù)的入口地址;函數(shù)相互之間調(diào)用的層次關(guān)系和深度等。這些信息對于程序的調(diào)試將非常有用。此文件將以擴(kuò)展名的形式存放在同一個項目路徑下,需要時可以用任何文本編輯器打開觀察。圖11-6PICC連接器選項設(shè)定&01540;Displaymemory-segmentusage:顯示詳細(xì)的內(nèi)存分配和使用情況報告。用戶可以了解到程序空間和數(shù)據(jù)存儲器空間資源分配的細(xì)節(jié)。下面列舉了在一個項目編譯后實際的內(nèi)存使用信息,為方便理解筆者用“〃”添加了一些注釋:PsectUsageMap: 〃程序段定位表Psect|Contents |MemoryRangepowerup|Poweronresetcode | $0000-$0003intentry|Interruptserviceroutine$0004-$000Cintcode |Interruptserviceroutine |$000D-$002Cintret |Interruptserviceroutine |$002D-$0035init|Initializationcode | $0036-$003Dendinit|Initializationcode |$003E-$0040clrtext|Memoryclearingcode $0041-$0047

const3$0060Stringsandconstantdata$0048-const$0071Stringsandconstantdata$0061-const2$0076Stringsandconstantdata$0072-text$0582Programandlibrarycode|$0576-text$07C7ProgramandlibrarycodeI$0583-float_te$07FFArithmeticroutinecode$07C8-rbssO$0042Bank0RAMvariables$0021-tempTemporaryRAMdata$0043$0047nvram PersistentRAMdata |$0048-$004Aintsave Registerssavedoninterrupt $004B-$004Dintsave Registerssavedoninterrupt $007F-$007Fintsavel|SavedcopyofWinbank1 |$00FF-$00FFrbitO|Bank0bitvariables|$0100-$0104config|User-programmedCONFIGbits|$2007-$2007MemoryUsageMap:〃程序空間代碼定位地址分布〃存儲空間使用情況報告119)wordsProgramROM$0000-$0076$119)wordsProgramROM$0576-$07FF$028A( 650)words$0301( 769)wordstotalProgramROM//bankO數(shù)據(jù)空間變量地址分布Bank 0RAM $0021- $004D $002D( 45)bytesBank 0RAM $007F- $007F $0001( 1)bytes$002E( 46)bytestotalBank0RAM//bankl數(shù)據(jù)空間變量地址分布Bank1RAM$00FF-$00FF $0001( 1)bytestotalBank1RAM//bankO數(shù)據(jù)空間位變量地址分布Bank0Bits$0100-$0104 $0005( 5)bitstotalBank0Bits〃配置字地址ConfigData$2007-$2007 $0001( 1)wordstotalConfigDataProgramstatistics:〃程序總體資源消耗統(tǒng)計TotalROMused 769words(18.8%) 〃生成代碼字總數(shù)和程序空間使用率TotalRAMused 48bytes(25.0%) 〃使用數(shù)據(jù)字節(jié)數(shù)和數(shù)據(jù)空間使用率

例11-7例11-7編譯后程序使用的內(nèi)存信息11.8.6 匯編器選項設(shè)定(PICCAssembler)PICC環(huán)境提供了自己的匯編編譯器,它和Microchip公司提供的MPASM編譯器在原程序的語法表達(dá)方面要求稍有不同。另外,PICC的匯編編譯器要求輸入原程序文件的擴(kuò)展名是“*.as",而MPASM缺省認(rèn)定的原程序以“*.asm”為擴(kuò)展名。在基于PICC編譯環(huán)境下開發(fā)PIC單片機(jī)的C語言應(yīng)用程序時基本無需關(guān)心其匯編編譯器,除非是在混合語言編程時用匯編語言編寫完整的匯編原程序模塊文件。其編譯選項設(shè)定的對話框見圖11-7,最重要的是優(yōu)化使能控制項“Enableoptimization",一般情況下應(yīng)該使用匯編器的優(yōu)化以節(jié)約程序空間。圖11-7PICC匯編器選項設(shè)定11.9C和匯編混合編程有兩個原因決定了用C語言進(jìn)行單片機(jī)應(yīng)用程序開發(fā)時使用匯編語句的必要性:單片機(jī)的一些特殊指令操作在標(biāo)準(zhǔn)的C語言語法中沒有直接對應(yīng)的描述,例如PIC單片機(jī)的清看門狗指令"clrwdt”和休眠指令"sleep";單片機(jī)系統(tǒng)強調(diào)的是控制的實時性,為了實現(xiàn)這一要求,有時必須用匯編指令實現(xiàn)部分代碼以提高程序運行的效率。這樣,一個項目中就會出現(xiàn)C和匯編混合編程的情形,我們在此討論一些混合編程的基本方法和技巧。嵌入行內(nèi)匯編的方法在C原程序中直接嵌入?yún)R編指令是最直接最容易的方法。如果只需要嵌入少量幾條的匯編指令,PICC提供了一個類似于函數(shù)的語句:asm("clrwdt");雙引號中可以編寫任何一條PIC的標(biāo)準(zhǔn)匯編指令。例如:for(;;){asm("clrwdt");〃清看門狗Task();

ClockRun0;asm("sleep");asm(nop);}〃休眠〃空操作延時例11-8例11-8逐行嵌入?yún)R編的方式如果需要編寫一段連續(xù)的匯編指令,PICC支持另外一種語法描述:用法asm”開始匯編指令段,用“#endasm”結(jié)束。例如下面的一段嵌入?yún)R編指令實現(xiàn)了將 0x20~0x7F間的RAM全部清零:#asmmovlw 0x20movwf _FSRclrf _INDFincf _FSR,fbtfss _FSR,7goto $-3ttendasm例11-9 整段嵌入?yún)R編的方式匯編指令尋址C語言定義的全局變量C語言中定義的全局或靜態(tài)變量尋址是最容易的,因為這些變量的地址已知且固定。按C語言的語法標(biāo)準(zhǔn),所有C中定義的符號在編譯后將自動在前面添加一下劃線符,因此,若要在匯編指令中尋址C語言定義的各類變量,一定要在變量前加上一 符號,我們在上面例11-9中已經(jīng)體現(xiàn)了這一變量引用的法則,因為FSR和INDF等所有特殊寄存器是以C語言語法定義的,因此匯編中需要對其尋址時前面必須添加下劃線。對于C語言中用戶自定義的全局變量,用行內(nèi)匯編指令尋址時也同樣必須加上下面的例11T0說明了具體的引用方法:volatileunsignedchartmp; 〃定義位于bankO的字符型全局變量voidTest(void){#asmclrf_STATUSmovlw0x10movwftmpttendasmif(tmp==0xl0){}〃測試程序〃開始行內(nèi)匯編〃選擇bankO〃設(shè)定初值//tmp=OxlO〃結(jié)束行內(nèi)匯編〃開始C語言程序

例11T0例11T0行內(nèi)匯編尋址C全局變量(位于bankO)上面的例子說明了匯編指令中尋址C語言所定義變量的基本方法。PICC在編譯處理嵌入的行內(nèi)匯編指令時將會原封不動地把這些指令復(fù)制成最后的機(jī)器碼。所有對C編譯器所作的優(yōu)化設(shè)定對這些行內(nèi)匯編指令而言將不起任何作用。編程員必須自己負(fù)責(zé)編寫最高效的匯編代碼,同時處理變量所在的bank設(shè)定。對于定義在其它bank中的變量,還必須在匯編指令中加以明確指示,見例11-11的代碼范例。volatilebanklunsignedchartmpBankl;〃定義位于bankl的字符型全局變量volatilebank2unsignedchartmpBank2;〃定義位于bank2的字符型全局變量〃定義位volatilebank3unsignedchartmpBank3;〃定義位于bank3的字符型全局變量voidTest(void)(#asmbcf _STATUS,6bsf _STATUS,5movlw0x10movwftmpBankl0x80bsf _STATUS,6movlw0x20〃測試程序〃開始行內(nèi)匯編〃選擇bankl〃設(shè)定初值//tmpBankl=OxlO〃選擇bank2〃設(shè)定初值//tmpBank2=0x20//tmpBank2=0x20bsfSTATUS,5bsfSTATUS,5movlw0x30〃選擇bank3〃

溫馨提示

  • 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)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論