Hallo zusammen, um werte aus einem 3-Achen Beschleunigungs-Sensor Auszulesen,möchte ich über den i2C (twi) bus auf die Register 0x02-0x07 des Sensors zugreifen. Der Slave hört auf den Namen 0x70 ich verwende folgenden code: #define F_CPU 1200000 #include <avr/io.h> #include <util/twi.h> #define SCL PC5 #define SDA PC4 #include "lcd-routines.h" int main(void) { int wert = 0x02; lcd_init(); lcd_string("start"); // Pull-Up Widerstände von SCL und SDA setzen DDRC &= ~((1<<SCL) | (1<<SDA)); PORTC |= (1<<SCL) | (1<<SDA); // benötigten Wert zur Datenratenerzeugung in das TWBR schreiben TWBR = 10; TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN) | (1<<TWEA); while (!(TWCR & (1<<TWINT))); TWDR = (0x70<<1) | TW_WRITE; TWCR = (1<<TWINT) | (1<<TWEN); while (!(TWCR & (1<<TWINT))); TWCR = (1<<TWINT) | (1<<TWEN); wert= TWDR; TWCR = (1<<TWINT) | (1<<TWSTO) | (1<<TWEN); lcd_setcursor(0,2); lcd_string("duch und fertig"); return 0; } über ein LCD Display soll er mir sagen das er angefangen hat und das er durch gelaufen ist. hat jemand von euch eine Ahnung was ich falsch gemacht habe? grüße Sebastian
Sebastian schrieb: > hat jemand von euch eine Ahnung was ich falsch gemacht habe? Was sollte denn passieren? Was passiert tatsächlich? Und wie stellst du das fest? > hat jemand von euch eine Ahnung was ich falsch gemacht habe? Du hast z.B. den Typ des uCs nicht genannt...
Hi >#define F_CPU 1200000 1,2MHz, sicher? >// Pull-Up Widerstände von SCL und SDA setzen >DDRC &= ~((1<<SCL) | (1<<SDA)); >PORTC |= (1<<SCL) | (1<<SDA); Für TWI sind die internen Pull-Up-Widerstände eine Krücke. Ca. eine Zehnerpotenz zu groß. >TWCR = (1<<TWINT) | (1<<TWEN); >wert= TWDR; Bevor du TWDR ausliest solltest du das ACK vom Slave abwarten. MfG Spess
Hi Führe dir am besten mal die passende AppNote zu Gemüte: http://www.atmel.com/Images/doc2564.pdf http://www.atmel.com/Images/AVR315.zip MfG Spess
ich habe den ATmega8 und warum sollten die pullup Widerstände nicht ausreichen? danke ich werde mir mal die beiden links in ruhe durchschauen
HI >warum sollten die pullup Widerstände nicht ausreichen? Schon mal etwas von der I2C-bus specification gehört? http://www.google.de/url?sa=t&rct=j&q=UM10204&source=web&cd=1&ved=0CCQQFjAA&url=http%3A%2F%2Fwww.nxp.com%2Fdocuments%2Fuser_manual%2FUM10204.pdf&ei=CuCPUOOKNYixtAbgw4HICQ&usg=AFQjCNG5emVs3tU5RbGVKjblTMFgLLHdqg MfG Spess
mit welchem Befehl kann ich auf das ACK warten ? und 10k interne pull up´s sollten doch eig reichen? zumindest haben die Pins 2,3 Volt am Ausgang sodass die 5V durchaus erreicht werden können.
Sebastian schrieb: > Das auf das ACK warten passirt doch in : while (!(TWCR & (1<<TWINT))); Nö, das signalisiert dir nur eine TWI Aktion. Aber im 'TWSR' (STATUSREGISTER) steht ein Code zum Status. Den musst du nun auswerten. Steffen
Hi >mit welchem Befehl kann ich auf das ACK warten ? Warten war eigentlich nicht korrekt. Aber vor dem Auslesen des Datenregisters muss das Statusregister überprüft werden, ob ein ACK vom Slave empfangen wurde. Wenn nicht sind die Daten ungültig. >und 10k interne pull up´s sollten doch eig reichen? Wie kommst du nur auf 10k. Die Pull-Up-Widerstände liegen zwischen 20 und 50k. >zumindest haben die >Pins 2,3 Volt am Ausgang sodass die 5V durchaus erreicht werden können. ????? Außerdem hat nichts mit dem Pegel zu tun. Durch die Widerstände müssen die Kapazitäten der Übertragungsstrecke (Ein- Ausgänge +Kabel) umgeladen werden. Und bei zu großen Widerständen passt die Anstiegszeit nicht mehr. MfG Spess
ich ging bis her davon aus das die pull up´s dafür verantwortlich sind das die Spannung auf konstant 5V gehalten wird, aber okay. mit volgendem code warte ich aufs ACK TWCR = (1<<TWINT) | (1<<TWEN); while(!(TWSR = 0x50)) wert= TWDR; TWCR = (1<<TWINT) | (1<<TWSTO) | (1<<TWEN); aber daran liegt es bei mir nicht, weil das Programm immer noch nicht durch läuft. ich werde es noch mit niedrigeren pull ups versuchen denke aber nicht das es klapen wird. grüße Sebastian
@Spess in dem von Atmel Verfügung gestellten Code sind 2 Bibliotheken enthalten die mein AVR Studio gar nicht hatt es handelt sich um #include <ioavr.h> #include <inavr.h> kann es sein das das eine Älter Bibliothek ist die in die neuen AVR Studios nicht übernommen wurde ?
Hi >kann es sein das das eine Älter Bibliothek ist die in die neuen AVR >Studios nicht übernommen wurde ? Nein. Die Dateien sind für den IAR-Compiler. Wirst du wohl etwas anpassen müssen. MfG Spess
so, ich habe es geschafft das mein Program endlich durchlauft :D jedoch gibt mir TWDR nicht das aus was mir der Chip sagt sondern was ich ihm gesagt hab was er dem sensor sagen soll dh. ich kriege als Antwort meine Frage
Sebastian schrieb: > jedoch gibt mir TWDR nicht das aus was mir der Chip sagt sondern was ich > ihm gesagt hab was er dem sensor sagen soll dh. ich kriege als Antwort > meine Frage Du sendest vermutlich nur die Adresse des TWI-Slaves? Dann bekommst du natürlich auch die Adresse des TWI-Slaves als erstes zurück geliefert. So machen es jedenfalls die meisten (wenn nicht sogar alle) TWI-Devices. Zeig doch mal deinen komletten TWI Kommunikations Code. Gruß Steffen
ich glaub ich habe den Grund warum es sich so verhält über TWCR = (1<<TWINT) | (1<<TWEN); Wert= TWDR; Antwortet doch der slave aber vorher habe ich ihm nicht gesagt was er mir senden soll nur das er angesprochen wurde ich habe versucht im einfach nach der adress Übertragung noch mir TWDR = (0x02<<1) | TW_WRITE; TWCR = (1<<TWINT) | (1<<TWEN); noch das Register zu übertragen aber jetzt erhalte ich als Antwort 224 gibt es andere Befele mit denen ich direkt das erfragt Register ansprechen kann ?
Jetzt sag doch mal bitte was du sendest und vor allem was ist das denn für ein Beschleunigungssensor? Bezeichnung wäre nicht schlecht, wenn man dir da weiter helfen soll. Wie sieht dessen Protokoll aus? Normalerweise wird folgendes gesendet: 1. TWI-Start 2. Slave Adresse + WR 3. Register 4. TWI-Restart oder TWI-STOP + TWI-Start 5. Slave Adresse + RD 6. dummy Byte (zurück bekommst du den Inhalt von Register) 6.1. eventuell weitere dummy Bytes.. 7. TWI-Stop So, und wie machst du das? Gruß Steffen
Hi >6. dummy Byte (zurück bekommst du den Inhalt von Register) >6.1. eventuell weitere dummy Bytes.. Verwechselst du das jetzt nicht mit SPI? MfG Spess
Spess53 schrieb: >>6. dummy Byte (zurück bekommst du den Inhalt von Register) >>6.1. eventuell weitere dummy Bytes.. > > Verwechselst du das jetzt nicht mit SPI? Ich hoffe doch nicht.. Aber sicher bin ich mir da jetzt auch nicht. Deswegen wäre ein Blick ins Datasheet des Sensors angebracht. Grüße Steffen
Spess53 schrieb: > Verwechselst du das jetzt nicht mit SPI? Du hast Recht Spess. Das TWI hat ja nur eine Datenleitung :( Man macht einfach ab Punkt 6. ein TWI-Read? Steffen
Hi >Ich hoffe doch nicht.. Aber sicher bin ich mir da jetzt auch nicht. >Deswegen wäre ein Blick ins Datasheet des Sensors angebracht. Bei TWI wird kein 'Dummybyte' gesendet. MfG Spess
Hallo nochmal ich habe meinen Code nochmal Komplett neu geschrieben und diesmal Dokumentiert was er genau wo macht. wenn der Code durchläuft erhalte ich als Antwort auf den LCD Bildschirm "start224"(meine der Text vom Start und Inhalt des empfangene Datenpaketes). würde mich freun wenn da noch jemand drüber schaut und mir sagen kann warum es nicht funzt. Datenblatt des Slaves und seine i2c Eigenschaften http://www.elv-downloads.de/Assets/Produkte/9/915/91521/Downloads/91521_bma020_data.pdf Seite 35 Danke C: und Grüße Sebastian
und doch laut Datenblatt wird ein bummy bit gesendet und wenn ich das richtig verstehe wird das benötigt das der slave weiß ob ich jetzt lesen oder schreiben will ?
Hi >und doch laut Datenblatt wird ein bummy bit gesendet >und wenn ich das richtig verstehe wird das benötigt das der slave weiß >ob ich jetzt lesen oder schreiben will ? Das RW-Bit wird immer zusammen mit der Slaveadresse gesendet. Also kein 'bummy bit'. MfG Spess
Bitte erst mal TWI verstehen. Dann kann man sich mal was einfaches an den AVR dranmachen z.B. I2C EEPROM. Protokoll und Kommandos ausprobieren. Danach kannst du es ja nochmal versuchen mit was komplizierterem.
Hi >Bitte erst mal TWI verstehen. Das hier ist sehr hilfreich: http://ics.nxp.com/support/documents/interface/pdf/i2c.bus.specification.pdf MfG Spess
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.