sprintf выводит некоторые странные данные
Я работаю над встроенным проектом, который включает чтение / запись структуры в 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 Обратите внимание, что вывод about был взят с%x в качестве значения адреса (поэтому addr является шестнадцатеричным)
Вторая проблема, которую вы, возможно, заметили с выводом, заключается в том, что он не останавливается, когда я> 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. Вряд ли я повторю эту проблему.
1 ответ
Я скажу вам одну вещь неправильно с вашим кодом, эту строку:
(unsigned char)addr>>8
не делает то, что вам нужно.
Преобразует значение в addr
в unsigned char
который (при условии 8-битной char
и либо 16-битный int
или только используя младшие 16 битов шире int
), всегда будет давать вам младшие восемь бит.
Если вы затем сдвинете вправо на восемь битов, вы всегда получите ноль.
Если вы хотите получить верхние восемь бит адреса, вам нужно использовать:
(unsigned char)(addr>>8)
так что сдвиг делается первым.