Liste der Anhänge anzeigen (Anzahl: 1)
I²C Master m328 kann Slave m328 nicht lesen
Peinlich. Meine Fehlersuche und Sachstudie zum Thema hilft mir seit Tagen (Nächten) nicht weiter. Bisherige Erfahrungen mit I²C auf Atmelcontrollern: schreiben und lesen eines Beschleunigungsaufnehmers, Code von Sternthaler mit leichten Abwandlungen.
Aktuell:
Kurzfassung: Daten von einem Master (mega328/8MHz int. Osz) können auf einen Slave (mega328/20MHz Quarz) übertragen werden. Lesen der Daten vom Master geht nicht - Programm hängt.
AV RStudio4 4.18 Build 700, Master-Slave-Kopplung nach RN/Wissen (siehe hier - klick) mit den dort präsentierten Codes bzw. PFleury-Lib.
Master :
- Der Code für Master wurde geringfügig abgewandelt: Sende-/Leseschleife durch while(1) mit eingebauter Tastenabfage. Wenn Taste gedrückt werden drei andere Bytes definiert wie ohne Tastendruck.
- Die Slaveadresse ist hex70.
- Eigene, bewährte UART-Routine
Slave :
- Der Code wurde bis auf die Slaveadresse übernommen.
Ergebnis:
- Schreiben der beiden Datensätze mit/ohne Taste geht einwandfrei, siehe Ausgabebeispiel - RS232 vom Slave
- Die Schleifendurchläufe des Masters werden durch eine getoggelte LED signalisiert.
- Lesen des Masters der geschriebenen Daten geht nicht, das Programm bleibt nach der Abfrage "Slave bereit zum Lesen" hängen - belegt durch LEDsignal am Master (toggelt nicht), siehe dazu Codeabschnitt.
HTML-Code:
i2c_init(); // init I2C interface
while (1)
{ // Schleife mit verschiedenen Ausgaben
if (!(PIND & (1 << PIND2))) // Taste bringt GND auf PD2?
{ //
byte1 = 42;
byte2 = 43;
byte3 = 44;
}
else //
{ //
byte1 = 56;
byte2 = 57;
byte3 = 58;
} // Ende if (!(PIND & (1 << PIND2)))
//
if(!(i2c_start(SLAVE_ADRESSE+I2C_WRITE))) //Slave bereit zum schreiben?
{
i2c_write(0x00); // Buffer Startadresse setzen
i2c_write(byte1); // Drei Bytes schreiben...
i2c_write(byte2);
i2c_write(byte3);
i2c_stop(); // Zugriff beenden
} //
else
{
/* Hier könnte eine Fehlermeldung ausgegeben werden... */
}
/*
waitms ( 200); // Warten vor Lesen ?? 30Nov2011, 2300
if(!(i2c_start(SLAVE_ADRESSE+I2C_WRITE))) //Slave bereit zum lesen?
{ //
//
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
ToggleBit(PORTD, 5); // LED auf PC2 toggeln
// ###>>> 02 Dez 2011, 0045: Programm kommt bis hieher, dann bleibt es stehen
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
//
i2c_write(0x00); //Buffer Startadresse zum Auslesen
i2c_rep_start(SLAVE_ADRESSE+I2C_READ); //Lesen beginnen
//
byte1= i2c_readAck(); // Bytes lesen...
byte2= i2c_readAck();
byte3= i2c_readNak(); // letztes Byte lesen, darum kein ACK
i2c_stop(); // Zugriff beenden
}
*/
//else
//{
///* Hier könnte eine Fehlermeldung ausgegeben werden... */
//}
Ausgabebeispiel:
Anhang 20704
Frage:
Wo steckt der Fehler??
Danke im Voraus für eure Hilfe.
Liste der Anhänge anzeigen (Anzahl: 1)
Um die Erledigung der Frage korrekt zu begründen, hier den aktuellen Stand.
Es werden vom Master (mega328/8MHz-intOsz) drei Bytes an den Slave (mega328bzw.168/20MHz-Quarz) gesendet. Je nachdem ob eine Taste gedrückt oder nicht gedrückt ist, werden zwei unterschiedliche Datensätze gesendet. Slaveadresse Schreiben x70, Slaveadresse Lesen x70+1. Schreibziel ist Position 2 bis 4 des Zielspeichers {von 1 bis 10 möglichen Plätzen}. Nach dem Senden des Datensatzes werden die drei Bytes zurückgelesen. Senden, Zurücklesen und evtl. Fehlermeldung werden im Terminal ausgegeben, siehe Beispiel der Ausgabe des Masters. Es ist eine Terminalverbindung des Masters (9600 Bd da ohne Quarz), des Slaves (128kBd) und des Sniffers (57600 Bd) eingesetzt.
......Anhang 20804
Um die Unterhaltung der beiden Controller mitzuschneiden wurde ein Sniffer (klick) gebaut (Dank an PDannegger). Tiny2313 mit 16MHz-Quarz. Beispiel für einen Mitschnitt:
I2C-Sniff 2313:
...
s70a01a36a37a38ap<\r
...
s70a01a36a37a38ap<\r>
Der Sniffer ist noch verbesserungswürdig, die Ausgaben sind gelegentlich gestört. Der obige Mitschnitt zeigt zweimal :
Sende an Adresse x70 / Speicherplatz 01 {von 10} / Datum x36 senden mit ACK / Datum x37 senden mit ACK / Datum x38 senden mit NAK / Stop