×
单片机 > 单片机程序设计 > 详情

MicroChip C18编译器上手及环境设置

发布时间:2024-05-19 发布时间:
|

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

/zixunimg/eeworldimg/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

详细内容要参见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;


『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
ARM 汇编的必知必会