<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

          EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計應(yīng)用 > PIC單片機C語言編程教程(1)

          PIC單片機C語言編程教程(1)

          作者: 時間:2016-11-22 來源:網(wǎng)絡(luò) 收藏
          PIC 單片機 C 語言編程簡介

          本文引用地址:http://www.ex-cimer.com/article/201611/319595.htm

          C 語言來開發(fā)單片機系統(tǒng)軟件最大的好處是編寫代碼效率高、軟件調(diào)試直觀、維護升級方便、

          代碼的重復(fù)利用率高、便于跨平臺的代碼移植等等,因此 C 語言編程在單片機系統(tǒng)設(shè)計中已得到越

          來越廣泛的運用。針對 PIC 單片機的軟件開發(fā),同樣可以用 C 語言實現(xiàn)。

          但在單片機上用 C 語言寫程序和在 PC 機上寫程序絕對不能簡單等同。現(xiàn)在的 PC 機資

          源十分豐富,運算能力強大,因此程序員在寫 PC 機的應(yīng)用程序時幾乎不用關(guān)心編譯后的可

          執(zhí)行代碼在運行過程中需要占用多少系統(tǒng)資源,也基本不用擔(dān)心運行效率有多高。寫單片機

          C 程序最關(guān)鍵的一點是單片機內(nèi)的資源非常有限,控制的實時性要求又很高,因此,如

          果沒有對單片機體系結(jié)構(gòu)和硬件資源作詳盡的了解,以筆者的愚見認(rèn)為是無法寫出高質(zhì)量實

          用的 C 語言程序。這就是為什么前面所有章節(jié)中的的示范代碼全部用基礎(chǔ)的匯編指令實現(xiàn)

          的原因,希望籍此能使讀者對 PIC 單片機的指令體系和硬件資源有深入了解,在這基礎(chǔ)之

          上再來討論 C 語言編程,就有水到渠成的感覺。

          本書圍繞中檔系列 PIC 單片機來展開討論,Microchip 公司自己沒有針對中低檔系列 PIC

          單片機的 C 語言編譯器,但很多專業(yè)的第三方公司有眾多支持 PIC 單片機的 C 語言編譯器

          提供,常見的有 Hitech、CCS、IAR、Bytecraft 等公司。其中筆者最常用的是 Hitech 公司的

          PICC 編譯器,它穩(wěn)定可靠,編譯生成的代碼效率高,在用 PIC 單片機進行系統(tǒng)設(shè)計和開發(fā)

          的工程師群體中得到廣泛認(rèn)可。其正式完全版軟件需要購置,但在其網(wǎng)站上有限時的試用版

          供用戶評估。另外,Hitech 公司針對廣大 PIC 的業(yè)余愛好者和初學(xué)者還提供了完全免費的學(xué)

          習(xí)版 PICC-Lite 編譯器套件,它的使用方式和完全版相同,只是支持的 PIC 單片機型號限制

          在 PIC16F84、PIC16F877 和 PIC16F628 等幾款。這幾款 Flash 型的單片機因其所具備的豐富

          的片上資源而最適用于單片機學(xué)習(xí)入門,因此筆者建議感興趣的讀者可從 PICC-Lite 入手掌

          握 PIC 單片機的 C 語言編程。

          在此列出幾個主要的針對 PIC 單片機的 C 編譯器相關(guān)連接網(wǎng)址,供讀者參考:

          Hitech-PICC: www.htsoft.com


          IAR:www.iar.com

          CCS:www.ccsinfo.com/picc.shtml

          ByteCraft:www.bytecraft.com/mpccaps.html


          本章將介紹 Hitech-PICC 編譯器的一些基本概念,由于篇幅所限將不涉及 C 語言的標(biāo)準(zhǔn)

          語法和基礎(chǔ)知識介紹,因為在這些方面都有大量的書籍可以參考。重點突出針對 PIC 單片

          機的特點而所需要特別注意的地方。

          11.2

          Hitech-PICC 編譯器

          PICC 基本上符合 ANSI 標(biāo)準(zhǔn),除了一點:它不支持函數(shù)的遞歸調(diào)用。其主要原因是因

          為 PIC 單片機特殊的堆棧結(jié)構(gòu)。在前面介紹 PIC 單片機架構(gòu)時已經(jīng)詳細(xì)說明了 PIC 單片機

          中的堆棧是硬件實現(xiàn)的,其深度已隨芯片而固定,無法實現(xiàn)需要大量堆棧操作的遞歸算法;

          另外在 PIC 單片機中實現(xiàn)軟件堆棧的效率也不是很高,為此,PICC 編譯器采用一種叫做“靜

          態(tài)覆蓋”的技術(shù)以實現(xiàn)對 C 語言函數(shù)中的局部變量分配固定的地址空間。經(jīng)這樣處理后產(chǎn)

          生出的機器代碼效率很高,按筆者實際使用的體會,當(dāng)代碼量超過 4K 字后,C 語言編譯出

          的代碼長度和全部用匯編代碼實現(xiàn)時的差別已經(jīng)不是很大(<10%),當(dāng)然前提是在整個 C

          代碼編寫過程中須時時處處注意所編寫語句的效率,而如果沒有對 PIC 單片機的內(nèi)核結(jié)構(gòu)、

          各功能模塊及其匯編指令深入了解,要做到這點是很難的。

          11.3

          MPLAB-IDE 內(nèi)掛接 PICC

          PICC 編譯器可以直接掛接在 MPLAB-IDE 集成開發(fā)平臺下,實現(xiàn)一體化的編譯連接和

          原代碼調(diào)試。使用 MPLAB-IDE 內(nèi)的調(diào)試工具 ICE2000、ICD2 和軟件模擬器都可以實現(xiàn)原

          代碼級的程序調(diào)試,非常方便。

          首先必須在你的計算機中安裝PICC編譯器,無論是完全版還是學(xué)習(xí)版都可以和

          MPLAB-IDE掛接。安裝成功后可以進入IDE,選擇菜單項Project Set Language Tool

          Locations…,打開語言工具掛接設(shè)置對話框,如圖 11-1 所示:

          %C3%82%C2%B3%C3%83%C2%8C%C3%82%C2%BD%C3%83%C2%8C%C3%82%C2%B3%C3%83%C2%8C.files/7.jpg" src="file:///F:/data/%C3%83%C2%8F%C3%83%C2%82%C3%83%C2%94%C3%83%C2%98/PIC%C3%82%C2%B5%C3%82%C2%A5%C3%83%C2%86%C3%82%C2%AC%C3%82%C2%BB%C3%83%C2%BAC%C3%83%C2%93%C3%83%C2%AF%C3%83%C2%91%C3%83%C2%94%C3%82%C2%B1%C3%83%C2%A0%3Cwbr%3E%C3%82%C2%B3%C3%83%C2%8C%C3%82%C2%BD%C3%83%C2%8C%C3%82%C2%B3%C3%83%C2%8C.files/7.jpg" />

          圖 11-1 MPLAB-IDE 語言工具設(shè)置對話框

          在對話框中選擇“HI-TECH PICC Toolsuite”欄,展開可執(zhí)行文件組“Executable”后,

          列出了將被 MPLAB-IDE 后臺調(diào)用的編譯器所用到的所有可執(zhí)行文件,其中有匯編編譯器

          “PICC Assembler”、C 原程序編譯器“PICC Compiler”和連接定位程序“PICC Linker”。同

          時在此列表中還顯示了對應(yīng)的可執(zhí)行程序名,請注意在這里都是“PICC.EXE”。用鼠標(biāo)分別

          點擊選中這三項可執(zhí)行文件,觀察對話框下面“Location”一欄中顯示的文件路徑,用

          “Browse…”按紐,從計算機中已經(jīng)安裝的 PICC 編譯器文件夾中選擇 PICC.EXE 文件。實

          際上 PICC.EXE 只是一個調(diào)度管理程序,它會按照所輸入的文件擴展名自動調(diào)用對應(yīng)的編譯

          器和連接器,用戶要注意的是 C 語言原程序擴展名用“.c”,匯編原程序用“.as”即可。

          工具掛接完成后,在建立項目時可以選擇語言工具為“HI-TECH PICC”,具體步驟可以

          參閱第三章 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ù)值計算、I2C 總線

          作、命令按鍵處理和液晶顯示驅(qū)動等不同的功能分別在不同的獨立的原程序模塊中實現(xiàn)。

          %C3%82%C2%B3%C3%83%C2%8C%C3%82%C2%BD%C3%83%C2%8C%C3%82%C2%B3%C3%83%C2%8C.files/8.jpg" src="file:///F:/data/%C3%83%C2%8F%C3%83%C2%82%C3%83%C2%94%C3%83%C2%98/PIC%C3%82%C2%B5%C3%82%C2%A5%C3%83%C2%86%C3%82%C2%AC%C3%82%C2%BB%C3%83%C2%BAC%C3%83%C2%93%C3%83%C2%AF%C3%83%C2%91%C3%83%C2%94%C3%82%C2%B1%C3%83%C2%A0%3Cwbr%3E%C3%82%C2%B3%C3%83%C2%8C%C3%82%C2%BD%C3%83%C2%8C%C3%82%C2%B3%C3%83%C2%8C.files/8.jpg" />

          圖 11-2 C 語言多模塊編程

          11.4 PIC 單片機的 C 語言原程序基本框架

          基于 PICC 編譯環(huán)境編寫 PIC 單片機程序的基本方式和標(biāo)準(zhǔn) C 程序類似,程序一般由以

          下幾個主要部分組成:

          &O1540; 在程序的最前面用#include 預(yù)處理指令引用包含頭文件,其中必須包含一個編譯器

          提供的“pic.h”文件,實現(xiàn)單片機內(nèi)特殊寄存器和其它特殊符號的聲明;

          &O1540; 用“__CONFIG”預(yù)處理指令定義芯片的配置位;

          &O1540; 聲明本模塊內(nèi)被調(diào)用的所有函數(shù)的類型,PICC 將對所調(diào)用的函數(shù)進行嚴(yán)格的類型

          匹配檢查;

          &O1540; 定義全局變量或符號替換;

          &O1540; 實現(xiàn)函數(shù)(子程序),特別注意 main 函數(shù)必須是一個沒有返回的死循環(huán)。

          下面的例 11-1 為一個 C 原程序的范例,供大家參考。

          #include //包含單片機內(nèi)部資源預(yù)定義

          #include “pc68.h” //包含自定義頭文件

          //定義芯片工作時的配置位

          __CONFIG (HS & PROTECT & PWRTEN & BOREN & WDTDIS);

          //聲明本模塊中所調(diào)用的函數(shù)類型

          void SetSFR(void);

          void Clock(void);

          void KeyScan(void);

          void Measure(void);

          void LCD_Test(void);

          void LCD_Disp(unsigned char);

          //定義變量

          unsigned char second, minute, hour;

          bit flag1,flag2;

          //函數(shù)和子程序

          void main(void)

          {

          SetSFR();

          PORTC = 0x00;

          TMR1H += TMR1H_CONST;

          LED1 = LED_OFF;

          LCD_Test();

          //程序工作主循環(huán)

          while(1) {

          asm(“clrwdt”);

          Clock();

          KeyScan();

          Measure();

          SetSFR();

          }

          }

          //清看門狗

          //更新時鐘

          //掃描鍵盤

          //數(shù)據(jù)測量

          //刷新特殊功能寄存器

          11.5

          PICC 中的變量定義


          例 11-1 C 語言原程序框架舉例

          11.5.1 PICC 中的基本變量類型


          PICC 遵循 Little-endian 標(biāo)準(zhǔn),多字節(jié)變量的低字節(jié)放在存儲空間的低地址,高字節(jié)放

          在高地址。

          11.5.2 PICC 中的高級變量

          基于表 11-1 的基本變量,除了 bit 型位變量外,PICC 完全支持?jǐn)?shù)組、結(jié)構(gòu)和聯(lián)合等復(fù)

          合型高級變量,這和標(biāo)準(zhǔn)的 C 語言所支持的高級變量類型沒有什么區(qū)別。例如:

          數(shù)組:unsigned int data[10];

          結(jié)構(gòu):struct commInData {

          unsigned char inBuff[8];

          unsigned char getPtr, putPtr;

          };

          聯(lián)合:union int_Byte {

          unsigned char c[2];

          unsigned int i;

          };

          例 11-2 C 語言高級變量舉例

          11.5.3 PICC 對數(shù)據(jù)寄存器 bank 的管理

          為了使編譯器產(chǎn)生最高效的機器碼,PICC 把單片機中數(shù)據(jù)寄存器的 bank 問題交由編程

          員自己管理,因此在定義用戶變量時你必須自己決定這些變量具體放在哪一個 bank 中。如

          果沒有特別指明,所定義的變量將被定位在 bank0,例如下面所定義的這些變量:

          unsigned char buffer[32];

          bit flag1,flag2;

          float val[8];

          除了 bank0 內(nèi)的變量聲明時不需特殊處理外,定義在其它 bank 內(nèi)的變量前面必須加上

          相應(yīng)的 bank 序號,例如:

          bank1 unsigned char buffer[32]; //變量定位在 bank1 中


          bank2 bit flag1,flag2;

          bank3 float val[8];


          //變量定位在 bank2 中

          //變量定位在 bank3 中


          中檔系列 PIC 單片機數(shù)據(jù)寄存器的一個 bank 大小為 128 字節(jié),刨去前面若干字節(jié)的特

          殊功能寄存器區(qū)域,在 C 語言中某一 bank 內(nèi)定義的變量字節(jié)總數(shù)不能超過可用 RAM 字節(jié)

          數(shù)。如果超過 bank 容量,在最后連接時會報錯,大致信息如下:

          Error[000] : Cant find 0x12C words for psect rbss_1 in segment BANK1

          連接器告訴你總共有 0x12C(300)個字節(jié)準(zhǔn)備放到 bank1 中但 bank1 容量不夠。顯然,只

          有把一部分原本定位在 bank1 中的變量改放到其它 bank 中才能解決此問題。

          雖然變量所在的 bank 定位必須由編程員自己決定,但在編寫原程序時進行變量存取操

          作前無需再特意編寫設(shè)定 bank 的指令。C 編譯器會根據(jù)所操作的對象自動生成對應(yīng) bank 設(shè)

          定的匯編指令。為避免頻繁的 bank 切換以提高代碼效率,盡量把實現(xiàn)同一任務(wù)的變量定位

          在同一個 bank 內(nèi);對不同 bank 內(nèi)的變量進行讀寫操作時也盡量把位于相同 bank 內(nèi)的變量

          歸并在一起進行連續(xù)操作。

          11.5.4 PICC 中的局部變量

          PICC 把所有函數(shù)內(nèi)部定義的 auto 型局部變量放在 bank0。為節(jié)約寶貴的存儲空間,它

          采用了一種被叫做“靜態(tài)覆蓋”的技術(shù)來實現(xiàn)局部變量的地址分配。其大致的原理是在編譯

          器編譯原代碼時掃描整個程序中函數(shù)調(diào)用的嵌套關(guān)系和層次,算出每個函數(shù)中的局部變量字

          節(jié)數(shù),然后為每個局部變量分配一個固定的地址,且按調(diào)用嵌套的層次關(guān)系各變量的地址可

          以相互重疊。利用這一技術(shù)后所有的動態(tài)局部變量都可以按已知的固定地址地進行直接尋

          址,用 PIC 匯編指令實現(xiàn)的效率最高,但這時不能出現(xiàn)函數(shù)遞歸調(diào)用。PICC 在編譯時會嚴(yán)

          格檢查遞歸調(diào)用的問題并認(rèn)為這是一個嚴(yán)重錯誤而立即終止編譯過程。

          既然所有的局部變量將占用 bank0 的存儲空間,因此用戶自己定位在 bank0 內(nèi)的變量字

          節(jié)數(shù)將受到一定的限制,在實際使用時需注意。

          11.5.5 PICC 中的位變量

          bit 型位變量只能是全局的或靜態(tài)的。PICC 將把定位在同一 bank 內(nèi)的 8 個位變量合并

          成一個字節(jié)存放于一個固定地址。因此所有針對位變量的操作將直接使用 PIC 單片機的位

          操作匯編指令高效實現(xiàn)?;诖耍蛔兞坎荒苁蔷植孔詣有妥兞?,也無法將其組合成復(fù)合型

          高級變量。

          PICC 對整個數(shù)據(jù)存儲空間實行位編址,0x000 單元的第 0 位是位地址 0x0000,以此后

          推,每個字節(jié)有 8 個位地址。編制位地址的意義純粹是為了編譯器最后產(chǎn)生匯編級位操作指

          令而用,對編程人員來說基本可以不管。但若能了解位變量的位地址編址方式就可以在最后

          程序調(diào)試時方便地查找自己所定義的位變量,如果一個位變量 flag1 被編址為 0x123,那么

          實際的存儲空間位于:

          字節(jié)地址=0x123/8 = 0x24

          位偏移 =0x123%8 = 3

          即 flag1 位變量位于地址為 0x24 字節(jié)的第 3 位。在程序調(diào)試時如果要觀察 flag1 的變化,必

          須觀察地址為 0x24 的字節(jié)而不是 0x123。

          PIC 單片機的位操作指令是非常高效的。因此,PICC 在編譯原代碼時只要有可能,對

          普通變量的操作也將以最簡單的位操作指令來實現(xiàn)。假設(shè)一個字節(jié)變量 tmp 最后被定位在

          地址 0x20,那么


          tmp |= 0x80

          tmp &= 0xf7


          => bsf

          => bcf


          0x20,7

          0x20,3


          if (tmp&0xfe)


          => btfsc 0x20,0


          即所有只對變量中某一位操作的 C 語句代碼將被直接編譯成匯編的位操作指令。雖然編程

          時可以不用太關(guān)心,但如果能了解編譯器是如何工作的,那將有助于引導(dǎo)我們寫出高效簡介

          的 C 語言原程序。

          在有些應(yīng)用中需要將一組位變量放在同一個字節(jié)中以便需要時一次性地進行讀寫,這一

          功能可以通過定義一個位域結(jié)構(gòu)和一個字節(jié)變量的聯(lián)合來實現(xiàn),例如:

          union {

          struct {

          unsigned b0: 1;

          unsigned b1: 1;

          unsigned b2: 1;

          unsigned b3: 1;

          unsigned b4: 1;

          unsigned b5: 1;

          unsigned : 2; //最高兩位保留

          } oneBit;

          unsigned char allBits;

          } myFlag;

          例 11-3 定義位變量于同一字節(jié)

          需要存取其中某一位時可以

          myFlag.oneBit.b3=1; //b3 位置 1

          一次性將全部位清零時可以

          myFlag.allBits=0; //全部位變量清 0

          當(dāng)程序中把非位變量進行強制類型轉(zhuǎn)換成位變量時,要注意編譯器只對普通變量的最低

          位做判別:如果最低位是 0,則轉(zhuǎn)換成位變量 0;如果最低位是 1,則轉(zhuǎn)換成位變量 1。而標(biāo)

          準(zhǔn)的 ANSI-C 做法是判整個變量值是否為 0。另外,函數(shù)可以返回一個位變量,實際上此返

          回的位變量將存放于單片機的進位位中帶出返回。

          11.5.6 PICC 中的浮點數(shù)

          PICC 中描述浮點數(shù)是以 IEEE-754 標(biāo)準(zhǔn)格式實現(xiàn)的。此標(biāo)準(zhǔn)下定義的浮點數(shù)為 32 位長,

          在單片機中要用 4 個字節(jié)存儲。為了節(jié)約單片機的數(shù)據(jù)空間和程序空間,PICC 專門提供了

          一種長度為 24 位的截短型浮點數(shù),它損失了浮點數(shù)的一點精度,但浮點運算的效率得以提

          高。在程序中定義的 float 型標(biāo)準(zhǔn)浮點數(shù)的長度固定為 24 位,雙精度 double 型浮點數(shù)一般

          也是 24 位長,但可以在程序編譯選項中選擇 double 型浮點數(shù)為 32 位,以提高計算的精度。

          一般控制系統(tǒng)中關(guān)心的是單片機的運行效率,因此在精度能夠滿足的前提下盡量選擇

          24 位的浮點數(shù)運算。




          關(guān)鍵詞: PIC單片機C語言編

          評論


          技術(shù)專區(qū)

          關(guān)閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();