構造体を EEPROM に読み書きする組み込みプロジェクトに取り組んでいます。sprintf を使用して、デバッグ情報を簡単に表示できるようにしています。
何らかの理由で、このコードには 2 つの問題があります。最初; 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 about 出力は、アドレス値の %x で取得されたことに注意してください (したがって、addr は 16 進数です)。
出力で気付いたかもしれない 2 番目の問題は、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 から離れ、OS、コンパイラ、IDE を変更しました。この問題を再現する可能性は低いです。