@登录C变量声明
我找到了PIC微控制器的这个头文件,名称为pic1250.h,我无法理解其中使用的一些语法。
该文件的来源是:
/* * 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。 有人可以帮帮我吗? 我只是个新手。
这是一个编译器扩展。
从PIC MPLAB XC8编译器文档(强调我的):
5.5.4绝对变量
大多数变量可以通过遵循构造@ address的声明来定位在绝对地址,其中address是存储器中要定位变量的位置。 这种变量称为绝对变量。
5.5.4.1数据存储器中的绝对变量
绝对变量主要用于将C标识符的地址与特殊function寄存器等同,但可用于将普通变量放在数据存储器的绝对地址中。
例如:
volatile unsigned char Portvar @ 0x06;
将声明一个名为Portvar的变量,位于数据存储器中的06h。 编译器将为此对象保留存储空间(如果地址属于通用RAM),并将变量的标识符等同于该地址。
请注意,MPLAB XC8不是唯一具有相同@
构造的编译器,用于将对象放置在特定的内存位置。
另一个众所周知的编译器是Freescale CodeWarrior(至少对于HCS08而言)。
另一个是IAR C编译器(至少对于MSP430和AVR)。
它是PIC编译器的扩展,用于将变量放在特定的内存位置。 我知道没有其他编译器具有该扩展名。
它是PIC编译器支持的C语言扩展,允许将变量分配给特定的RAM地址。
exemples:
char a @ 0x25; /* place A at address 0x25 */ bit b @ 0x25.3; /* place B at the third bit of address 0x25 */
这有三个用途:
- 在嵌入式系统中,您通常只有很少的内存,需要在同一个字节中打包几个变量。 尽管标准位字段也可以使用,但这种语法更容易实现。
- 另一个原因是PIC寄存器映射到RAM,因此您可以像任何其他内存位置一样访问它们。 使用此语法,您可以为您感兴趣的位定义同义词,并像普通变量一样使用它们。
- 在特定位置放置您自己的变量(无论大小)。 这偶尔会有用。
请记住,嵌入式编程完全是关于硬件的完全控制。
除了已经说过的内容之外,请注意非标准的@
运算符是一个多余的function。 您可以使用标准C实现完全相同的行为:
#define RTCC (*(volatile uint8_t*)0x0001u)
由于这种情况下的变量是硬件寄存器,因此您无需担心分配,它们已经存在于硬件中。 如果要在自定义地址处分配变量,则应该有某种链接器文件来修复它(因为@运算符只解决变量的特定分配,而不是代码)。
许多嵌入式编译器提出像@
这样的非标准运算符的主要原因是因为他们在设计调试器时无法思考。 他们期望在提供给调试器的目标文件中存在某种变量,但是如果使用#define,则不会分配这样的“调试信息对象”。
如果调试器改为查看源代码,或者更好的是内置了MCU感知,那么就不需要像这样的非标准代码。 来自专注于调试器的公司的高质量工具总是内置支持查看寄存器映射。