Gast
#451656
Guten morgen. Ich will einen Aduc70xx mit ARM Core als I2C Master verwenden, um ein Poti, DS 1803, anzusteuern. Ich habe die I2C Spzeifikation von Phillips gelesen und im Handbuch zum Aduc das I2C Kapitel mehrmals gelesen. Ich habe mir auch den Beispielcode angesehen. Mein Problem ist, dass ich die I2C Spezifikation im Handbuch nicht wiedererkenne. Wenn ein Master auf einen Slave schreiben will, läuft folgendes auf dem Bus ab: 1. Master sendet START 2. Master sendet 7bit SlaveAdresse + letzte Bit 0 3. Slave sendet ACK 4. Master sendet Command Byte 5. Slave sendet ACK 6. Master sendet Daten Byte 7. Slave sendet ACK 8. Master sendet STOP Auf dem uC habe ich im Master-Mode folgende Register: I2C1MSTA (R): Statusregister. Bits werden gesetzt, wenn kein ACK empfangen wurde, Sende-Fifo leer etc. I2C1MRX (R): Empfangsregister I2C1MTX (W): Senderegister I2C1ADR (R/W): Hier ist mit Sinn noch nicht 100% klar, desshalb aus dem Handbuch: I2CxADR are master address byte registers. The I2CxADR value is the device address that the master wants to communicate with. It automatically transmits at the start of a master transfer sequence if there is no valid data in the I2CxMTX register when the master enable bit is set. I2C1CFG: Konfiguration des I2C-Bus. Mit diesem Register wird Master Clock, Master Mode und IRQs konfiguriert. I2C1DIV (R/W): Taktrate des Bus I2C1CNT (R/W): Wofür ist das gut= Wenn mehre Bytes empfangen werden sollen? I2CxCCNT are 8-bit start/stop generation counters. They hold off SDA low for start and stop conditions. I2C1FSTA (R): Status des Tx-Fifo Jetzt zu meinen Problemen. Ich will das Poti ds 1803 Einstellen. Laut Handbuch müssen hierfür 3 Bytes übertragen werden: Slave Adresse, Command Byte, Data Byte Zum Initialisieren setze ich folgende Register GP1CON |= 0x2200; // Aktiviere I2C Bus Nr. 2 I2C1DIV = 0xCFCF; // normal mode 100kHz I2C1CFG = 0x82; // Aktiviere Clock und Master Mode Wie übertrage ich die eigentlichen Daten? Was passiert, wenn ich ein Byte in das Senderegister schreibe? Wird dann autoamtisch eine START-Condition gesendet, auf die dann mein Byte folgt? Woher weiß der Controller, wann die STOP-Condition gesendet werden soll? So etwas wird im Handbuch nirgens erwähnt. Ich hätte die Daten so übertragen: Schreibe Slave-Adresse in I2C1ADR; Warte bis Sende-Fifo Leer Überprüfe ob ACK gesendet wurde Sende Command Byte Warte bis Sende-Fifo Leer Überprüfe ob ACK gesendet wurde Sende Data Byte Warte bis Sende-Fifo Leer Überprüfe ob ACK gesendet wurde ?? Setze STOP-Condition Mit dieser Funktion versuche ich zu senden: int SendI2C(char SlaveAddress, char Command, char Data) { //SlaveAddress ^= 0x01; // Beim Schreiben ist das letzte Bit der Adresse 0 I2C1ADR = SlaveAddress; // Sende Adresse des Slave zu Fifo I2C1MTX = Command; // Sende Befehl //I2C1CNT = 3; // Anzahl der Bytes der Übertragung // Kein ACK angekommen oder Arbitration Loss char status = I2C1MSTA; if ((status & 0x08)!=0) WritelnUart ("Kein ACK"); if ((status & 0x10)!=0) WritelnUart ("Arbitration Loss"); WritelnUart("XX"); I2C1MTX = Data; status = I2C1MSTA; if ((status & 0x08)!=0) WritelnUart ("Kein ACK"); if ((status & 0x10)!=0) WritelnUart ("Arbitration Loss"); return 0; } Als Ausgabe erhalte ich: XX Arbitration Loss Warum erhalte ich den Fehler? Dummerweise erhalte ich die die selbe Ausgabe, wenn ich eine ungültige Slave Adresse verwende. Leider habe ich keine Ahnung, wo ich mit der Fehlersuche anfangen soll .... Gruß, Tilo