26

我通过 pic1250.h 的名称找到了 PIC 微控制器的头文件,但我无法掌握其中使用的某些语法。

该文件的来源是:

/*
 *  Header file for the Microchip 
 *  PIC 12c508 chip 
 *  PIC 12c509 chip
 *  Baseline Microcontrollers
 */

static volatile unsigned char   RTCC    @ 0x01;
static volatile unsigned char   TMR0    @ 0x01;
static volatile unsigned char   PCL @ 0x02;
static volatile unsigned char   STATUS  @ 0x03;
static          unsigned char   FSR @ 0x04;
static volatile unsigned char   OSCCAL  @ 0x05;
static volatile unsigned char   GPIO    @ 0x06;

static          unsigned char control   OPTION  @ 0x00;
static volatile unsigned char control   TRIS    @ 0x06;

/*  STATUS bits */
static bit  GPWUF   @ (unsigned)&STATUS*8+7;
static bit  PA0 @ (unsigned)&STATUS*8+5;
static bit  TO  @ (unsigned)&STATUS*8+4;
static bit  PD  @ (unsigned)&STATUS*8+3;
static bit  ZERO    @ (unsigned)&STATUS*8+2;
static bit  DC  @ (unsigned)&STATUS*8+1;
static bit  CARRY   @ (unsigned)&STATUS*8+0;

/*  OPTION bits */
#define     GPWU    (1<<7)
#define     GPPU    (1<<6)
#define     T0CS    (1<<5)
#define     T0SE    (1<<4)
#define     PSA (1<<3)
#define     PS2 (1<<2)
#define     PS1 (1<<1)
#define     PS0 (1<<0)

/*  OSCCAL bits */
static bit  CAL7    @ (unsigned)&OSCCAL*8+7;
static bit  CAL6    @ (unsigned)&OSCCAL*8+6;
static bit  CAL5    @ (unsigned)&OSCCAL*8+5;
static bit  CAL4    @ (unsigned)&OSCCAL*8+4;

/*  GPIO bits   */
static bit  GP5 @ (unsigned)&GPIO*8+5;
static bit  GP4 @ (unsigned)&GPIO*8+4;
static bit  GP3 @ (unsigned)&GPIO*8+3;
static bit  GP2 @ (unsigned)&GPIO*8+2;
static bit  GP1 @ (unsigned)&GPIO*8+1;
static bit  GP0 @ (unsigned)&GPIO*8+0;

#define CONFIG_ADDR 0xFFF
#define FOSC0       0x01
#define FOSC1       0x02
#define WDTE        0x04
#define CP      0x08
#define MCLRE       0x0F

我无法理解整个 modifer-datatype @ declaration-something。有人可以帮我吗?我只是这方面的新手。

4

4 回答 4

38

这是一个编译器扩展。

来自 PIC MPLAB XC8编译器文档(重点是我的):

5.5.4 绝对变量

大多数变量可以通过在其声明之后使用构造 @address来定位在绝对地址,其中 address 是要定位变量的内存位置。这样的变量称为绝对变量。

5.5.4.1 数据存储器中的绝对变量

绝对变量主要用于将 C 标识符的地址与特殊功能寄存器相等,但可用于将普通变量放置在数据存储器中的绝对地址处。

例如:

volatile unsigned char Portvar @ 0x06;

将在数据存储器的 06h 处声明一个名为 Portvar 的变量。编译器将为此对象保留存储空间(如果地址落入通用 RAM)并将变量的标识符等同于该地址。

请注意,MPLAB XC8 并不是唯一具有相同@结构来将对象放置在特定内存位置的编译器。

另一个著名的编译器是 Freescale CodeWarrior(至少对于 HCS08)。

另一个是 IAR C 编译器(至少对于 MSP430 和 AVR)。

于 2013-04-11T18:22:24.997 回答
22

它是 PIC 编译器中的扩展,用于将变量放置在特定的内存位置。我知道没有其他编译器具有该扩展名。

于 2013-04-11T18:13:59.603 回答
6

除了已经说过的,请注意非标准@运算符是一个多余的功能。您可以使用标准 C 实现完全相同的行为:

#define RTCC (*(volatile uint8_t*)0x0001u)

由于本例中的变量是硬件寄存器,因此您无需担心分配问题,它们已经存在于硬件中。如果您想在自定义地址分配变量,则应该有某种类型的链接器文件来解决该问题(因为 @ 运算符仅解决变量的特定分配,而不是代码)。

很多嵌入式编译器想出一些非标准的操作符之类@的主要原因是因为他们在设计调试器时不能跳出框框思考。他们希望在提供给调试器的目标文件中存在某种变量,但是如果您使用#define,则不会分配这样的“调试信息对象”。

如果调试器改为查看源代码,或者更好的是,内置了 MCU 感知,那么就不需要像这样的非标准代码。仅专注于调试器的公司提供的高质量工具总是带有用于查看寄存器映射的内置支持。

于 2013-04-12T06:57:46.630 回答
1

一个简短的扩展:

自 xc8 2.0 及更高版本以来,这不再有效。你现在必须写:

unsigned char a __at(0x025);

将变量 ( a) 放在绝对地址 ( 0x025) 上。

对于 XC8 2.0,如果您将编译器设置设置为使用“C90”格式,则可以使用 @ 语法编译旧代码。设置看起来像这样,它在“XC8 Global Options”下,被称为“C标准”。

于 2019-06-26T06:10:10.843 回答