У меня есть Arduino’s I²C шина, подключенная к шине I²C микрочипа PICDEM 2 плата для программирования своей 32K байтовой EEPROM. Код ниже имеет проблемы с чтением. В частности, я написал всю EEPROM с 16-разрядным счетным шаблоном и проверил, что все данные верны.
Следующий код управляется Java-программой на ПК. Я читаю и пишу 16-байтовые страницы. Я проверил адреса, поступающие с ПК, и все они верны. Все возвращаемые данные верны, за исключением 256-байтового блока адреса в 0x0AXX
, Прочитанные данные выглядят как строка из 0x9F0
, Я не смог выяснить, почему возникает ошибка.
#include "Wire.h"
const int bufsize = 68;
char ibuf[bufsize];
int bytecnt;
int result;
void setup() {
Wire.begin();
Serial.begin(9600);
}
void i2c_init() {
Wire.begin();
}
void i2c_write( int addr, int count ){
Wire.beginTransmission( addr );
for(int i=0;i<count;i++) {
Wire.write(ibuf[3+i]);
}
result = Wire.endTransmission();
delay(20);
Serial.write(result);
}
void i2c_read( int addr, int count ){
result = Wire.requestFrom( addr, count );
Serial.write( result );
}
void i2c_xfer( int count ){
for(int i=0; i<count; i++ ){
Serial.write( Wire.read() );
}
}void loop() {
// Accept a line of input
bytecnt = Serial.readBytesUntil('\n', ibuf, bufsize);
if ( bytecnt > 0 ) {
switch( ibuf[0] ) {
case 0: i2c_init(); break;
case 1: i2c_write(ibuf[1],ibuf[2]); break;
case 2: i2c_read(ibuf[1],ibuf[2]); break;
case 3: i2c_xfer(ibuf[1]); break;
default: break;
}
}
}
Все данные, полученные на ПК, верны, за исключением следующего блока:
09c0 e0 04 e1 04 e2 04 e3 04 e4 04 e5 04 e6 04 e7 04
09d0 e8 04 e9 04 ea 04 eb 04 ec 04 ed 04 ee 04 ef 04
09e0 f0 04 f1 04 f2 04 f3 04 f4 04 f5 04 f6 04 f7 04
09f0 f8 04 f9 04 fa 04 fb 04 fc 04 fd 04 fe 04 ff 04
0a00 f8 04 f9 04 fa 04 fb 04 fc 04 fd 04 fe 04 ff 04
0a10 f8 04 f9 04 fa 04 fb 04 fc 04 fd 04 fe 04 ff 04
0a20 f8 04 f9 04 fa 04 fb 04 fc 04 fd 04 fe 04 ff 04
0a30 f8 04 f9 04 fa 04 fb 04 fc 04 fd 04 fe 04 ff 04
0a40 f8 04 f9 04 fa 04 fb 04 fc 04 fd 04 fe 04 ff 04
0a50 f8 04 f9 04 fa 04 fb 04 fc 04 fd 04 fe 04 ff 04
0a60 f8 04 f9 04 fa 04 fb 04 fc 04 fd 04 fe 04 ff 04
0a70 f8 04 f9 04 fa 04 fb 04 fc 04 fd 04 fe 04 ff 04
0a80 f8 04 f9 04 fa 04 fb 04 fc 04 fd 04 fe 04 ff 04
0a90 f8 04 f9 04 fa 04 fb 04 fc 04 fd 04 fe 04 ff 04
0aa0 f8 04 f9 04 fa 04 fb 04 fc 04 fd 04 fe 04 ff 04
0ab0 f8 04 f9 04 fa 04 fb 04 fc 04 fd 04 fe 04 ff 04
0ac0 f8 04 f9 04 fa 04 fb 04 fc 04 fd 04 fe 04 ff 04
0ad0 f8 04 f9 04 fa 04 fb 04 fc 04 fd 04 fe 04 ff 04
0ae0 f8 04 f9 04 fa 04 fb 04 fc 04 fd 04 fe 04 ff 04
0af0 f8 04 f9 04 fa 04 fb 04 fc 04 fd 04 fe 04 ff 04
0b00 80 05 81 05 82 05 83 05 84 05 85 05 86 05 87 05
0b10 88 05 89 05 8a 05 8b 05 8c 05 8d 05 8e 05 8f 05
0b20 90 05 91 05 92 05 93 05 94 05 95 05 96 05 97 05
Все до и после этого блока в порядке, но 0x0A00 — 0x0AFF повторяют данные из строки 0x09F0. Следующий код был использован для записи и проверки всей схемы подсчета:
#include "Wire.h"
int EEPROM = 0x50;
int pageSize = 0x10;
unsigned int length = 0x8000;
unsigned int addr = 0;
unsigned int data = 0;
unsigned int datah = 0;
unsigned int datal = 0;
int result;
unsigned int i;
unsigned int r;
long j;
int k;
int errors;
void setup() {
Wire.begin();
Serial.begin(9600);
}
void eeprom_check() {
for(i=0; i<length; i+=pageSize) {
// Write to set address pointer
Wire.beginTransmission( EEPROM );
Wire.write( (i>>8) & 0xFF );
Wire.write( i & 0xFF );
Wire.endTransmission();
if(( i & 0xfF ) == 0 ) {
Serial.write('\n');
Serial.print( i,HEX);
Serial.write(": ");
}
errors = 0;
result = Wire.requestFrom( EEPROM, pageSize );
for(j=0; j<8; j++) {
datal = Wire.read();
datah = Wire.read();
data = (i>>1)+j;
if( datal != (data & 0xFF) )
errors += 1;
if( datah != ( (data>>8) & 0xFF) )
errors += 1;
}
if( errors > 0 )
Serial.write('X');
else
Serial.write('_');
}
}
void eeprom_dump() {
for(i=0; i<length; i+=pageSize) {
// Write to set address pointer
Wire.beginTransmission( EEPROM );
Wire.write( (i>>8) & 0xFF );
Wire.write( i & 0xFF );
Wire.endTransmission();
if(( i & 0xF ) == 0 ) {
Serial.write('\n');
Serial.print( i,HEX);
Serial.write(": ");
}
result = Wire.requestFrom( EEPROM, pageSize );
for(j=0; j<result; j++) {
data = Wire.read();
if( data < 16 ){
Serial.print('0');
Serial.print(data,HEX);
}
else {
Serial.print(data,HEX);
}
Serial.print(' ');
}
}
}
void eeprom_write() {
for(i=0; i<length; i+=pageSize) {
for(k=0; k<10; k++){
Wire.beginTransmission( EEPROM );
Wire.write( (i>>8) & 0xFF );
Wire.write( i & 0xFF );
for(j=0; j<8; j++ ){
data = (i>>1)+j;
Wire.write( data & 0xFF );
Wire.write( (data>>8) & 0xff );
}
result = Wire.endTransmission();
delay(10);
if( result==0 )
break;
else
Serial.write(result);
}
k = i / pageSize;
if(( k & 0xF ) == 0 ) {
Serial.write('\n');
Serial.print( i,HEX);
Serial.write(": ");
}
Serial.write('W');
}
}
void eeprom_break() {
i = 0xa00;
Wire.beginTransmission( EEPROM );
Wire.write( (i>>8) & 0xFF );
Wire.write( i & 0xFF );
Wire.write( 0x55 );
Wire.write( 0xAA );
Wire.endTransmission();
Serial.write("Break Compelted\n");
}
void loop() {
char ch;
Serial.write("Interactive EEPROM Test Tool\n");
while( true ) {
Serial.write('>');
while( Serial.available() == 0 );
ch = Serial.read();
Serial.write( ch );
Serial.write('\n');
while( Serial.available() != 0)
Serial.read();
switch( ch ) {
case 'c': eeprom_check(); break;
case 'd': eeprom_dump(); break;
case 'w': eeprom_write(); break;
case 'z': eeprom_break(); break;
default: break;
}
}
}
Я боролся с этим в течение нескольких дней. Любое понимание будет с благодарностью.
Проблема решена (через много-много времени)!
Java-программа отправляет команды в Arduino в виде строки, которая начинается с команды в виде одной цифры, за которой следует серия байтов и CR. Это оно!
Когда адрес 0x0A ?? 0A — это CR, и он усекает мою команду! Я чувствую себя глупо
Других решений пока нет …