Forum: Mikrocontroller und Digitale Elektronik Twi sendet keine Daten


von Sebastian (Gast)


Lesenswert?

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

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

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...

von spess53 (Gast)


Lesenswert?

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

von spess53 (Gast)


Lesenswert?

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

von Sebastian (Gast)


Lesenswert?

ich habe den ATmega8
und warum sollten die pullup Widerstände nicht ausreichen?
danke ich werde mir mal die beiden links in ruhe durchschauen

von spess53 (Gast)


Lesenswert?


von Sebastian (Gast)


Lesenswert?

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.

von Sebastian (Gast)


Lesenswert?

Das auf das ACK warten passirt doch in :  while (!(TWCR & (1<<TWINT)));

von Steffen H. (avrsteffen)


Lesenswert?

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

von Spess53 (Gast)


Lesenswert?

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

von Sebastian (Gast)


Lesenswert?

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

von Sebastian (Gast)


Lesenswert?

@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 ?

von Spess53 (Gast)


Lesenswert?

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

von Sebastian (Gast)


Lesenswert?

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

von Steffen H. (avrsteffen) (Gast)


Lesenswert?

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

von Sebastian (Gast)


Lesenswert?

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 ?

von Steffen H. (avrsteffen) (Gast)


Lesenswert?

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

von Spess53 (Gast)


Lesenswert?

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

von Steffen H. (avrsteffen) (Gast)


Lesenswert?

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

von Georg G. (df2au)


Lesenswert?

Sebastian schrieb:
> while(!(TWSR = 0x50))

Sicher, dass das so gemeint ist?

von Steffen H. (avrsteffen) (Gast)


Lesenswert?

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

von Spess53 (Gast)


Lesenswert?

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

von Sebastian (Gast)


Angehängte Dateien:

Lesenswert?

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

von sebastian (Gast)


Lesenswert?

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 ?

von spess53 (Gast)


Lesenswert?

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

von Uwe (Gast)


Lesenswert?

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.

von spess53 (Gast)


Lesenswert?

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
Noch kein Account? Hier anmelden.