PIC 單片機 C 語(yǔ)言編程簡(jiǎn)介(3)
PICC 會(huì )自動(dòng)加入代碼實(shí)現中斷現場(chǎng)的保護,并在中斷結束時(shí)自動(dòng)恢復現場(chǎng),所以編程
員無(wú)需象編寫(xiě)匯編程序那樣加入中斷現場(chǎng)保護和恢復的額外指令語(yǔ)句。但如果在中斷服務(wù)程
序中需要修改某些全局變量時(shí),是否需要保護這些變量的初值將由編程員自己決定和實(shí)施。
用 C 語(yǔ)言編寫(xiě)中斷服務(wù)程序必須遵循高效的原則:
&O1540;
&O1540;
遞歸調用的問(wèn)題,此函數必須為中斷服務(wù)獨家專(zhuān)用。既如此,不妨把原本要寫(xiě)在其
它函數內的代碼直接寫(xiě)在中斷服務(wù)程序中。
&O1540;
算不出現遞歸調用的問(wèn)題,光在中斷入口和出口處為了保護和恢復這些中間臨時(shí)變
量就需要大量的開(kāi)銷(xiāo),嚴重影響中斷服務(wù)的效率。
中檔系列 PIC 單片機的中斷入口只有一個(gè),因此整個(gè)程序中只能有一個(gè)中斷服務(wù)函數。
11.6.5
PICC 提供了較完整的 C 標準庫函數支持,其中包括數學(xué)運算函數和字符串操作函數。
在程序中使用這些現成的庫函數時(shí)需要注意的是入口參數必須在 bank0 中。
如果需要用到數學(xué)函數,則應在程序前
用字符串操作函數,就需要包含“#include ”頭文件。在這些頭文件中提供了函數
類(lèi)型的聲明。通過(guò)直接查看這些頭文件就可以知道 PICC 提供了哪些標準庫函數。
C
printf/sprintf 是一個(gè)非常大的函數,一旦使用,你的程序代碼長(cháng)度就會(huì )增加很多。除非是在
編寫(xiě)試驗性質(zhì)的代碼,可以考慮使用格式化打印函數以簡(jiǎn)化測試程序;一般的最終產(chǎn)品設計
都是自己編寫(xiě)最精簡(jiǎn)的代碼實(shí)現特定格式的數據顯示和輸出。本來(lái),在單片機應用中輸出的
數據格式都相對簡(jiǎn)單而且固定,實(shí)現起來(lái)應該很容易。
對于標準 C 語(yǔ)言的控制臺輸入(scanf)/輸出(printf)函數,PICC 需要用戶(hù)自己編寫(xiě)
其底層函數 getch()和 putch()。在單片機系統中實(shí)現 scanf/printf 本來(lái)就沒(méi)什么太多意義,如
果一定要實(shí)現,只要編寫(xiě)好特定的
出格式化的數據。
11.7
PICC 定義特殊區域值
PICC 提供了相關(guān)的預處理指令以實(shí)現在原程序中定義單片機的配置字和標記單元。
11.7.1
在原程序中定義 PIC 單片機工作配置字的重要性在前面章節中已經(jīng)闡述。在用 PICC 寫(xiě)
程序時(shí)同樣可以在 C 原程序中定義,具體方式如下:
__CONFIG (HS & UNPROTECT & PWRTEN & BORDIS & WDTEN);
上面的關(guān)鍵詞“__CONFIG”(注意前面有兩個(gè)下劃線(xiàn)符)專(zhuān)門(mén)用于是芯片配置字的設
定,后面括號中的各項配置位符號在特定型號單片機的頭文件中已經(jīng)定義(注意不是
頭文件),相互之間用邏輯“與”操作符組合在一起。這樣定義的配置字信息最后將和程序
代碼一起放入同一個(gè) HEX 文件。
在這里列出了適用于
配置字定義方式類(lèi)似,使用前查閱一下對應的頭文件即可。
#define RC
#define HS
0x3FFF // RC 振蕩
0x3FFE // HS 模式
#define XT
#define LP
0x3FFD // XT 模式
0x3FFC // LP 模式
#define WDTEN
#define WDTDIS
#define PWRTEN
0x3FFB //
0x3FF7 //
#define PWRTDIS
#define BOREN
#define BORDIS
0x3FBF //
#define UNPROTECT
#define PROTECT
例 11-6 頭文件預定義的配置信息符號
11.7.2
PIC 單片機中的標記單元定義可以用下面的__IDLOC(注意前面有兩個(gè)下劃線(xiàn)符)預處
理指令實(shí)現,方法如下:
__IDLOC (1234);
其特殊之處是括號內的值全部為 16 進(jìn)制數,不需要用“0x”引導。這樣上面的定義就設定
了標記單元內容為 01020304。
11.8
MPLAB-IDE 中實(shí)現 PICC 的編譯選項設置
在 11.3 節中已經(jīng)介紹了如何實(shí)現 PICC 和 MPLAB-IDE 開(kāi)發(fā)平臺的掛接。一旦項目建立
成功、程序編寫(xiě)完成后即可以通過(guò) MPLAB 環(huán)境下的項目管理工具實(shí)現程序的編譯、連接和
調試。它們的含義分別
是:
-項目維護(Make):MPLAB 檢查項目中的原程序文件,只編譯那些在上次編
譯后又被修改過(guò)的原程序,最后進(jìn)行連接;
-項目重建(Build All):項目中的所有原程序文件,不管是否有修改,都將被
重新編譯一次,最后進(jìn)行連接。
也可以通過(guò) Project 菜單選擇“Make”或“Build All”實(shí)現項目編譯。不管采用何種方
式,在啟動(dòng)編譯過(guò)程前一般都要設定一些編譯選項。
11.8.1
在選擇 PICC 作為語(yǔ)言工具并建立了項目后,同樣通過(guò)菜單項 Configure&O1616;Select Device
在 MPLAB 環(huán)境中選擇具體單片機型號。請回顧一下例 11-1 的代碼,我們在原程序一開(kāi)始
使用了“#include ”實(shí)現了相關(guān)單片機的一些預定義符號的直接引用,但沒(méi)有具體指
明是哪一個(gè)型號。實(shí)際上,“pic.h”頭文件只是一個(gè)簡(jiǎn)單的管理工具(條件判別),它會(huì )按照
MPLAB 所選擇的特定型號的單片機,把真正對應的頭文件包含進(jìn)來(lái)。有興趣者可以直接用
文本編輯工具打開(kāi) pic.h 文件查看其是如何根據不同的單片機型號包含對應的頭文件。
這樣對編程員而言,程序中只需加上一句“#include ”即可。
11.8.2
參考第三章
PICC 語(yǔ)言工具時(shí)對話(huà)框的內容和用 MPAMS 匯編工具相比完全不同。圖 11-3 為 PICC 編譯
環(huán)境下普通選項設定的界面。
在此界面中用戶(hù)唯一能改變的是編譯器查找頭文件時(shí)的指定路徑(Include Path),實(shí)際
上如果編譯器安裝沒(méi)有問(wèn)題,在此界面中這些普通選項的設定無(wú)需任何改動(dòng),編譯器會(huì )自動(dòng)
到缺省認定的路徑中(編譯器安裝后的相關(guān)路徑)查找編譯所需的各類(lèi)文件。
%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/9.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/9.jpg" />
圖 11-3
11.8.3
全局選項將影響項目中所有 C 和匯編原程序的編譯,詳細的設定內容見(jiàn)圖 11-4。其中
必須關(guān)注的有:
&O1540;
就必須打鉤選中。這樣編譯后的結果就能保證
分的程序和數據空間)不被應用程序所占用。
&O1540;
是無(wú)符號數。如果在設計中需要使用帶符號的‘char’型變量,此項就應該被選中。
&O1540;
‘double’型的雙精度浮點(diǎn)數變量的實(shí)現長(cháng)度為 24 位(等同于普通 float 型浮點(diǎn)數)。
在這里可以選擇使其長(cháng)度達 32 位。這樣數值計算的精度將得到提高,但代碼長(cháng)度
將增加,計算速度也會(huì )降低,所以請在權衡利弊后作出你自己的決定。
11.8.4
項目中所有的 C 原程序都將通過(guò) C 編譯器編譯成機器碼,這些選項決定了 C 編譯器是
如何工作的。所有選項又分為兩組:普通選項(General)和高級選項(Advanced),分別見(jiàn)
圖 11-5A 和 11-5B。
C 編譯器的普通選項最重要的就是針對代碼優(yōu)化的設定。如果沒(méi)有特殊原因,應該設定
全局優(yōu)化級別為 9 級(最高級別優(yōu)化),同時(shí)使用匯編級優(yōu)化,這樣最終得到的代碼效率最
高(長(cháng)度和執行速度兩方面)。按筆者的使用經(jīng)驗,僅從代碼長(cháng)度去比較,使用最高級別優(yōu)
化后代碼長(cháng)度至少可以減少 20%(2K 字以上的程序)。而且 PICC 的優(yōu)化器相當可靠,一般
%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/11.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/11.jpg" />
(A)常用選項
不會(huì )因為使用優(yōu)化從而使生成的程序出現錯誤。碰到的一些問(wèn)題也基本都是用戶(hù)編寫(xiě)的原程
序有漏洞所導致,例如一些變量應該是 volatile 型但編程員沒(méi)有明確定義,在優(yōu)化前程序可
以正常運行,一旦使用優(yōu)化,程序運行就出現異常。顯然,把出現的這些問(wèn)題歸罪到編譯器
是毫無(wú)道理的。
使用優(yōu)化后可能對原程序級的調試帶來(lái)一些不便之處。因 PICC 可能會(huì )重組編譯后的代
碼,例如多處重復的代碼可能會(huì )改成同一個(gè)子程序調用以節約程序空間,這樣在調試過(guò)程中
跟蹤原程序時(shí)可能會(huì )出現程序亂跳的現象,這基本是正常的。若為了強調更直觀(guān)的代碼調試
過(guò)程,你可以將優(yōu)化級別降低甚至關(guān)閉所有優(yōu)化功能,這樣調試時(shí)程序的運行就可以按部就
班了。
C 編譯器的高級選項設定基本都是針對診斷信息輸出的,和生成的代碼無(wú)關(guān)。用得相對
較多的選項有:
&O1540;
中列出了每一行
條
題的輔助手段。如果你懷疑編譯器生成的代碼有錯誤,不妨先產(chǎn)生對應的匯編列表
文件,看看在優(yōu)化前一條 C 語(yǔ)句被編譯后的匯編碼到底是什么。
&O1540;
(*.as),此時(shí)將不生成目標文件,也不進(jìn)行最后的連接定位。這一選項在 C 和匯
編混合編程時(shí)特別有用。通過(guò)解讀 C 程序對應的匯編指令,可以掌握 C 程序中存
取變量的具體方法,然后用在自己編寫(xiě)的匯編指令中。我們將在稍后專(zhuān)門(mén)做介紹。
11.8.5
連接器 PICC Linker 的選項基本不用作太多的改變,在圖 11-6 的對話(huà)框中顯示了可設定的各類(lèi)
項目。其中有兩項有用的信息輸出可以考慮加以利用:
&O1540;
序用到的變量的具體物理地址;所有函數的入口地址;函數相互之間調用的層次關(guān)系和深度等。這
些信息對于程序的調試將非常有用。此文件將以擴展名“*.map”的形式存放在同一個(gè)項目路徑
下,需要時(shí)可以用任何文本編輯器打開(kāi)觀(guā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/13.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/13.jpg" />
圖 11-6
&O1540;
了解到程序空間和數據存儲器空間資源分配的細節。下面列舉了在一個(gè)項目編譯后實(shí)際的內存使用
信息,為方便理解筆者用“//”添加了一些注釋?zhuān)?/p>
Psect Usage Map:
Psect
----------|------------------------------|--------------------
powerup
intentry
intcode
intret
init
end_init
clrtext
const3
const
const2
text
text
float_te
rbss_0
temp
nvram
intsave
intsave
intsave_1 | Saved copy of W in bank 1
rbit_0
config
Memory Usage Map:
//程序空間代碼定位地址分布
//存儲空間使用情況報告
Program
Program
//bank0 數據空間變量地址分布
Bank
Bank
//bank1 數據空間變量地址分布
Bank 1 RAM
//bank0 數據空間位變量地址分布
Bank 0 Bits
//配置字地址
Config Data
Program statistics:
//程序總體資源消耗統計
Total ROM used
Total RAM used
例 11-7
11.8.6
PICC 環(huán)境提供了自己的匯編編譯器,它和 Microchip 公司提供的 MPASM 編譯器在原
程序的語(yǔ)法表達方面要求稍有不同。另外,PICC 的匯編編譯器要求輸入原程序文件的擴展
名是“*.as”,而 MPASM 缺省認定的原程序以“*.asm”為擴展名。
在基于 PICC 編譯環(huán)境下開(kāi)發(fā) PIC 單片機的 C 語(yǔ)言應用程序時(shí)基本無(wú)需關(guān)心其匯編編譯
器,除非是在混合語(yǔ)言編程時(shí)用匯編語(yǔ)言編寫(xiě)完整的匯編原程序模塊文件。其編譯選項設定
的對話(huà)框見(jiàn)圖 11-7,最重要的是優(yōu)化使能控制項“Enable optimization”,一般情況下應該使
用匯編器的優(yōu)化以節約程序空間。
評論