初學(xué)者之軟件使用教程-avruserguide_第1頁
初學(xué)者之軟件使用教程-avruserguide_第2頁
初學(xué)者之軟件使用教程-avruserguide_第3頁
初學(xué)者之軟件使用教程-avruserguide_第4頁
初學(xué)者之軟件使用教程-avruserguide_第5頁
已閱讀5頁,還剩28頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡(jiǎn)介

第十章 C編譯器的使 CExpanded3rdPartyIAREmbeddedWorkbench–CandEC++–IARvisualSTATEcase–IARMakeAppapplicationbuilderImageCraftICCAVR/ICCtiny–Supportsdeviceswithout–Embeddedapplication–Global–ISP-supportGNU –Free–Nosupport,butGNUusersactiveonmailing–Gettingstartedappnote–NextgenerationAVRStudiowillsupportGNUoutputformatCodeVision –IncludesadvancedCC本公司的ImageCraft的ICCAVR編譯器理由:免費(fèi)提供30天的使用版,可生成燒錄文件,而IAR免費(fèi)提供的使用版,只生成調(diào)試文件,不能生成燒錄文件;功能適合,使用方便,技術(shù)支援好;不斷增加新功能模塊,如單總線,SPI,UART,IIC總線,LCD,LED(本公司也在幫助改進(jìn),增加新功能)等;價(jià)格適合,原售199,雙龍公司成為ICCAVR中國獨(dú)家,另售價(jià)為1380元人民幣,與ICE-200實(shí)時(shí)仿真器(2200元)捆邦銷售,僅售3200元/套ImageCraftICCAVR方法一a 雙擊光盤中文 SETUP.EXE的圖d按照屏幕提示 方法二a 開始菜單中選擇運(yùn)行項(xiàng)目 運(yùn)行框中填 確 鍵開始安注意1 按上述方法進(jìn)行安裝后得到的是一個(gè)只可以使用30天的未版對(duì)正式版 ICCAVR縮 30天的用戶可以這樣將正式版中附帶的一張名稱 UnlockDisk的軟 你機(jī)器的軟盤驅(qū)動(dòng)器 IDE的Help菜單中尋找標(biāo)題為ImportingaLicensefromaFloppyDisk的一項(xiàng) ICCAVR自動(dòng)進(jìn)行 當(dāng)完成后會(huì)提示你文件已從軟盤移走當(dāng)你確定并再次重新啟動(dòng)ICCAVR后會(huì)發(fā)現(xiàn)已經(jīng)完成30天的用戶可這樣 對(duì)這類用戶在程序啟動(dòng)時(shí)已不能進(jìn)入IDE環(huán)境而是出現(xiàn)一個(gè)提示你的框你應(yīng)該選擇YES按鈕 框上有一個(gè)標(biāo)題為ImportingaLicensefromaFloppyDisk的按鈕 將正式版中附帶的一張名稱為UnlockDisk的軟盤你機(jī)器的軟盤驅(qū)動(dòng)器中單 ICCAVR自動(dòng)進(jìn)行當(dāng)完成后會(huì)提示你文件已從軟盤移走當(dāng)你確定并再次重新啟動(dòng)ICCAVR后會(huì)發(fā)現(xiàn)已經(jīng)完成aUnlockDisk軟盤在時(shí)應(yīng)打開寫保護(hù)否則無法完完成后UnlockDisk軟盤成為一張空盤不可以在另一臺(tái)機(jī)器上進(jìn)行安裝當(dāng)你需要在不同的電腦中使用ICCAVR或在同一臺(tái)電腦中將ICCAVR重新安裝在與原來不同的位置時(shí)應(yīng)該首先在HelpTransferringYourLicensetoaFloppyDisk一項(xiàng)將你的文件傳送到一張軟盤上然后再按上述方法進(jìn)行安裝 ImageCraft的ICCAVR是一種使用符合ANSI標(biāo)準(zhǔn)的C語言來開發(fā)微控制器MCU程序的一個(gè)工具它有以下幾個(gè)主要特點(diǎn)源文件全部被組織到工程之中文件的編輯和工程的構(gòu)筑也在這個(gè)環(huán)境中完成編譯錯(cuò)誤顯示在狀態(tài)窗口中并且當(dāng)你用鼠標(biāo)單擊編譯錯(cuò)誤時(shí)光標(biāo)會(huì)自動(dòng)跳轉(zhuǎn)到編輯窗口中引起錯(cuò)誤的那一行這個(gè)工程管理器還能直接產(chǎn)生您希望得到的可以直接使用的INHEX格式文件INHEX格式文件可被大多數(shù)的編程器所支持用于程序到中去位的程序支CICCAVR所必須具備的知識(shí)因此要求讀者在閱讀本書內(nèi)容之前應(yīng)對(duì)C語言有了一定程度的理解ICCAVR文件類型是由它們的擴(kuò)展名決定的IDE和編譯器可以使用以下幾種類型的文件 C C.prj擴(kuò)展名----IDE.a擴(kuò)展名----庫文件它可以由幾個(gè)庫封裝在一起libcavr.aCAVR特殊程序調(diào)用的基本庫如果庫被器會(huì)將其到您的模塊或文件中您也可以創(chuàng)建或修 C語言源文件.o由匯編文件匯編產(chǎn)生的目標(biāo)文件多個(gè)目標(biāo)文件可以成一個(gè)可執(zhí)行文 HEX格式文件其中包含了程序的機(jī)器代碼.eep HEX格式文件包含了EEPROM COFF格式輸出文件用于ATMELAvrStudio環(huán)境下進(jìn)行程序調(diào) 列表文 在這個(gè)文件中列舉出了目標(biāo)代碼對(duì)應(yīng)的最終地 內(nèi)存映象文 它包含了您程序中有關(guān)符號(hào)及其所占內(nèi)存大小的信.cmdNoICE2.xx NoICE3.xx ImageCraft #pragmainterrupt_handler<func1>:<vectornumber><func2>:<vector>這個(gè)附注必須在函數(shù)之前定義它說明函數(shù)func1func2是中斷操作函數(shù)所以編譯器在中斷retiret并且保存和恢復(fù)函數(shù)所使用的全部寄存器同樣編譯器根據(jù)中斷向量號(hào)vectornumber生成中斷向量地址 k<func1>RTOS實(shí)時(shí)操作系統(tǒng)中讓RTOS核直接管理寄存器#pragma改變代碼段名稱#pragmaEEPROM中時(shí)必須被使用讀者可參考EEPROM的例子#pragma函數(shù)與全局?jǐn)?shù)據(jù)不使用浮動(dòng)定位重定位而是從<address>開始分配絕對(duì)地址這在中斷#pragma結(jié)束絕對(duì)定位C++如果你選擇了編譯擴(kuò)充(Project->Options- 你可以在你的源代碼中使用C++的如果你選擇了編譯擴(kuò)充(Project->Options->Compiler)你可以使0b<1|0>*來指定二進(jìn)制常數(shù)例如0b10101等于十進(jìn)制數(shù)21你可以使用asm("string")函數(shù)來指定匯編代碼讀者可參考匯IARCAVRCIAR編譯ImageCraftANSIC標(biāo)準(zhǔn)的程序代碼不需要轉(zhuǎn)換IARC中IO寄存器的定義與ICCAVR也是相同的中斷操作描述ICCAVR使用pragma附注描述中斷操作函數(shù)而IAR引入了語法擴(kuò)充關(guān)鍵字下面是一個(gè)對(duì)照在ICCAVR中#pragmainterrupt_handlerfunc:4//4是這個(gè)中斷的向量號(hào)func為中斷處理函數(shù)名稱在IAR中interrupt[vector_name]func()//vector_name是某一個(gè)中斷向量的名稱IARC的中斷向量地址使用中斷名稱來代替以增加程序的可讀性IAR引入flash關(guān)鍵字將項(xiàng)目分配進(jìn)入程序存貯空間FLASH存貯器ICCAVR使用const關(guān)在兩個(gè)編譯系統(tǒng)之間函數(shù)參數(shù)傳遞使用的寄存器是不同的這僅影響手工寫的匯編函數(shù)匯編宏等IAR不支持匯編符號(hào)而ICCAVR支持匯編 IDE后首先從ProjectOpen命令進(jìn)入\icc\examples.avr并且選擇并打開led工程工程管理器顯示在這個(gè)工程中只有一個(gè)文件led.cProject菜單中選擇Options命令打開工程編譯選項(xiàng)在""標(biāo)號(hào)下選擇目標(biāo)處理器然后從Project菜單中MakeProject命令I(lǐng)DE將調(diào)用編譯器編譯這個(gè)工程文件并且在狀態(tài)窗口中顯示所有的信如果沒有錯(cuò)誤在與源文件同一個(gè)在這個(gè)例子中是\icc\examples.avr中輸出一個(gè)文件led.hex這個(gè)文件是INHEX格式大多數(shù)能支持AVRMCU的編程器和模擬器都支持這種格式并且能這個(gè)程序進(jìn)入你的目標(biāo)系統(tǒng)這樣就完成了一個(gè)程序的構(gòu)筑COFFAVRStudio那么你需要從Project菜單中選擇Options命令在編譯下選擇COFF輸出文件格式對(duì)一些常用的功能你也可使用工具條或鼠標(biāo)右鍵彈出菜單例如你可以在工程窗口單擊鼠標(biāo)右鍵選擇編譯選項(xiàng)在工程窗口中雙擊文件名IDEled.c作為試驗(yàn)可設(shè)置一些錯(cuò)誤例如從一行中刪除分號(hào)現(xiàn)在從Project菜單中選擇MakeProject命令I(lǐng)DE首先自動(dòng)保存已經(jīng)改變的文件并且開始編譯這個(gè)文件這時(shí)在狀態(tài)窗口中會(huì)顯示錯(cuò)誤信息單擊狀態(tài)窗口中錯(cuò)誤信息行或單擊其左邊的錯(cuò)誤符號(hào)光標(biāo)將移到編輯器中錯(cuò)誤行的下面一行上基本上所有C編譯器都是這樣ProjectNew命令并且瀏覽至你希望輸出工程文件的輸出文件的名稱取決于你的工程文件名稱例如如果你創(chuàng)建一個(gè)名稱為foo.prj的工程那么輸出文件名稱為foo.hex或foo.cof等自從創(chuàng)建你自己的工程后你可以開始寫你的源代碼(C或匯編格式)并且將這個(gè)文件加入到工程文件排列中單擊中Build圖標(biāo)可以很容易地構(gòu)筑這個(gè)工程IDE輸出與ATMELAVRStudio完全兼容的COFF文件你可以使用ATMELAVRStudio來調(diào)試你的代碼C一個(gè)C程序必須定義一個(gè)main調(diào)用函數(shù)編譯器會(huì)將你的程序與啟動(dòng)代碼和庫函數(shù)一個(gè)可執(zhí)行文件因此你也可以在你的目標(biāo)系統(tǒng)中執(zhí)行它啟動(dòng)代碼的用途在啟動(dòng)文件中很詳細(xì)地被描述了一個(gè)C程序需要設(shè)定目標(biāo)環(huán)境啟動(dòng)代碼初始化這個(gè)目標(biāo)使其滿足所有的要求通常你的main例程完成一些初始化后然后是無限循環(huán)地運(yùn)行作為例子讓 #include<io8515.h>/*LED的變化圖案延時(shí)程序需要有足夠的延時(shí)時(shí)間*/voidDelay(){unsignedchara,for(a=1;a;a++)for(b=1;b;;}voidLED_On(int{PORTB~BIT(i);/*LED*/}void{DDRB /*定義B口輸出PORTB=0xFF; /*B口全部為高電平對(duì)應(yīng)LED熄滅*/while(1){/*LED*/for(i0;i8;i++)/*LED*/for(i=8;i>0;i--)/*LED跳躍for(i=0;i<8;i+=2)for(i=7;i>0;i-=2)}}mainIOLEDLEDLED_OnLED_On例程中直IOCPULED_On例程調(diào)用了延時(shí)例程因?yàn)檠訒r(shí)的實(shí)際延時(shí)值不能被確定這一對(duì)嵌套循環(huán)只能給出延時(shí)的近似延時(shí)時(shí)間如果這個(gè)實(shí)際定時(shí)時(shí)間是重要的那么這個(gè)例程應(yīng)該使用硬件定時(shí)器來完成延時(shí)8515intr.cC寫一個(gè)中斷處理過程這四ICCAVRIDE有文件然而有時(shí)也需要將一個(gè)文件單獨(dú)地編譯為目標(biāo)文件或最終的輸出文件這時(shí)可以這樣操作從IDE菜單File中選擇CompileFile...命令來執(zhí)行toObject和toOutput中的任意一個(gè)當(dāng)你調(diào)用這個(gè)命令時(shí)文件應(yīng)該是打開的并且在編輯窗口中可以編輯的編譯一個(gè)文件為目標(biāo)文件toObject對(duì)檢查語法錯(cuò)誤和編譯一個(gè)新的啟動(dòng)文件是很有用的編譯一個(gè)文件為輸出文件toOutput對(duì)較小的并且是一個(gè)文件的程序較為有用注意這里使為創(chuàng)建一個(gè)新的工程從菜單Project中選擇New命令I(lǐng)DE會(huì)彈出一個(gè)框在框中你可以指定工程的名稱這也是你的輸出文件的名稱如果你使用一些已經(jīng)建立的源文件你可在菜單Project中選擇AddFile(s)命令另外你可以在菜單File 中選擇New 命令來建立一個(gè)新的源文件來輸入你的代碼你可以在菜單File 中選擇Save 或SaveAs 命令來保存文件然后你可以象上面所述調(diào)用 命令將文件加入到工程中也可在當(dāng)前編輯窗口中單擊鼠標(biāo)右鍵選擇Addto 將文件加入已打開的工程列表中通常你輸出源文件在工程同一 中但也可不工程的編譯選項(xiàng)使用菜單中 中的 命工程管理允許你將多個(gè)文件組織進(jìn)同一個(gè)工程而且定義它們的編譯選項(xiàng)這個(gè)特性允許你將工程分解成許多小的模塊當(dāng)你處理工程構(gòu)筑時(shí)只有一個(gè)文件被修改和重新編譯如果一個(gè)頭文件作了修改當(dāng)你編譯包含這個(gè)頭文件的源文件時(shí)IDE會(huì)自動(dòng)重新編譯已經(jīng)改變的頭文件一個(gè)源文件可以寫成C或匯編格式的任意一種C文件必須使用.c擴(kuò)展名匯編文件必須使用.s擴(kuò)展名你可以將任意文件放在工程列表中例如你可以將一個(gè)工程文檔文件放在工程管理窗口中工程管理器在構(gòu)筑工程時(shí)對(duì)源文件以外的文件不予理睬對(duì)目標(biāo)器件不同的工程可以在編譯選項(xiàng)中設(shè)置有關(guān)參數(shù)當(dāng)你新建一個(gè)工程時(shí)使用默認(rèn)的編譯選項(xiàng)你可以將現(xiàn)有編譯選項(xiàng)設(shè)置成默認(rèn)選項(xiàng)也可將默認(rèn)編譯選項(xiàng)裝入現(xiàn)有工程中默認(rèn)編譯選項(xiàng)保存在default.prj文件中為避免你的工程你可以指定輸出文件和中間文件到一個(gè)指定的通常這個(gè)目錄是你的工程的一個(gè)子IDE當(dāng)編譯存在錯(cuò)誤時(shí)用鼠標(biāo)單擊有關(guān)錯(cuò)誤信息時(shí)編輯器會(huì)自動(dòng)將光標(biāo)定位在錯(cuò)誤行的位置注意對(duì)C源文件中缺少分號(hào)的錯(cuò)誤編輯器定位于其下面一行應(yīng)用構(gòu)筑向?qū)怯糜趧?chuàng) 設(shè)備初始化代碼的一個(gè)圖形界面你可以單擊工具條中Wizard按鈕或菜單Tools中的ApplicationBuilder應(yīng)用構(gòu)筑向?qū)褂镁幾g選項(xiàng)中指定的目標(biāo)MCU來產(chǎn)生相應(yīng)的選項(xiàng)和代應(yīng)用構(gòu)筑向?qū)э@示目標(biāo)MCU的每一個(gè) 設(shè)備子系統(tǒng)它的使用是很顯而易見的在這里你可以設(shè)置MCU的所具有的中斷內(nèi)存定時(shí)器IO端口UART SPI和模擬量比較器等main()IDE有一個(gè)內(nèi)置的終端仿真器注意它不包含任意一個(gè)ISP在系統(tǒng)編程功能但它可以作為一個(gè)簡(jiǎn)單的終端或以顯示你的目標(biāo)裝置的調(diào)試信息也可一個(gè)ASC碼文件6.20IDEISP 菜單解File文件菜 新建一個(gè)文 你可在編輯窗口是輸入文字或代 重新打開歷史文件有關(guān)歷史文件顯示的右邊的子菜單中 打開一個(gè)已以經(jīng)存在的文件用于編輯文件用瀏覽窗口選擇Reload…formDisk放棄全部的修改從磁盤中重新裝載當(dāng)前文件Reload….fromBackUP從最后一次的備份文件中裝載當(dāng)前文件 保存當(dāng)前文件如果環(huán)境設(shè)置中設(shè)置了保存?zhèn)浞菸募t將原文件以<file>.~<ext>Save Close關(guān)閉當(dāng)前文件如果文件有過修 系統(tǒng)會(huì)進(jìn)行提CompileFile…toObject 編譯當(dāng)前文件成目標(biāo)文件注意目標(biāo)文件不可以直接用于對(duì)芯片編程或用于調(diào)試其主要用于語法檢查為創(chuàng)建新的啟動(dòng)文件或庫產(chǎn)生目標(biāo)文件CompileFiletoOutputSave 保存所有打開的文ClossAll 打印當(dāng)前文 撤消最后一次的修改 撤消最后一次的Undo Delete刪除選擇的Select 選擇全部?jī)?nèi)Block Block MatchCase–區(qū)分大小寫WholeWord–全字匹配Up/Down–往上或往下FindinFiles...–在當(dāng)前打開的文件中或在當(dāng)前工程的所有文件中或當(dāng)前 中尋找一段文本它有以下選項(xiàng)CaseSensitive大小寫敏感WholeWord-全字匹配RegularExpression–Replace...–FindAgain–GotoLineNumber轉(zhuǎn)到指定行AddBookmark–DeleteBookmark刪除NextBookmark跳轉(zhuǎn)到下一個(gè)GotoBookmark跳轉(zhuǎn)到指定的書StatusWindow–如果選中顯示狀態(tài)窗口ProjectMakefile–makefile文件OutputListingFile–以只讀方式打開列表文件Project工程菜New...–Open打開一個(gè)已經(jīng)存在的工程文件OpenAllFiles...打開工程的全部源文件CloseAllFiles–關(guān)閉全部打開的文件Reopen...–MakeProject–RebuildAll–AddFile(s)–RemoveSelectedFiles–Option...–打開工程編譯選項(xiàng)Close–SaveAs...–將工程換一個(gè)名稱存 EnvironmentOptions–打開環(huán)境和終端仿真器選項(xiàng)EditorandPrintOptions–打開編輯和打印選項(xiàng)AVRCalc–AVR計(jì)算器可以計(jì)算UART的波特率定時(shí)器的定時(shí)常數(shù)ApplicationBuilder–ConfigureTools–RunCompilerOptions編譯選項(xiàng)總共有三個(gè)頁面 和PathsIncludePath(s)–你可以指定包含文件的路徑AssemblerIncludePath(s)–指定匯編包含文件的路徑LibraryPath–器所使用的庫文件的路徑OutputDirectory–輸出文件的CompilerStrictANSICChecking–ANSICAcceptExtensions–C++MacroDefine(s)–定義宏宏之間用空格或分號(hào)分 宏定義形式如name[:value]#defineDEBUG1#definePRINTprintfMacroUndefine(s)–同上但意義相反OutputFileFormat–輸出文件格式COFF/HEXInHEX或COFFOptimizations–代碼優(yōu)化Default–基本優(yōu)化象寄存器分 共用相同的子例程izeCodeSizeReduction–只有專業(yè)版才可使用它調(diào)用了代碼壓縮優(yōu)化去除了無DeviceConfiguration選擇目標(biāo)MemorySizes–要選擇"Custom"時(shí)指定內(nèi)存大小包括ROMSRAMEEPROMTextAddress–通常代碼地址開始于中斷向量區(qū)域后面DataAddress–指定數(shù)據(jù)起始地址通常–EnhancedCore–IORegistersOffsetInternalSRAM–指定SRAM的偏移量例如,8515的SRAM起始于0x60,IO512Mega603,IOSRAM空間中因此SRAM也是從0開始的InternalExternalSRAM–SRAM類型PRINTFVersion–PRINTF的版本Small或Basic:只有%c,%d,%x,%X,%u,and%sLong:%ld,%lu,%lx,Floatingpoint:%f支持注意這個(gè)選項(xiàng)需要很大的AVRStudioSimulatorIO–如果選 AdditionalLibraries–使用標(biāo)準(zhǔn)庫以外的附加–ReturnStackSize–指定編譯器使用的硬件堆棧的大小編譯器使用的堆棧的大小不需NonDefaultStartup–PathsIDEUnusedROMFillPatternROM C庫函數(shù)與啟動(dòng)文這個(gè)器會(huì)自動(dòng)將啟動(dòng)文件連接到您的程序之前并將標(biāo)準(zhǔn)庫libcavr.a與你的程序相連接啟動(dòng)文件根據(jù)目標(biāo)MCU的不同在crtavr.o和crtatmega.o中間任意選擇一個(gè)啟動(dòng)文件定義了一個(gè)全局符號(hào)start 它也是您的程序的起點(diǎn)啟動(dòng)文件的功能有bss定義一個(gè)退出點(diǎn)如果你的主函數(shù)main一旦退出它將進(jìn)入這個(gè)退出點(diǎn)進(jìn)行無限循環(huán)啟動(dòng)文件也定義了復(fù)位向量你不需要修改啟動(dòng)文件來使用別的中斷具體可參斷操作cd\ ;進(jìn)入你安裝的編譯器路<edit ;crtavr.s<opencrtavr.susingtheIDE>;IDEcrtavr.s<Choose"CompileFileTo->Object"> ;選擇編譯到目標(biāo)文件創(chuàng)建一個(gè)新的crtavr.ocopycrtavr.o..\lib ;拷貝到庫MCUMega你應(yīng)該用"crtatmega"代替"crtavr"Mega的每個(gè)中斷地址使用兩個(gè)字word而非Mega每一個(gè)中斷地址使用一個(gè)字word.你也可以有多個(gè)啟動(dòng)文件你可以在工程選項(xiàng)框中很方便地直接指定一個(gè)啟動(dòng)文件加入您的工程中注意您必須指定啟動(dòng)文件的絕對(duì)路徑或啟動(dòng)文件必須位于工程選項(xiàng)庫路徑所指定的目1庫源代這個(gè)庫源代碼缺省路徑為c:\icc\libsrc.avr\libsrc.zip是一個(gè)保護(hù)的ZIP壓縮文件你可以從互連網(wǎng)上任意一個(gè)UNZIP程序進(jìn)行解壓縮當(dāng)本被開鎖后顯示在"About"框中例如unzip-s;unzip2AVR特殊函數(shù)-----ICCAVR有許多UARTEEPROM和SPI的函數(shù)堆棧檢查函數(shù)對(duì)檢測(cè)堆棧是否溢出很有用另外的互連網(wǎng)上有一個(gè)頁專門存放用戶寫的源代碼3io*.h(io2313.h,io8515.h,iom603.h,...等這些文件中是從ATMEL公開的定義IO寄存器的源文件經(jīng)過修改得到的應(yīng)該用這些文件來代替老的avr.h文件PORTB=1;uc=PORTA;45其它頭文下列標(biāo)準(zhǔn)的C頭文件是被支持的如果你的程序使用了頭文件所列出的函數(shù)那么包含頭文件是一個(gè)好#include預(yù)編譯指令包含這些包含了這些函數(shù)的頭文件讀者可參考返回非整型值的函數(shù)assert.h-assert(),宏ctype.h–字符類型函數(shù)float.h–浮點(diǎn)數(shù)limits.h–math.h–浮點(diǎn)運(yùn)算函數(shù)stdarg.h–變量參數(shù)表.stddef.h–標(biāo)準(zhǔn)定義stdio.h–標(biāo)準(zhǔn)輸入輸出IO函數(shù)stdlib.h–包含內(nèi)存分配函數(shù)的標(biāo)準(zhǔn)庫string.h–字符串處理函數(shù)ACSII字符集字符分類使用這些函數(shù)之前應(yīng)當(dāng)用"#includeintisalnum(int如果c是數(shù)字或字母返回非零數(shù) 否則返回intisalpha(int如果c是字母返回非零數(shù) 否則返回 trl(int如果c是控制字符如FF,BELL,LF..等返回非零數(shù)值否則返回intisdigit(int如果c是數(shù)字返回非零數(shù) 否則返回intisgraph(intc是一個(gè)可打印字符而非空格返回非零數(shù)值intislower(int如果c是小寫字母返回非零數(shù) 否則返回intisprint(int如果c是一個(gè)可打印字符返回非零數(shù) 否則返回intispunct(int如果c是一個(gè)可打印字符而不是空 數(shù)字或字母返回非零數(shù) 否則返回intisspace(int如果c是一個(gè)空格字符返回非零數(shù) 包括空格CR,FF,HT,NL,和 否則返回intisupper(int如果c是大寫字母返回非零數(shù) 否則返回intisxdigit(int如果c是十六進(jìn)制數(shù)字返回非零數(shù) 否則返回inttolower(intcccinttoupper(intc)如果c是小寫字母則返回c對(duì)應(yīng)的大寫字 其它類型仍然返回下列函數(shù)支持浮點(diǎn)數(shù)運(yùn)算使用這些函數(shù)之前必須 #include 包floatasin(float os(floatfloatatan(floatfloatatan2(floatx,float返回y/x的反正 其范圍在 之floatceil(float返回對(duì)應(yīng)x的一個(gè)整型 小數(shù)部分四舍五floatcos(floatfloatcosh(floatfloatexp(floatexexfloatexp10(floatx)10為底的冪floatfabs(floatfloatfloor(floatfloatfmod(floatx,floatfloatfrexp(floatx,int把浮點(diǎn)數(shù)x分解成數(shù)字部分y尾數(shù)和以2為底的指數(shù)n兩個(gè)部分即 2ny的范圍 y值被函數(shù)返回npexpfloatfround(floatfloatldexp(floatx,int返回 2exfloatlog(floatfloatlog10(floatfloatmodf(floatx,floatpint指向的變量小數(shù)部分應(yīng)當(dāng)大于或等于0而小于1并且作為函數(shù)返回值返回floatpow(floatx,floatfloatsqrt(floatfloatsin(floatfloatsinh(floatfloattan(floatfloattanh(float5標(biāo)準(zhǔn)的文件輸入輸出是不能真正植入微控制器MCU的標(biāo)準(zhǔn)stdio.h的許多內(nèi)容不可以使用不過有一些IO函數(shù)是被支持的同樣使用之前應(yīng)用"#include<stdio.h>"預(yù)處理并且需要初始化輸出端口最低層的IO程序是單字符的輸入(getchar)和輸出(putchar)程序如果你針對(duì)不同的裝置使用的IO函數(shù)例如用printf輸出LCD你需要全部重新定義最底層的函數(shù)ATMELAVRStudioIOIO注意作為缺省單字符輸出函數(shù)putchar是輸出到UART裝置沒有修改無論如何為使輸出能如期望的那樣出現(xiàn)在程序終端窗口中'\n'字符必須被為成對(duì)的回車和換行CR/LFintintprintf(char*fmt,frm%d--輸出有符號(hào)十進(jìn)制整%o--輸出無符號(hào)八進(jìn)制%x輸出無符號(hào)十六進(jìn)制整%X除了大寫字母使用'A'F'外同%u輸出無符號(hào)十進(jìn)制整–%c–ASCII字符形式輸出只輸出一個(gè)字%f以小數(shù)形式輸出浮點(diǎn)%S–FLASHprintf支持三個(gè)版本取決于你的特別需要和代碼的大小越高的要求代碼越大基本形:只有%c,%d,%x,%u,和%s格式說明符是承認(rèn)的長(zhǎng)整形:%ld,%lu,%lx被支持,以適用于精度要求較高的領(lǐng)域浮點(diǎn)形:全部格式包括%f被支持你使用編譯選項(xiàng)框來選擇版本代碼大小的增加是值得關(guān)注intputchar(int輸出單個(gè)字符這個(gè)庫程序使用了UART以查尋方式輸出單個(gè)字符注意輸出’\n’字符至程序intputs(charintsprintf(char*buf,charfrmprintf("constchar*"支持功能cprintfcsprintf是將FLASHprinfsprinf 標(biāo)準(zhǔn)庫頭文件<stdlib.h>NULLRAND_MAXsize_t并且描述了下列函數(shù)注意在你調(diào)用任意內(nèi)存分配程序比如..callocmalloc和realloc)之前必須調(diào)用_NewHeap來初始化堆heapintabs(intintatoi(chars為整型數(shù)并返回它字符串s0doubleatof(constchar*s)s為雙精度浮點(diǎn)數(shù)并返回它字符串slongatol(chars為長(zhǎng)整型數(shù)并返回它字符串s0void*calloc(size_tnelem,size_tsize)分配"nelem"size0如果分配成功返回分配內(nèi)存單元的首地址否則返回0void終止程序運(yùn)行典型的是無限循 voidfree(voidsize0void_NewHeap(void*start,void*end)初始化內(nèi)存分配程序的 一個(gè)典型的調(diào)用是將符號(hào)_bss_end+1的地址用作"start" _bss_end1的目的是堆棧檢查函數(shù)使用_bss_end字節(jié)存貯為標(biāo)志字節(jié)這個(gè)結(jié)束值不能被放入堆棧中externchar_NewHeap(&_bss_end+1,&_bss_end+201);//200intvoid*realloc(void*ptr,size_tptrsizesize可比原來大或小返回指向該內(nèi)存區(qū)的地voidsrand(unsignedlongstrtol(char*s,char**endptr,int按照"base."的格式轉(zhuǎn)換"s"中起始字符為長(zhǎng)整型數(shù)如果"endptr"不為空*endptr將設(shè)定"s"中unsignedlongstrtoul(char*s,char**endptr,int除了返回類型為無符號(hào)長(zhǎng)整型數(shù)外其余同用"#include<string.h>"預(yù)處理后編譯器支持下列函 <string.h>定義了NULL類型void*memchr(void*s,intc,size_t在字符串snc相同的字符如果成功返回匹配字符的地址指針否則返回NULLintmemcmp(void*s1,void*s2,size_t對(duì)字符串s1和s2的前n個(gè)字符進(jìn)行比較如果相同則返回0如果s1中字符大于s2中字符則返回1如果s1中字符小于s2中字符 void*memcpy(void*s1,void*s2,size_t拷貝s2中n個(gè)字符至 但拷貝區(qū)不可以重void*memmove(void*s1,void*s2,size_t拷貝s2中n個(gè)字符至 返回 其與memcpy基本相同但拷貝區(qū)可以重void*memset(void*s,intc,size_tsncschar*strcat(char*s1,char*s2)s2s1的結(jié)尾返回char*strchr(char*s,int在s1中搜索第一個(gè)出現(xiàn)的c 包括結(jié)束NULL字符如果成功返回指向匹配字符的指針如果沒有匹配字符找到返回空指針intstrcmp(char*s1,char比較兩個(gè)字符串如果相同返回0s1>s21s1<s2則返回-1char*strcpy(char*s1,char*s2)拷貝字符串s2至字符串 返回size_tstrcspn(char*s1,chars1搜索與字符串s2NULLs1中找到的匹size_tstrlen(char返回字符串s的長(zhǎng) 不包括結(jié)束NULL字char*strncat(char*s1,char*s2,size_t拷貝字符串s2不含結(jié)束NULL字符中n個(gè)字符到 如果s2長(zhǎng)度比n小則只拷貝intstrncmp(char*s1,char*s2,size_tstrcmp函數(shù)相同nchar*strncpy(char*s1,char*s2,size_tstrcpy函數(shù)相同nchar*strpbrk(char*s1,charstrcspn函數(shù)相同但它返回的是在s1匹配字符的地址指針否則返回NULLchar*strrchr(char*s,intsc并返回它的指針否則返回NULL.size_tstrspn(char*s1,char*s2)s1搜索與字符串s2NULLs1char*strstr(char*s1,chars1中找到與s2s1則返回NULL"constchar*"這些函數(shù)除了它的操作對(duì)象是在FLASH中常數(shù)字符串外其余同c中的函size_tcstrlen(constcharchar*cstrcpy(char*dst,constchar*src);intcstrcmp(constchar*s1,char*s2);<stdarg.h>va_listva_start(va_listfoo,<last-初始化變量foova_arg(va_listfoo,<promotedtype>)下一個(gè)參數(shù)分派指定的類型注意那個(gè)類型必須是高級(jí)類型如 long或小的整型類型如"char"不能被支例如printf()vfprintf()來實(shí)現(xiàn)#include<stdarg.h>intprintf(char*fmt,{va_start(ap,fmt);vfprintf(fmt,ap);}有幾個(gè)庫函數(shù)是用于檢查堆棧是否溢出內(nèi)存圖如下如果硬件堆棧增長(zhǎng)到堆棧中那么軟件堆棧的內(nèi)容將會(huì)被改變也就是說局部變量和別的堆棧項(xiàng)目被改變硬件堆棧是用作函數(shù)的返回地址如果你的函數(shù)調(diào)用層次太深偶然會(huì)發(fā)生這種情況同樣地堆棧溢出進(jìn)數(shù)據(jù)區(qū)域?qū)?huì)改變?nèi)肿兞炕蚱渌o態(tài)分配的項(xiàng)目如果你使用動(dòng)態(tài)分配內(nèi)存還會(huì)改變堆項(xiàng)目這種情況在你定義了太多的局部變量或一個(gè)局部集合變量太大也會(huì)偶AVR硬 的編 AVR的低層硬件行AVR性能除了要最大程序地優(yōu)化代碼外很少使用匯編偶然情況下目標(biāo)MCU的硬件特點(diǎn)在C語言中不能很好地使用很顯然使用匯編和預(yù)處理宏能這些特點(diǎn)io*.hio8515.hiom603.h等定義了指定AVRMCUIO寄存器細(xì)節(jié)這些文件是從ATMEL發(fā)布的文件經(jīng)過修改以匹配這個(gè)編譯器的語法要求文件macros.h定義了許多有用的宏例如宏UART_TRANSMIT_ON()能使UART開始工作這個(gè)編譯器的效率很高當(dāng)由IO寄存器的內(nèi)存時(shí)能產(chǎn)生單周期指令象inoutsbissbi等參考IO寄存器avr.hIObit有一些模糊盡管io*.hbit的位置io*.hIObitmacros.hBIT()宏例#define 0x80//外部RAM...(C程序)MCUCR|=#define ...(你的C程序)#include<macros.h>一個(gè)共同的任務(wù)是編程微控制器MCU打開或關(guān)閉IO寄存器的一些位bit很幸運(yùn)標(biāo)準(zhǔn)CC結(jié)構(gòu)C定義了一些按位進(jìn)a|b–按位或這個(gè)表達(dá)式指示中a被表達(dá)式中的b按位進(jìn)行或運(yùn)算這慣用于打開某些位尤其常用|=的形式例如PORTA|=0x80;//打開位7(最a&b–按位與1時(shí)有用IfPORTA&0x81)0)//檢查7注意圓括號(hào)需要括在&運(yùn)算符的周圍因?yàn)樗?=相比運(yùn)算優(yōu)先級(jí)較低這是C程序中很多a^b–按位異或這個(gè)運(yùn)算對(duì)一個(gè)位取反有用例如在下面的例子中7PORTA^=0x80;//~a–按位取反.在表達(dá)式中這個(gè)運(yùn)算執(zhí)行一個(gè)取反當(dāng)用按位與運(yùn)算關(guān)閉某些位時(shí)與這個(gè)運(yùn)算組合使用尤其有用如這個(gè)編譯器對(duì)這些運(yùn)算能產(chǎn)生最理想的機(jī)器指令例如sbic指令可以用在根據(jù)位的狀態(tài)進(jìn)行AVRMCU的例如分開的地址空間允許AVR裝置比傳統(tǒng)結(jié)構(gòu)的存貯器例如Atmega系列允許有超過64K字WORD的程序存貯器和64K字節(jié)的數(shù)據(jù)存貯器將來的MCU裝置可能用到的程序存貯器而程序計(jì)數(shù)器仍保留在16位上不幸的是C不是在這種機(jī)器上發(fā)明的特別地C指針是任意一個(gè)數(shù)據(jù)指針或函數(shù)指針C規(guī)則已經(jīng)指定你不可以假設(shè)數(shù)據(jù)和函數(shù)指針能被向前和向后修改同是哈佛結(jié)構(gòu)的AVR要求C解決了這個(gè)問題ImageCraftAVR編譯器使用"const"限定詞表示項(xiàng)目是在程序存貯器中注意對(duì)指針描述這個(gè)const限定詞可以應(yīng)用于不同的場(chǎng)合不管是限定指針變量自己還是指向項(xiàng)目的指針例如constinttable[]={1,2,3};constchar*ptr1;char*constconstchar*const"table""ptr1"是一個(gè)項(xiàng)目在數(shù)據(jù)存貯器而指向數(shù)據(jù)的指針在程序存貯器"ptr2"是一個(gè)項(xiàng)目在程序存貯器而指向數(shù)據(jù)的指針在數(shù)據(jù)存貯器最后"ptr3"是項(xiàng)目在程序"table"和和"ptr1"是很典型的C編譯器生成LPM指令來程序存貯器注意C標(biāo)準(zhǔn)不要求"const"數(shù)據(jù)是放入只讀存貯器中而且在傳統(tǒng)結(jié)構(gòu)中除了正確就沒有要緊的了因而在承認(rèn)參數(shù)的Cconst限定是非傳統(tǒng)的無論如何這樣做與標(biāo)準(zhǔn)C函例如標(biāo)準(zhǔn)"strcpy"strcpy(char*dst,constchar*src)帶有const限定的第二個(gè)參數(shù)表示函數(shù)不能修改參數(shù)然而在ICCAVR下const限定詞表示第二個(gè)參數(shù)指向程序存貯器是不合適的因此這些函數(shù)定義設(shè)有const限制FLASHconstFLASH中而可能導(dǎo)致不明AVR中程序內(nèi)存和數(shù)據(jù)內(nèi)存分開給程序內(nèi)存和數(shù)據(jù)內(nèi)存的說明帶來了一定的復(fù)雜性這頁說明字符串這個(gè)編譯器將帶有const說明的表和項(xiàng)目放入程序存貯器中最的是字符串的分配和處理Cchar指針如果字符串是分配進(jìn)程序存貯器中那么所有字符串庫函數(shù)中的任意一個(gè)必須被成不同于指針的操作或者字符串也必須被分配在數(shù)據(jù)存貯器中貯器的為了確保它們的值是正確的在程序啟動(dòng)時(shí)字符串是由程序存貯器拷貝進(jìn)數(shù)據(jù)存貯器中的因此只有單一的字符串拷貝函數(shù)是必須的編譯器執(zhí)行全局變量初始化也是這樣處理的如果你希望節(jié)省空間你能使用常量字符型數(shù)組來將字符串只分配進(jìn)程序存貯器 例constcharo[]="o在這個(gè)例子中o可以在上下文中作為字符串使用但不能用作標(biāo)準(zhǔn)C庫中字符串函數(shù)Printf已被擴(kuò)展成帶%S格式字符來輸出只存貯于FLASH中字符 另 新的字符串函數(shù)只分配全部字符串到FLASH存貯器當(dāng)對(duì)應(yīng)"Project->Options->->StringsInFLASHOnly"檢查框被選中時(shí)你可以指揮編譯器將字符串只放在FLASH中這時(shí)稱必須很地調(diào)用庫函數(shù)當(dāng)這個(gè)選項(xiàng)是選中的字符串類型"constchar*""constchar*"與字符串有關(guān)系外創(chuàng)建了cprintfcsprintf函數(shù)承認(rèn)字符串格式的類型參考標(biāo)準(zhǔn)輸入輸出函數(shù)注意當(dāng)選項(xiàng)2只分配全部字符串到FLASH存貯器中時(shí)應(yīng)使用cprintf()對(duì)constchar*及constcharptr[]類型字符串并且加%S參數(shù)當(dāng)選項(xiàng)1時(shí)應(yīng)使用 對(duì)constchar*及constcharptr[]類型字符串并且加%S參生成代碼使用兩個(gè)堆棧一個(gè)是用于子程序調(diào)用和中斷操作的硬件堆棧一個(gè)是用于以堆棧結(jié)構(gòu)傳遞的參數(shù)臨時(shí)變量和局部變量的堆棧 堆棧通常如果你的程%fprintf()等庫函數(shù)那么默認(rèn)的16字節(jié)應(yīng)該在大多數(shù)的例子中能良好工作在絕大多數(shù)程序中除了很繁重的遞歸調(diào)用程序再入式函數(shù)最多40個(gè)字節(jié)堆棧和數(shù)據(jù)內(nèi)存的大小是受在編譯器選項(xiàng)中的目標(biāo)裝置項(xiàng)設(shè)定限制的數(shù)據(jù)區(qū)從0x60開始分配在IO空間后面是正確的允許數(shù)據(jù)區(qū)和堆棧彼此相向生長(zhǎng)如果你選擇的目標(biāo)裝置帶有32K或64K的外部SRAM那么堆棧是放在SRAM的頂部而且向低內(nèi)存地址方向生長(zhǎng)參考程序和數(shù)據(jù)內(nèi)存的使用能溢出并且當(dāng)一個(gè)堆棧溢出時(shí)會(huì)偶然產(chǎn)生壞的事情你可以使用堆棧檢查函數(shù)檢測(cè)溢出情況 除了在匯編文件中寫匯編函數(shù)外匯編允許你寫匯編代碼進(jìn)你的C文件中當(dāng)然在你的工程使用匯編源文件作為一個(gè)部件是良好的匯編的語法是多個(gè)匯編可以被符號(hào)\n分隔成新的一行String可以被用來指定多個(gè) 加的ASM為了在匯編中一個(gè)C的變量可使用%<變量名>格式如registerunsignedcharuc;asm("mov%uc,R0\n"任意一個(gè)C變量都可以被如果你在匯編指令中需使用一個(gè)CPU寄存器你必須使用寄存器存貯類register來強(qiáng)制分配一個(gè)局部變量到CPU寄存器中通常使用匯編局部寄存器的能力是有限的如果你在函數(shù)中描述了太多的寄存器變量就很可能沒有寄存器可用在這種情況你將從匯編程序得到一個(gè)錯(cuò)誤那時(shí)也不能控制寄存器變量的分配所以你的匯編指令很可能失敗作為例子使用LDI指令需要使用R16~R31中的一個(gè)寄存器但這里沒有請(qǐng)求使用匯編同樣也沒有上半部分的整數(shù)寄存器匯編可以被用在C函數(shù)的或外部編譯器將匯編的每行都分解成可讀的不AVR匯編器ImageCraft匯編器允許放置在任意地方所以你可以在你的匯編代碼中創(chuàng)建當(dāng)匯編在函數(shù)外部時(shí)你可能得到一個(gè)警告你不要理睬這個(gè)警告 IOIOSREG可以被兩條路線IO0x000x3f之間可以INOUTIO0x200x5F通數(shù)據(jù)指令和地址模式兩種方法在C中都可使用數(shù)據(jù)內(nèi)存地址一個(gè)直接地址可以通過加指針類型符號(hào)直接例如SREG的數(shù)據(jù)內(nèi)存在地址是0x5F:unsignedcharc*(volatileunsignedchar*)0x5F;//*(volatileunsignedchar*)0x5F|0x80;//031CPU寄存器注意不要不注意地改變CPU寄存當(dāng)在IO寄存器范圍中的數(shù)據(jù)內(nèi)存時(shí)編譯器自動(dòng)生成低級(jí)指令象inout sbrc等IO地址你可以使用匯編和預(yù)處理宏來IO地registerunsignedcharuc;asm("in%uc,$3F");//SREGasm("out //打開全局中斷avr.hIObit有一些模糊盡管io*.hbit的位置io*.hIObitmacros.hBIT()宏例#define 0x80//外部RAMC程序)MCUCR|=SRE;#define ...(C程序#include<macros.h>MCUCR|=8你的程序可能需要使用絕對(duì)內(nèi)存地址例如外部IO設(shè)備通常被成特殊的內(nèi)存這些可能包括LCD界面和雙口SRAM通常你可以使用匯編或單獨(dú)的匯編文件來描述那些定位在特殊內(nèi)存地址的數(shù)據(jù)在稍后版本的編譯器中已在C語言中提供這些能力在下面有例子中假設(shè)有一個(gè)兩字節(jié)的LCD0x1000地址LCD數(shù)據(jù)寄存器定位在0x1002地址并且有一個(gè)100字節(jié)的SRAM0x2000的地址使用匯編模式在一個(gè)匯編文件中輸入以下內(nèi)容.area _LCD_control_register::.blkw_LCD_data_register::.blkw .blkbexternunsignedintLCD_control_register,LCD_data_register;externchardual_port_SRAM[100];注意界面規(guī)定在匯編文件中外部變量名稱是帶'_'前墜 并且使用兩個(gè)冒號(hào)定義為全局變使用匯匯編遵守同樣的匯編語則除了它被附加了一個(gè)asm()偽函數(shù)在C文件中關(guān)于上asm(".areamemory(abs)" C中你仍然要使用"extern"C編譯器不會(huì)真正知道在asm中的 C任務(wù)Tasks作為匯編界面的描述和調(diào)用規(guī)則編譯器通常在生成代碼來保存和恢復(fù)保護(hù)的寄存器在一些情況下這些行為可能是不合適的例如如果你使用RTOS實(shí)時(shí)操作系統(tǒng)RTOS管理著寄存器的保存和恢復(fù)并作為任務(wù)切換處理的一部分編譯器如果再這些代碼就變得多余了為了這種行為你可以使用"#pragma k"例如 kdrive_motoremit_sirenvoiddrive_motor(){...voidemit_siren()這個(gè)附注(pragma)必須被用在函數(shù)定義之前注意作為默認(rèn)的情況從不返回的程序"main"是有這個(gè)屬性的它也沒有必要為返回保存和恢復(fù)任意一個(gè)寄存器 C中斷操作中C中可以使用無論函數(shù)定義在文件的什么地方你必須用一個(gè)附注pragma在函#pragmainterrupt_handler<name>:<vectornumber>"vectornumber"1用RETIRET#pragma void{}rjmp ;對(duì)普通 jmp ;對(duì) 上述指令定位在0x06字節(jié)地址針對(duì)普通裝置和0x0c字節(jié)地址針對(duì)Mega裝置使用2個(gè)字作為中斷向 非Mega使用1字作為中斷向量 多個(gè)用空格分開的名稱分別帶有多個(gè)不同的向量號(hào)例如#pragmainterrupt_handlertimer_ovf:7你可以用匯編語言寫中斷操作如果在你的匯編操作調(diào)用C函數(shù)無論如何要 程序要保存和恢復(fù)揮發(fā)寄存器參考匯編界面C函數(shù)不做這些工作如果你使用匯編中斷操作那么你必須自己定義向量你使用"abs"屬性描述絕對(duì)區(qū)域用 來rjmp或jmp指令的正確地址注意這個(gè) "使用的是字節(jié)地;ATMega.area ;中斷 rjmp;ATMega.area ; jmp UARTgetcharputcharUART\icc\examples.avr有一個(gè)以中斷方式工作的IO程序可以代替默認(rèn)的程序 EEPROMEEPROM在運(yùn)行時(shí)可以使用庫函數(shù) EEPROM_READ(intlocation,object)這個(gè)宏調(diào)用了EEPROMReadBytes函數(shù)從EEPROM指定位置數(shù)據(jù)送給數(shù)據(jù)對(duì)象可以是任意程序變量包括結(jié)構(gòu)和數(shù)組intEEPROM_Read(0x1i);//2iEEPROM_WRITE(intlocation,object)是任意程序變量包括結(jié)構(gòu)和數(shù)組EEPROM_WRITE(0x1, //寫兩個(gè)字節(jié)至這些宏和函數(shù)可以用于任意AVR裝置對(duì)EEPROM單元少于256字節(jié)的MCU即使不需要高地址字節(jié)它們也是欠佳的因?yàn)樗匀皇且獙懙娜绻P(guān)系重大你可以為EEPROM較少EEPROMC源文件中它作為一個(gè)全局變量被分配到特殊調(diào)用區(qū)域"eeprom."中的這是可以用附注實(shí)現(xiàn)的結(jié)果是產(chǎn)生擴(kuò)展名為.eep的輸出文件例如#pragmadata:eepromintfoo=chartable[]={0,1,2,3,4,5};#pragmadata:dataintEEPROM_READ((int)&foo, //i等于第二個(gè)附注是必須的為返回默認(rèn)的"data."區(qū)域需要重設(shè)數(shù)據(jù)區(qū)名注意因?yàn)锳VR的硬件原因初始化EEPROM數(shù)據(jù)至0地址是不可以使用注意當(dāng)使用外部描述比如在另一個(gè)文件中的foo你不需要加入這個(gè)附 例externintfoo;inti;EEPROM_READ((int)&foo,unsignedcharEEPROMread(intintEEPROMwrite(intlocation,unsignedcharEEPROM0voidEEPROMReadBytes(intlocation,void*ptr,int從EEPROM指定位置處開始"size"個(gè)字節(jié)至由"ptr."指向的緩沖voidEEPROMWriteBytes(intlocation,void*ptr,int個(gè)字節(jié)寫的內(nèi)容由 SPI一個(gè)以查尋模 SPI的函數(shù)是提供 的信息參考 一個(gè)帶8K程序存貯器的裝置全部范圍內(nèi)的跳轉(zhuǎn)可以使用相對(duì)轉(zhuǎn)移和調(diào)用指令(rjmp和rcall)8K為分界的例如一個(gè)較遠(yuǎn)的跳轉(zhuǎn)跳轉(zhuǎn)到0x2100字節(jié)處0x2000為8K實(shí)際上會(huì)跳轉(zhuǎn)到地址0x100處8KC 類 長(zhǎng)度(字節(jié) 范unsigned signed -char unsigned (signed) - (signed) - (signed) - +/-1.175e- (*)"char"等同于"unsignedchar"floats和doublesIEEE標(biāo)準(zhǔn)32位格式7位表示指數(shù)23位表示尾數(shù)1位表示符號(hào)unsignedsigned關(guān)鍵字而且將被包含在一個(gè)較小的空間中如可定義structunsigneda:1,b:這個(gè)結(jié)構(gòu)體的長(zhǎng)度只有一個(gè)1 位域是從右往左放置2C語言中的名稱在匯編文件中是以下劃線為前墜 如函數(shù)main()在匯編模塊中是以_main(的名稱的有效長(zhǎng)度為32個(gè)字符在名稱后面加兩個(gè)冒號(hào)如.word1(C文件中externint

可以定義成一個(gè)全局變量R16/R17R18/R19傳遞如果參數(shù)是長(zhǎng)整型或浮點(diǎn)數(shù)則通過R16/R17/R18/R19傳遞其余參數(shù)通過堆棧傳遞比整型參數(shù)小的如char參數(shù)擴(kuò)展成整型int長(zhǎng)度傳遞即使函數(shù)原型是可用的如果R16/R17已傳遞了R18/R19傳遞而高半部分通過堆棧傳遞R16/R17R16/R17/R18/R19R28/R29YR10/R11/R12/R13/R14/R15/R20/R21/R22/R23這些寄存器是調(diào)用保護(hù)寄存器這些d)器別的寄存可以在匯編語言函數(shù)中使用而不被保護(hù)和恢復(fù)這些寄存器是調(diào)用揮發(fā)寄存器e中斷處這不同于普通的函數(shù)調(diào)用在中斷操作中必須保護(hù)和恢復(fù)它所使用的全部寄存器如果你是C函數(shù)來描述中斷處理那么編譯器有能力自動(dòng)完成的如果使用匯編寫中斷處理而它又CC函數(shù)調(diào)用不保護(hù)它們中斷處理操作同普通程序操作是異步的中斷處理或它的函數(shù)調(diào)用不能改變?nèi)我庖粋€(gè)MCU寄3數(shù)之前應(yīng)當(dāng)用#include語句包含頭文件<math.h> 否則在這些程序返回它們的值后你的程序?qū)⒉还ぷ鬟@和那些返回整型值的函數(shù)是有不同之處的(也就是傳遞結(jié)構(gòu)的地址)和傳遞任意數(shù)據(jù)項(xiàng)目的地址是相同的,都是通過一個(gè)2字節(jié)的指針當(dāng)一個(gè)返回結(jié)構(gòu)的函數(shù)被調(diào)用時(shí)這個(gè)調(diào)用函數(shù)分配一個(gè)臨時(shí)貯藏庫而且傳遞一個(gè)隱藏指針給調(diào)用函數(shù)當(dāng)這個(gè)函數(shù)返回時(shí)它拷貝返回值進(jìn)這個(gè)臨時(shí)貯藏庫程序和數(shù)據(jù)區(qū)的使用程序存貯器是被用于保存你的程序代碼常數(shù)表和確定數(shù)據(jù)的初始值比如字符串全局變量編譯器可以生成一個(gè)對(duì)應(yīng)程序存貯器映像的輸出文件HEX文件這個(gè)文件可以被編程器用來對(duì)通常編譯器不能使用任意64K字節(jié)以上的程序存貯器為了64K字節(jié)邊界以上的存貯器如在Mega103裝置中你需要在設(shè)定RAMPZ寄存器后直接調(diào)用ELPM指令數(shù)據(jù)存貯器僅指這個(gè)數(shù)據(jù)存貯器是被用于保存變量堆棧結(jié)構(gòu)和動(dòng)態(tài)內(nèi)存分配的堆通常它們不產(chǎn)生輸出文件但在程序運(yùn)行時(shí)使用一個(gè)程序使用數(shù)據(jù)內(nèi)存如下圖堆CPUIO內(nèi)存圖的底部是地址0開始的960x60字節(jié)是CPU寄存器和IO寄存器編譯器從0x60往上放置全局變量和字符串在變量區(qū)域的頂部你可以分配動(dòng)態(tài)內(nèi)存在高端地址硬件堆棧開始于SRAM的最后位置在它的下面是向下生長(zhǎng)的堆棧它要求你作為程序師要確保硬件堆棧不生長(zhǎng)進(jìn)堆棧而堆棧不生長(zhǎng)進(jìn)堆否則將導(dǎo)致意外的結(jié)果數(shù)據(jù)存貯器外部如果你選擇帶有32K或64K外部SRAM的目標(biāo)裝置那么堆棧是放置在SRAM的頂部并且是朝內(nèi)存地址向下生長(zhǎng)數(shù)據(jù)內(nèi)存是開始于硬件堆棧的頂部并且向上生長(zhǎng)這樣分配的原因是在多數(shù)場(chǎng)合SRAM比外部SRAM的速度要快分配堆棧到較快的內(nèi)存是有很多好5編譯器生成代碼和數(shù)據(jù)到不同的區(qū)域"areas."區(qū)域按照內(nèi)存地址增高的順序被編譯器使用interrupt func_lit–函數(shù)表區(qū)這個(gè)區(qū)的每個(gè)字包括了函數(shù)的地址為了與代碼壓縮完全兼容所有間接的函數(shù)索引必須通過間接的額外對(duì)準(zhǔn)如果你在C中使用函數(shù)指針調(diào)用函數(shù)這是自動(dòng)完成的在匯編中舉例如下;_foo.areaPL_foo::.word_foo創(chuàng)建函數(shù).arealdiR30,<PL_fooldiR31,>PL_foorcallxicall你可以間接地在函數(shù)表地址送入R30/R31寄存器對(duì)后使用庫函數(shù)xicall調(diào)用這個(gè)函lit–text–這個(gè)區(qū)域包括程序代碼data這個(gè)區(qū)域包括全局變量靜態(tài)變量和字符串全局變量和字符串的初始值是保存在"idata"區(qū)域并且是在啟動(dòng)時(shí)被拷貝進(jìn)數(shù)據(jù)區(qū)的bss這個(gè)區(qū)域包括未初始化的全局變量ANSIC0EEPROM存貯器eeprom-EEPROM數(shù)據(jù)EEPROM數(shù)據(jù)是寫進(jìn)擴(kuò)展名為.eep ICCAVR可以輸出COFF格式調(diào)試文使用戶可ATMELAVRStudio中進(jìn)行源程序級(jí)的AVRStudioIOICCAVR的編譯選項(xiàng)中必須將AVRStudioSimulatorIO一項(xiàng)打鉤ICCAVR匯編參1名(‘_’|[a-z])[[a-z]|[0-9]|‘_’ ICC中匯編名稱必須由下劃線或字母開始隨后跟字母數(shù)字或下劃線組成在這個(gè)文檔中PC地址的標(biāo)號(hào)名稱中的任意一個(gè)一個(gè)名稱的長(zhǎng)度最多為30個(gè)字符長(zhǎng)而且區(qū)分大小寫匯編指令和匯編偽指令除外符號(hào)可以只用在程序模塊中也可顯式地被其它模塊使用在以前的例子中符號(hào)

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(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)論