重要的#pragma聲明

#pragma聲明是基於單片機開發的特點而對標準C語法的一個擴充。它對充分利用單片機內各類有限的資源起到不可或缺的關鍵作用。下面簡單介紹幾個最常用的#pragma聲明。

1 #pragma DATA_SEG
定義變量所處的數據段。其語法型式爲:
#pragma DATA_SEG <屬性> 名稱
數據段名稱可以自己任意命名,但習慣上有些約定的名稱,其作用分別爲:
 DEFAULT - 缺省的數據段,在08 系列單片機中的地址爲0x100 以上。一般的變量定義可以放在這一區域。
 MY_ZEROPAGE - 特指第0頁數據段,地址範圍0x00-0xff,但實際用戶可用的空間不到256 字節,因爲前面的一些地址空間已經分配給了片內寄存器。需要頻繁或快速存取的變量應該指定放在這一特殊區域,特別是位變量。
數據段名稱必須和prm 文件中的數據段配置說明相關連才能真正發揮其定位作用。如果你自己命名的數據段在prm 文件中沒有特別說明,那此數據段的性質等同於“DEFAULT”。
數據段的“屬性”可以缺省,它主要的目的是告訴編譯器此段數據可適用的尋址模式。不同的尋址模式所花的指令數量和運行時間都不同。對於08 系列單片機,關鍵的是第0頁數據段可以用8位地址進行直接快速尋址,故對應此數據段應儘量指明其屬性爲“__SHORT_SEG”。對於一般數據段沒有屬性描述,其缺省是
“__FAR_SEG”,將用16位地址間接尋址。
舉幾個數據段定義的例子加以進一步說明。
#pragma DATA_SEG __SHORT_SEG MY_ZEROPAGE //開始0 頁數據定義
volatile struct {
unsigned powerOn : 1;
unsigned alarmOn : 1;
unsigned commActive : 1;
unsigned sysError : 1;
} myFlag;
volatile word msCounter;
byte i,j,k;
#pragma DATA_SEG DEFAULT //開始普通數據段定義(結束0 頁數據段)byte tmpBuff[16];

2 #pragma CONST_SEG
定義一個常數數據段,必須和變量的const修飾關鍵詞配合使用。其語法型式爲:
#pragma CONST_SEG 名稱
該數據段下定義的所有數據將被放置在程序只讀的ROM 區,也就是08 系列單片機內的Flash 程序空間區。常數段名稱可以用戶自由定義,但一般都用“DEFAULT”,讓連接器按可用的ROM區域自由分配變量位置。舉例如下:
#pragma CONST_SEG DEFAULT
const byte prjName[]=”This is a demo”;
FSL 系列單片機開發及C語言編程簡介
const word version = 0x0301;
#pragma CONST_SEG DEFAULT
word version = 0x0301; //沒有const 該變量將被放置在RAM 區!
#pragma DATA_SEG DEFAULT
const word version = 0x0301; //儘管有const 但該變量將被放置在RAM 區!
3.3.3 #pragma INTO_ROM
功能類似於“CONST_SEG”,和變量修飾詞“const”配合使用。但它只定義一個常數變量到ROM區,且只作用於緊接着的下一行定義。例如:
#pragma INTO_ROM
const byte prjName[]=”This is a demo”; //變量將被放置在ROM 區
word verData = 0x0301; //變量將被放置在缺省RAM 區

4 #pragma CODE_SEG
用以定義程序段並賦以特定的段名,語法型式如下:
#pragma CODE_SEG <屬性> 名稱
一般的程序設計是無需對代碼段做特殊處理的。因爲所有傳統的08 系列單片機其程序空間都不超過64KB(16 位尋址最大範圍)且在內存地址中呈線性連續分佈。對於項目中所有的代碼文件或庫文件,連接器會在最後按程序模塊出現的先後順序挨個自動安排所有程序函數在內存中所處的實際位置,用戶不必太關心某一個函數的具體位置。但最新推出的幾款8 位機程序將超過64KB,這樣必須在內存空間中以頁面型式映射到首64KB地址範圍,其對應的程序段屬性要特殊聲明。某些特殊的設計需要將不同部分的程序分別定位到不同的地址空間,例如實現程序代碼下載自動更新。這樣的設計需要把負責應用程序下載更新的驅動代碼固定放置在一個保留區域內,而把一般的應用程序放置在另外一個區域以便在需要時整體擦除後更新。這時就需要用“CODE_SEG”來分別指明不同的程序段,但還必須配合prm文件對程序空間進行分配和指派。
代碼段的屬性一般都用缺省的“__FAR_SEG”,表明所有的函數調用都是長調用(對應彙編指令爲JSR)。但C08 和S08 系列單片機支持效率更高的函數短調用(對應彙編指令爲BSR),如果你的某一個功能模塊含有多個相互調用的小函數且函數調用間距不超過+127 或-128 字節,則可以將這部分代碼段聲明爲短調用屬性“__NEAR_SEG”。但實際編程時由於C 代碼對應的彙編指令長度不是很容易就能估測得到,所以短調用屬性很少使用。
下面以幾個實例進一步說明:
//定義缺省的代碼段,缺省屬性爲遠調用
#pragma CODE_SEG DEFAULT
void main(void)
FSL 08系列單片機開發及C語言編程簡介
{
...
}
//定義名字爲FUNC_CODE 的代碼段,缺省屬性爲遠調用
#pragma CODE_SEG FUNC_CODE
void MyApp(void)
{
}
//定義遠調用的程序段,段名爲BOOTLOAD
#pragma CODE_SEG __FAR_SEG BOOTLOAD
void BootLoader(void)
{
}
//定義近調用的程序段,段名爲KEYBOARD
#pragma CODE_SEG __NEAR_SEG KEYBOARD
void KeyDebounce(void)
{
...
}
byte KeyCheck(void)
{
...
}
void KeyBoard(void)
{
if (keyCheck()) {
KeyDebounce();
...
}
}

5 #pragma TRAP_PROC
用於定義一個函數爲中斷服務類型。此類型的函數編譯器在將C 代碼編譯成彙編指令時會在代碼前後增加必要的現場保護和恢復彙編代碼,同時函數的最後返回用匯編指令“RTI”而不是針對普通函數的“RTS”。例如:
#pragma TRAP_PROC
void SCI1_Int(void) { //定義SCI1的中斷服務程序
...
}
注意用“TRAP_PROC”定義的中斷服務函數其實際中斷矢量地址必須通過prm 文件指派。

6 #pragma MESSAGE
這個聲明用以控制編譯信息的顯示。一般情況下這些編譯信息都是有用的,特別是告警和錯誤信息。但有時我們會按單片機的工作特性編寫一些代碼,但正常程序編寫時這些代碼會產生一些告警信息,例如
#pragma MESSAGE DISABLE C4002 //忽略“Result-not-used”告警
//==============================================================
// sci1 1 data receive interrupt service routine
// Assigned for full-duplex communication with Main board
//==============================================================
void interrupt 17 sci11_Receive_ISR(void)
FSL 08系列單片機開發及C語言編程簡介
{
SCI1S1; //讀一次狀態寄存器清除中斷標誌,會產生C4002 告警
sci1RxFifo[sci1FifoPut] = SCI1D;
sci1FifoPut++;
sci1FifoPut &= (SCI1_RXFIFO_SIZE-1);
}
如果你不想每次都看見編譯器給出的這一類信息,可以先確認這一信息的編號,然後用“#pragma MESSAGE”加上“DISABLE” 關鍵詞和信息號將它屏蔽。如果你想特別關注某類信息,可以用“ENABLE”讓其永遠顯示出來。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章