0

Arduino のI²Cバスを Microchip PICDEM 2ボードの I²C バスに接続して、32K バイトの EEPROM をプログラムしています。以下のコードには読み取りの問題があります。具体的には、EEPROM 全体に 16 ビットのカウント パターンを書き込み、すべてのデータが正しいことを確認しました。

次のコードは、PC 上の Java プログラムによって駆動されます。16 バイトのページを読み書きしています。PC からのアドレスを監視しましたが、すべて正しいです。戻ってくるデータは、 のアドレスの 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;
        }
    }
}

PC が受信したデータは、次のブロックを除いてすべて正しいです。

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;
        }
    }
}

私は何日もこれに苦労してきました。どんな洞察も大歓迎です。

4

1 に答える 1

0

問題が解決しました(かなりの時間がかかりました)!

Java プログラムは、1 桁のコマンドで始まり、その後に一連のバイトと CR が続く行の形式で Arduino にコマンドを送信します。それでおしまい!アドレスが0x0Aの場合?? 0A は CR であり、コマンドが切り捨てられます! 私はばかだと感じます。

于 2012-10-25T20:39:09.620 に答える