Hallo miroblaz,
Du bekommst das Ack-Bit immer?
Hast du Pull-Up-Widerstände eingebaut?
Gruss, Michael
Hallo Leute,
ich habe ein Problem in der Kommunikation über I2C mit meinem TMC222 Chip.
Ich benutze einen ATMega128 als Master und mein I2C-Protokoll ist in C geschrieben. Das Schreiben in den TMC222 funktioniert anscheinend, da ich vom Slave den Acknowledge-Bit immer bekomme. Wenn ich aber, die Daten vom TMC222 auslesen will, geht das nicht. Im Datenblatt stehen die Datagramme wie man es programmieren soll, aber irgend wie kapiere ich das nicht. Ich habe es so versucht, die Befehle GetFullStatus1, GetFullStatus2 und GetOTPParam auszuführen aber es funktioniert nicht:
|Startbit|SlaveAddress|0|A|Befehl|A|Stoppbit| und danach
|Startbit|SlaveAddress|1|A|Data|A|.....|Data|nA|St oppbit|
Wenn mir jemand helfen könnte und richtigen Datagramm aufschreiben würde, wäre ich sehr dankbar.
Miro
Hallo miroblaz,
Du bekommst das Ack-Bit immer?
Hast du Pull-Up-Widerstände eingebaut?
Gruss, Michael
Hallo Michael,
ich habe die Pull-Up-Widerstände nicht eingebaut, dafür habe ich aber die internen Pull-Up-Wid. vom Mikrocontroller aktiviert. Also meine SDA und SCL Leitungen sind im Ruhezustand immer auf High.
Also das ist mein Code:
int start_i2c(unsigned char address) //* Senden der I²C Startbedingung + Addresse des anzusprechenden Geäts
{
/*
* Returnwerte:
* 0 -> Startbedinung erfolgreich gesendet
* 1 -> Probleme beim sender der Start-Bedinung
* 2 -> Probleme beim senden der Addresse
* bzw. kein Device mit der angegebenen Addresse
*/
//Senden der START Bedingung
TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN);
//Warten bis TWI Bedingung gesendet wurde
while(!(TWCR & (1<<TWINT)));
//TWI Status berprfen
if((TWSR & 0xF != TW_START) return 1;
//Adresse des anzusprechenden Devices senden
TWDR = address;
TWCR = (1<<TWINT) | (1<<TWEN);
//Warten bis TWI Bedingung gesendet wurde
while(!(TWCR & (1<<TWINT)));
//TWI Status überprüfen
if((TWSR & 0xF != TW_MT_SLA_ACK) return 2;
return 0;
}
void stop_i2c(void) /*Senden der I2C Stopbedingung*/
{
TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO);
}
void write_i2c(unsigned char data) /* Daten an das addressierte Gerät schicken */
{
//Daten an das addressierte Devices senden
TWDR = data;
TWCR = (1<<TWINT) | (1<<TWEN);
//Warten bis TWI Bedingung gesendet wurde
while(!(TWCR & (1<<TWINT)));
}
unsigned char read_i2c_ack(void) /* Daten vom addressierten Gerät lesen und mit ACK best„tigen
Für alle Bytes bis auf das letzte zu übertragende Byte*/
{
TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWEA);
//Warten bis TWI Bedingung gesendet wurde
while(!(TWCR & (1<<TWINT)));
//TWI Status berprfen
if((TWSR & 0xF == TW_MR_DATA_ACK) return TWDR;
return 1;
}
unsigned char read_i2c_nack(void) /* Für das letzte zu übertragende Byte */
{
TWCR = (1<<TWINT) | (1<<TWEN);
//Warten bis TWI Bedingung gesendet wurde
while(!(TWCR & (1<<TWINT)));
//TWI Status berprfen
if((TWSR & 0xF == TW_MR_DATA_NACK) return TWDR;
return 2;
}
und ich gehe davon aus, dass die Ack-Bits nach dem senden der Adresse und des Befehlsbytes ankommen da auch meine Stoppbedingung ausgeführt wird und keine Fehler gemeldet werden.
Gruss, Miro
Hallo miroblaz,
Ich glaube nicht, dass sich deine TWI-Routinen davon beeindrucken lassenich habe die Pull-Up-Widerstände nicht eingebaut, dafür habe ich aber die internen Pull-Up-Wid. vom Mikrocontroller aktiviert.
Die Spec von I2C sagt mir, dass das I2C/TWI als open Collektor-System arbeitet. Das macht auch Sinn, wenn man mehr als 2 beteiligte Komponenten am Bus hat. Ich habe selbst noch wenig mit I2C gemacht, da ich lieber parallel arbeite. Eins weiss ich aber: Du _musst_ einen Pull-Up-Widerstand auf jeder I2C-Leitung einbauen.
Gruss, Michael
Hallo miroblaz,
ich tippe auch auf die (fehlenden) Pull-Up-Widerstände. Mach die internen aus und schliesse externe an. Bei mir läufts ganz gut mit 4K7.
So teuer sind zwei Widerstände ja auch nicht
Übrigens: zum TMC222 gabs schon mal was: Link
Grüsse, Martin
Hallo Michael und Martin,
ich habe die Widerstände eingebaut, so wie ihr das meinten. Es funktioniert trotzdem nicht. Kann es sein, dass ich den TMC222 irgendwie kaputgemacht habe!? Weil ich bei der Betriebspannung von 12V den Befehl SetOTP ausgeführt habe. Erst später bemerkte ich, dass "Supply Voltage for OTP Zapping" zwischen 8,5 und 9,5V liegt.
Grüsse, Miro!
Hallo miroblaz,
also richtig Kaputt kann ich mir nicht vorstellen (siehe anderer Thread, den ich weiter oben gepostet habe), ich hab das schon mit 24V gemacht, danach ließ sich der OTP zwar nicht mehr programmieren (auch nicht mit der richtigen Spannung), aber alles andere geht noch =D>
Du musst halt jetzt das IC mit seiner Basisadresse ansprechen.
Was bekommst du denn genau, wenn du den Slave auslesen willst?
Nicht zufällig nur FF? Das hatte ich am Anfang mal. Ich muß mal überlegen, was der Fehler war
Grüsse, Martin
Hallo Martin,
ich habe den neunen IC reingelötet und mit GetFullStatus1 abgefragt.
Der TMC222 antwortet aber nicht.
Ich wollte nichts weiter tun, bevor ich nachfrage, ob ich dann mit z.B. SetMotorParameter Command weiter gehen kann, ohne die 9V als Suply Voltage?
Noch eine Frage hätte ich noch.
Was bedeutet diese Dump Internal Address to Slave?
Ist es der Befehl der zu dem TMC gesendet werden muss. (zumindest habe ich das so gemacht)
SetMotorParameter ist unkritisch, das kannst du 1000mal machen, egal mit welcher Spannung (naja, nicht ganz ). Kritisch ist wirklich nur SetOTP.
Wenn du nach SetMotorParam mal einen Haltestrom auf dem Motor hast, ist das gröbste geschafft!
Martin
man bekommt die FFs wenn die I2C-Übertragung zu hoch ist. Das ist meistens bei GetOTPParam. Versuche mit <50kHz.Was bekommst du denn genau, wenn du den Slave auslesen willst? Nicht zufällig nur FF? Das hatte ich am Anfang mal. Ich muß mal überlegen, was der Fehler war
IngBo
Lesezeichen