国产肉体XXXX裸体137大胆,国产成人久久精品流白浆,国产乱子伦视频在线观看,无码中文字幕免费一区二区三区 国产成人手机在线-午夜国产精品无套-swag国产精品-国产毛片久久国产

新聞中心

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

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

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

本文引用地址:http://m.ptau.cn/article/201611/319595.htm

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

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

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

但在單片機上用 C 語言寫程序和在 PC 機上寫程序絕對不能簡單等同?,F(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 單片機進(jìn)行系統(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掛接。安裝成功后可以進(jìn)入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ù)進(jìn)行嚴(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 定位必須由編程員自己決定,但在編寫原程序時進(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ù)操作。

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)局部變量都可以按已知的固定地址地進(jìn)行直接尋

址,用 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é)中以便需要時一次性地進(jìn)行讀寫,這一

功能可以通過定義一個位域結(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)程序中把非位變量進(jìn)行強制類型轉(zhuǎn)換成位變量時,要注意編譯器只對普通變量的最低

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

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

回的位變量將存放于單片機的進(jìn)位位中帶出返回。

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)閉