我正在从事一个嵌入式项目,该项目涉及将结构读/写到 EEPROM 中。我正在使用 sprintf 来轻松显示一些调试信息。
由于某种原因,此代码存在两个问题。首先; sprintf 正在打印一个非常奇怪的输出。当我打印 'addr++' 时,它将遵循一个没有意义的模式 '0, 1, 2, 3, 4, 32, ...'。
void ee_read(char * buf, unsigned int addr, unsigned int len) {
unsigned int i;
sprintf(bf1, "Starting EEPROM read of %u bytes.\r\n", len); // Debug output
debugr(bf1);
IdleI2C1();
StartI2C1();
WriteI2C1(EE_ADDR | EE_W);
IdleI2C1();
WriteI2C1((unsigned char)addr>>8); // Address to start reading data from
IdleI2C1();
WriteI2C1((unsigned char)addr&0xFF);
IdleI2C1();
RestartI2C1();
WriteI2C1(EE_ADDR | EE_R);
IdleI2C1();
for (i=0; i<len; i++) {
buf[i] = ReadI2C1(); // Read a byte from EEPROM
sprintf(bf1, "Addr: %u Byte: %c\r\n", addr, buf[i]); // Display the read byte and the address
debugr(bf1);
addr++; // Increment address
IdleI2C1();
if (i == len-1) { // This makes sure the last byte gets 'nAcked'
NotAckI2C1();
} else {
AckI2C1();
}
}
StopI2C1();
}
上面的输出在这里:https ://gist.github.com/3803316 请注意,关于输出是用 %x 作为地址值(所以 addr 是十六进制)
您可能已经注意到输出的第二个问题是当 i > len 时它不会停止。它继续比我提供的输出更远,并且在微控制器的看门狗重新启动之前不会停止。
编辑: 调用函数
Location loc;
ee_read(&loc, 0, sizeof(Location));
声明:
struct location_struct {
char lat[12]; // ddmm.mmmmmm
char latd[2]; // n/s
char lon[13]; // dddmm.mmmmmm
char lond[2]; // e/w
char utc[11]; // hhmmss.sss
char fix[2]; // a/v
};
typedef struct location_struct Location;
char bf1[BUFFER_SIZE];
我不认为这是一个竞争条件。我禁用了使用 bf1 的中断。即使那样,如果发生这种情况,它也会破坏整个调试字符串,而且肯定不会如此可重复。
编辑 addr 的值从零开始,可以在这里看到:https ://gist.github.com/3803411
编辑 这应该做什么它将位置结构逐字节复制到 EEPROM 中,然后在需要时调用它。
关闭 所以我从来没有解决过这个问题。该项目从 EEPROM 移出,此后我更改了操作系统、编译器和 IDE。我不太可能复制这个问题。