我在PIC24f16ka102和xc16编译器中遇到了一个简单而快速的C问题。
我想给我的函数传递一个变量引用。变量位于eeprom空间:
int __attribute__ ((space(eedata))) eeData; // Variable located in EEPROM,declared as a global variable.
通过这个序列,我可以将一些数据保存在eeprom存储器中:
unsigned int offset;
// Set up NVMCON to erase one word of data EEPROM
NVMCON = 0x4004;
// Set up a pointer to the EEPROM location to be erased
TBLPAG = __builtin_tblpage(&eeData2); // Initialize EE Data page pointer
testDebug = TBLPAG;
offset = __builtin_tbloffset(&eeData); // Initizlize lower word of address
__builtin_tblwtl(offset, 0x9876); // Write EEPROM data to write latch
asm volatile ("disi #5"); // Disable Interrupts For 5 Instructions
__builtin_write_NVM(); // Issue Unlock Sequence & Start Write Cycle
while(NVMCONbits.WR == 1);
这样,我将值0x9876写入eeprom的前16位。
但我需要它
&eeData
我想写我自己的函数:
void eeprom_writeWord(unsigned int __attribute__ ((space(eedata))) addresOfMyEEpromVariable, unsigned int value)
{
unsigned int offset;
// Set up NVMCON to erase one word of data EEPROM
NVMCON = 0x4004;
// Set up a pointer to the EEPROM location to be erased
TBLPAG = __builtin_tblpage(&addresOfMyEEpromVariable); // Initialize EE Data page pointer
offset = __builtin_tbloffset(&addresOfMyEEpromVariable); // Initizlize lower word of address
__builtin_tblwtl(offset, value); // Write EEPROM data to write latch
asm volatile ("disi #5"); // Disable Interrupts For 5 Instructions
__builtin_write_NVM(); // Issue Unlock Sequence & Start Write Cycle
while(NVMCONbits.WR == 1);
}
但是如何将我的地址作为函数参数传递,以便我的函数可以看到它仍然是eeprom空间中的地址?它不能仅仅是地址,因为如果是这样的话我会出错。__内置函数需要一些属性为eeprom存储器的地址。
如何将带有属性的eeprom地址传递给我的函数?
请帮忙
编辑:
谢谢你的建议,但我还是犯了同样的错误:
error: Argument to __builtin_tbloffset() is not the address
of an object in a code, psv, or eedata section;
函数builtin tbloffset需要eeprom存储器的地址,而不仅仅是某个东西的地址。如果我使用整个序列,而不是在函数中(我的意思是在我的第一篇文章中的序列),它会很好地工作。
现在我试着像你说的那样:
void eeprom_writeWord(unsigned int *addresOfMyEEpromVariable, unsigned int value)
{
//write word
// Set up NVMCON to write one word of data EEPROM
NVMCON = 0x4004;
// Set up a pointer to the EEPROM location to be written
TBLPAG = __builtin_tblpage(*addresOfMyEEpromVariable);
unsigned int offset = __builtin_tbloffset(*addresOfMyEEpromVariable);
// Write Data Value To Holding Latch
__builtin_tblwtl(offset, 0x9999);
// Disable Interrupts For 5 Instructions
asm volatile ("disi #5");
// Issue Unlock Sequence & Start Write Cycle
__builtin_write_NVM();
while(NVMCONbits.WR == 1);
}
甚至没有“*”标志:
void eeprom_writeWord(unsigned int *addresOfMyEEpromVariable, unsigned int value)
{
//write word
// Set up NVMCON to write one word of data EEPROM
NVMCON = 0x4004;
// Set up a pointer to the EEPROM location to be written
TBLPAG = __builtin_tblpage(addresOfMyEEpromVariable);
unsigned int offset = __builtin_tbloffset(addresOfMyEEpromVariable);
// Write Data Value To Holding Latch
__builtin_tblwtl(offset, 0x9999);
// Disable Interrupts For 5 Instructions
asm volatile ("disi #5");
// Issue Unlock Sequence & Start Write Cycle
__builtin_write_NVM();
while(NVMCONbits.WR == 1);
}
结果还是一样的。__内置函数tblpage和其他内置函数…)是内置在xc16编译器中的函数。
最佳答案
可能是内置例程可以处理硬编码地址(如第一个示例中所示——编译器/链接器知道eeData的位置),但不能处理变量地址。
你可以尝试两件事:
(1)使eeprom写为内联函数(这样编译器就可以再次硬编码地址)。请注意,如果这样做有效,在“复杂”情况下(如存储在索引数组中的地址)仍然可能失败。
(2)查看为工作示例中的内置例程生成的汇编程序代码,并根据需要重写它们(使用C或内联汇编程序)。这些程序只有几条指令那么长。例如,builtin-tblpage只是剥离了地址的上半部分——在C语言中,通过掩蔽和/或右移很容易实现。
关于c - eeprom空间中的变量地址作为C中的函数参数,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/31698696/