MicroChip C18編譯器上手及環境設置

C18是MCHP老早針對PIC18高端片子自己出的編譯器環境,可能是用戶覆蓋面的原因,個人感覺比PIC16上的Hi-tech PICC要難用很多。

針對不同的單片機要安裝不同升級包,因爲官方的頭文件支持一直在更新;使用較新的單片機時,建議安裝最新的C18 upgrade installation升級包。


下面說說不同之處和比較難配置的關鍵的幾個點:

-------------------------------------------------------------------------------------

#pragma指令:

這個C/C++語言常見的預處理指令,是用來定位代碼區域的,定位到RAM區和ROM區,以及類似Config關鍵配置字的作用。這個跟Freescale的HCS08/12系列單片機的Codewarrior環境風格有點像。這玩意兒是編譯器相關的,也就是說有的編譯環境支持,有的壓根不支持,所以得仔細去讀C18文檔。。。頭大。我就做個簡單學習加翻譯了!

# pragma udata [ 屬性列表] [section-name [=address]]
# pragma idata [ 屬性列表] [section-name [=address]]
# pragma romdata [overlay] [section-name [=address]]
# pragma code [overlay] [section-name [=address]]


但是每個PIC18器件的設定值並不相同,不能閉着眼睛猜,官方的C18用戶手冊是這麼說的:

2.9.5.1
語法
pragma-config僞指令:
     # pragma config setting-listsetting-list:     setting
   | setting-list, settingsetting:
     setting-name = value-name
setting-name和value-name是特定於器件的,可通過使用 --help-config命令行選項來確定。另外,PIC18 Configuration Settings Addendum(DS51537)中給出了每個器件的有效設置和相關值。


然後在MCHP官網上,已經停止更新這個文檔了:

PIC18 CONFIGURATION SETTINGS ADDENDUM  
Page 4. PIC18 Configuration Settings Addendum DS51537E-page iv 296 Page
6. PIC18 Configuration Settings Addendum DS51537E-page vi 
http://ww1.microchip.com/downloads/en/DeviceDoc/C18_Config_Settings_51537e.pdf

The PIC18 Configuration Settings Addendum is no longer published as a .PDF file.  It is included with MPLAB IDE and MPLAB C18 C Compiler as on-line help. 

網上可以找到的是陳舊的2006年版本的,已經不需要看了,直接在打開MPLAB IDE--Help---Topic,裏面找PIC18 Config Setting   裏面很方便!!

---------------------------------------------------------------------

The ANSI C standard provides each C implementation a method for defining unique
constructs, as required by the architecture of the target processor. This is done using
the #pragma directive. The most common #pragma directive in the MPLAB C18
compiler identifies the section of memory to be used in the PIC18XXXX. For instance,
#pragma code
tells MPLAB 18 to compile the C language code following this directive into the “code”
section of program memory. The code section is defined in the associated linker script
for each PIC18XXXX device, specifying the program memory areas where instructions
can be executed. This directive can be inserted as shown, or it can also be followed by
an address in the code areas of the target processor, allowing full control over the
location of code in memory. Usually, it doesn’t matter, but in some applications, such
as bootloader, it is very important to have strict control over where certain blocks of
code will be executed in the application.

MPLAB® C18 #pragma DIRECTIVES
指令 用途
code 程序空間指令:將其後所有指令編譯到目標PIC18單片機的程序空間。
romdata 存儲在程序空間的數據:將其後所有靜態數據存入目標PIC18單片機的程序空間。
udata 未初始化的數據:將後續需要的未初始化的靜態變量,分配給數據data存儲器空間。
idata 初始化過的數據:將後續需要的靜態變量,分配給數據data存儲器空間,且這些變量是在源代碼中設過初始值的。
config 定義PIC18單片機的配置字,這些將會在鏈接輸出的hex文件中生成幷包含在固件內寫入單片機。
interrupt 將已定義命名的C函數編譯爲高優先級的中斷服務ISR程序;
interruptlow 將已定義命名的C函數編譯爲較低優先級的中斷服務ISR程序;
varlocate 定義變量將要存儲的位置,以便於編譯器避免設定bank地址翻頁。
















詳細內容要參見C18 User's Guide用戶參考手冊!


2.9.1.5 定位代碼
在 #pragma code 僞指令後生成的所有代碼將被分配到指定的代碼段,直到遇到下一個 #pragma code 僞指令。絕對代碼段允許將代碼分配到一個特定的地址。例如: #pragma code my_code=0x2000  
將把代碼段 my_code 分配到程序存儲器地址0x2000。鏈接器會強制將代碼段放入程序存儲區;然而,代碼段也可以位於指定的存儲區。可以用鏈接器描述文件中的SECTION 僞指令把一個段分配到特定的存儲區。下面鏈接器描述文件中的僞指令把代碼段my_code1 分配到存儲區page1:
SECTION NAME=my_code1 ROM=page1

2.9.1.6 定位數據
對於MPLAB C18 編譯器,數據可以放入數據存儲器或者程序存儲器。如果沒有用戶提供的附加代碼,片內程序存儲器中的數據只能讀不能寫。如果沒有用戶提供的附加代碼,片外程序存儲器中的數據一般是隻能讀或者只能寫。
例如,下面的語句爲靜態分配的未初始化數據(udata)聲明瞭一個位於絕對地址0x120 的段:
#pragma udata my_new_data_section=0x120
rom 關鍵字告知編譯器應該將變量放入程序存儲器。編譯器會把這個變量分配到當前
的romdata 型段。例如:
#pragma romdata const_table
const rom char my_const_array[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
/* Resume allocation of romdata into the default section */
#pragma romdata
鏈接器強制將romdata 段放入程序存儲區,將udata 和 idata 段放入數據存儲區;
然而,數據段也可以位於指定的存儲區。可以使用鏈接器描述文件中的SECTION 僞
指令把一個段分配到一個特定的存儲區。下面的語句將把udata 段my_data 分配到
存儲區gpr1:
SECTION NAME=my_data RAM=gpr1


-----------------------------------------------------------------------

我摸索了一陣子,還發現C18的另外幾個特點:

1. 新來的rom指令(注意必須小寫,否則C18編譯器不認識),作用類似於#pragma romdata xxxxx

//The direction that the mouse will move in
rom signed char dir_table[]={-4,-4,-4, 0, 4, 4, 4, 0};

2. PORTBbits.RB3和LATBbits.LATB0的區別,
	RB1=0;
	RB2=1;
上面這種端口引腳定義在C18裏是沒法直接用的,所有bits位必須帶寄存器名的前綴,比如PORTBbits.RB1;這跟PICC編譯器的風格有很大不同,所以我剛開始感覺很不習慣。當然這樣統一標準其實也有好處,就是增加程序代碼的可讀性和可辨識性,一眼就能看出bits操作。

操作PortX作爲digital IO輸出端口時,儘量用latch寄存器來操作,避免用PORTBbits.RB3,因爲後者只是用來讀取端口狀態的;
#define LED0				LATBbits.LATB0
#define LED1				LATBbits.LATB1
#define LED2 				LATBbits.LATB2
LED0=!LED0;


發佈了40 篇原創文章 · 獲贊 22 · 訪問量 16萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章