mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Freescale I²C/TWI Implementierung


Autor: Bob (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Forum,

ich versuche gerade auf einem Freescale Mikrocontroller (MC56f8036) die 
TWI/I²C-Inerface zu implemtieren.

2 Mikrocontroller sollen als Master/Slave kommunitieren.

Für I²C-Schnittstelle nehme ich Pin 1 als SDA und Pin 42 als SCL
(GPIOB6 -> SDA; GPIOB8 -> SCL).
über 2,7 kOhm Widerstände sind beide Leitungen mit 3,3 V verbunden 
(Pull-up).

1 Mikrocontroller ist als Master und der andere ist als Slave 
konfiguriert.
Damit ich sehe dass die Verbindung funktioniert und die Kommunikation 
stattfindet, will ganz einfach STARTEN und ADRESSE vom Slave auswählen. 
Wenn ich das hab, dann müsste ich doch ACK vom Slave erhalten oder wenn 
die Adresse nicht existiert, dass ich Fehlermeldung erhalte.

Egal welche Adresse ich auswähle, bekomme ich OK Meldung.

Die Entwicklungsumgebung ist CodeWarrior.

Bin für jede Hilfe sehr dankbar

Bob

Autor: M. H. (doktorgnadenlos)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ein ACK darf es nur bei übereinstimmender Adresse geben. Beim Datenbyte 
ist das ACK bei den meisten Slave-Devices nicht aktiv.

Hast Du bei dem Slave-uC die I2C-Adresse schon programmiert ?

Hast Du technisch die Möglichkeit ein Oszibild von der SCL- und der 
SDA-Leitung hier ins Forum zu stellen ?

Autor: Bob (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
ich übergebe dem Slave die Adresse 0x10 und damit muss doch die Adresse 
festgelegt sein..

ich war gerade dabei ein Bild von Oszi zu machen :-)

Autor: M. H. (doktorgnadenlos)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich erkenne auf dem Bild nicht die Adresse 0x10, sondern 0x20, gefolgt 
von dem 9. Clock für das ACK. Wenn der Slave auf die Adresse 0x10 
reagieren soll,  wird er seine SDA-Leitung während des ACK-Pulses nicht 
auf Masse ziehen.

Autor: Bob (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
wie erkennst du dass es 0x20 ist?

Habe für "Slave Address" 0x10 eingetragen.

Autor: M. H. (doktorgnadenlos)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Zum Oszibild:
Das erste Byte fängt wohl nach dem etwas verlängerten High-Impuls auf 
der SDA-Leitung an. Bei jeder steigenden Flanke der SCK-Leitung wird der 
Zustand auf der SDA-Leitung überprüft. Man kommt dann auf das Bitmuster 
00100000(1), was hexadezimal 0x20 entspricht.

Zu dem I2C-Tool:
Mir fällt auf, dass dort "7-bit-address" eingestellt ist. Probier das 
mal mit "8-bit-address", wenn sich das machen läßt. Das wäre nämlich die 
Erklärung, dass er das Byte um einen Clock nach links verschiebt.

Autor: Bob (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
:-( es gibt aber nur 7bit oder 10bit Adresse

Autor: M. H. (doktorgnadenlos)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dann versuch's mal mit der Burst durch's Auge und konfigurier den Slave 
mit Adresse 0x20, also dem Wert, den ich auf dem Bus erkenne. Dann 
sollte das 9.Bit LOW sein, weil der Slave seine Adresse erkannt hat.

Autor: M. H. (doktorgnadenlos)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
"Brust", nicht "Burst" :-)

Autor: Bob (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hmm.. wenn ich die Slave-Adresse 0x20 auswähle, bekomme ich 0100 0000 
(0x40) als Bitmuster.

ist für dich der zweite High-Pegel ACK vom Slave? Warum bekomme ich dann 
immer diesen zweiten High-Pegel?

Autor: Bob (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
auch bei der Slave-Adresse 0x20 bleit alles gleich

Autor: M. H. (doktorgnadenlos)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du sieht 9 mal einen Clock-Impuls pro Byte. Die ersten acht Bit stehen 
für das Datenbyte, das letzte bit ist das ACK. Wenn die Adresse erkannt 
wird, muss es auf LOW liegen.
Noch eine andere Möglichkeit, wenn's nicht weiterführt : Ich sehe, das 
Datenbyte wird ständig gesendet. Interessant wäre das Verhalten nach 
einem Reset des I2C-Slaves. Denn wenn einmal ein Bit zuviel oder zuwenig 
gesendet wird, "verschluckt" sich der Slave und ist nicht mehr 
bytesynchron. Auch auf die Adresse richtige kann er dann nicht mehr 
reagieren.

Autor: Bob (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
@ M. H.

danke du warst eine große Hilfe.

7bit Adresse ist 7 Bit groß. Das 8. Bit steht für read/write und das 9. 
ACK/NACK.

beim 8. Puls durch runterziehen des High-Pegels auf Low bestätigt Slave 
das alles OK ist :-)

Autor: Bob (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
beim Datenübertragen habe ich Probleme:

wenn ich Daten an Slave sende, wird es in "I2C_DATA"-Register 
festgehalten aber wenn ich versuche vom Slave zu lesen, bekomme ich 
keine Daten.

Beim Slave werden doch die Daten zum übertragen im "I2C_TXFT"-Register 
gespeichert und wenn Master zum lesen auffordert, müsste Master doch die 
Daten vom "I2C_TXFT"-Register abholen/bekommen oder stimmt das nicht?

Autor: M. H. (doktorgnadenlos)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich habe gerade das Datenblatt des MC56F8036 überflogen. Da gibt es 
zunächst ein Register I2C_DATA, welches als Receive- und 
Transmit-Register konzipiert ist. Probier dort mal Dein Byte dort 
reinzuschieben.
Das I2C_TXFT ist eher ein Fifo, gedacht für den Fall, dass der Slave 
mehrere Bytes zeitlich hintereinander senden soll, aber die Zeit zum 
Nachladen des I2C_DATA-Registers möglicherweise nicht ausreicht.

Autor: Bob (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hmmm.. etwas ist faul, aber weiß nicht was faul ist.

beim Slave schreibe schreibe ich ins Data-Register und will beim Master 
es auslesen aber es will nicht.

Ich benutze sowohl die Funktion RecvChar() ( ANSIC prototype: byte 
RecvChar(byte *Chr) ) als auch das Data-Register beim Master, aber steht 
immer eine 0 drin

Autor: Bob (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
habe ein Bild vom Oszi eingefügt.

Was passiert nach dem 9.Clock? ( SDA->HIGH; SCL->LOW und SCL ist länger 
als sonst)

Und am Ende kommt ein NACK (weil SDA auf HIGH)

Autor: M. H. (doktorgnadenlos)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sieht so aus, als ob der Slave tatsächlich 0x00 zurückschickt, der 
Fehler liegt wohl an der Slavekonfiguration.

Sind die zugehörigen I2C-Register richtig konfiguriert ? Ich meine 
verlangt das Telegramm nach einer Antwort vom Slave ? Wie Du gesehen 
hast gibt es Read- und Write-Telegramme. Der Slave muss so konfiguriert 
sein, dass sein Datenbyte auch abgefragt wird.

Hast Du mal probiert  v o r  dem Empfang der I2C-Adresse das 
I2C_DATA-Register mit einem Wert zu beschreiben ?

Autor: Bob (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
wenn ich vor dem Empfang der I²C-Adresse das I2C_DATA-Register mit einem 
Wert zu beschreibe, sendet der Master kein STOP Condition mehr und am 
Bus liegt immer dieser Wert, was in das I2C_DATA-Register beschrieben 
wurde.

Der Slave muss immer mit ACK/NACK antworten.

Das erste Telegramm beinhaltet (7bit Slaver Adresse + 1bit Read/Write + 
ACK/NACK) und alle anderen (8bit für Daten + 1bit ACK/NACK), dh. wenn 
Master Daten sendet/empfängt muss Slave mit ACK reagieren

Autor: M. H. (doktorgnadenlos)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Dass der Slave immer mit einem ACK antwortet ist nicht richtig. Leider 
ist da I2C nicht einheitlich. In vielen Fällen wird das Datenbyte mit 
NACK quittiert, d.h. das 9.Bit bleibt auf HIGH ! Am besten Du 
verifizierst über das Datenblatt, wie sich der I2C des MC56F8036 
tatsächlich verhält.

Autor: Cimbom Gs (cimbomgs)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Kann mir bitte jemand helfen??

Ich benutze den selben Mikrocontroller und habe einige Probleme bei der 
I²C-Kommunikation.

Mein Problem ist, dass mein Master immer die vorherige Werte vom Slave 
erhält und beim ersten Start bekomme ich immer eine Null.

Dh. sobald ich I²C-Bus starte und den Wert vom Slave abhole, erhalte ich 
eine Null..UND das nächste Mal erhalte ich die Werte von vorher..


Was kann ich machen? Oder wie kann ich das umgehen??

Da ich 2 Werte vergleiche, brauche ich immer die aktuellen Werte


und noch eine Frage:
Ist es normal, dass man über I²C-Bus immer vom Slave die vorherigen Wert 
erhält??


Danke

Autor: Doktor Gnadenlos (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nein, das ist nicht normal. Was hast Du für ein I2C-Slave dranhängen ? 
Hast Du mal im Datenblatt von diesem I2C-Baustein nachgeschaut ?

Autor: Cimbom Gs (cimbomgs)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Doktor Gnadenlos wrote:
> Nein, das ist nicht normal. Was hast Du für ein I2C-Slave dranhängen ?
> Hast Du mal im Datenblatt von diesem I2C-Baustein nachgeschaut ?

Ich benutze 2 mal den gleichen Mikrocontroller. Habe den einen als Slave 
und den anderen als Master konfiguriert.

Ich weiß nicht voran es liegt aber habe fast alles mögliche ausprobiert 
->jedes mal das gleiche.

Autor: Mike R. (thesealion)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenn du da immer die zu alten Werte zurüc kbekommst, dann ist 
wahrscheinlich deine Routine auf dem Slave fehlerhaft.

Ich kann mich erinnern, daß es bei der Freescale implementierung des 
Slave nicht ganz einfach war die richtigen Daten auch schnell genug 
bereit zu stellen.

Autor: Doktor Gnadenlos (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Bist Du sicher, dass auch der jeweils vorige Wert verschickt wird oder 
liegt der Fehler in der Software ?
Hast Du das mal mit einem Oszi überprüft ?

Autor: Cimbom Gs (cimbomgs)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Doktor Gnadenlos wrote:
> Bist Du sicher, dass auch der jeweils vorige Wert verschickt wird oder
> liegt der Fehler in der Software ?
> Hast Du das mal mit einem Oszi überprüft ?

ich benutze parallel dazu einen Oszi aber bringt nicht viel, da die 
Werte sich ständig ändern und ich ja die Signale nicht zwischenspeichern 
kann.

aber ich benutze 2 PCs und habe Brakepoints gesetzt. Wenn ich das ganze 
debugge dann sehe ich ganz genau, dass der Master immer den alten Wert 
vom Slave hat. Was aber gar nicht sein sollte. der Slave müsste immer 
den aktellen Wert für den Master in den Buffer legen.

ps. auch wenn ich einen Langen delay beim Master einfüge, bekommt Master 
das erste Mal immer nur Nullen.

Autor: Doktor Gnadenlos (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Okay, mit welchem Controller arbeitest Du ?
Im Datenblatt muss es ein Hinweis geben, der das Verhalten erklärt.

Ich schau mir das gern mal an.

Autor: Cimbom Gs (cimbomgs)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Freescale Mikrocontroller (MC56f8036)

ich habe das Datenblatt mehrmals durchblättert aber finde nichts :-(

Autor: Doktor Gnadenlos (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Naja, bis jetzt finde ich noch nichts verdächtiges. Mir fällt auf, dass 
es nur ein gemeinsames Register für Senden und Empfangen gibt.

Wann wird der zu sendende Wert des Slaves ins Register I2C_Data 
geschrieben ? Etwa schon vor dem I2C-Interupt ?

Evtll. muss das Register bei Auftreten des Interrupt und vor jedem 
Senden erst noch gelesen werden, auch wenn der Wert keine Info enthält.

volatile unsigned char bDummy;
bDummy = I2C_Data;

Autor: Cimbom Gs (cimbomgs)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Doktor Gnadenlos wrote:
> Wann wird der zu sendende Wert des Slaves ins Register I2C_Data
> geschrieben ? Etwa schon vor dem I2C-Interupt ?

immer dann wenn ein START-Condition ausgelöst wurde. Slave wartet bis 
Master gestarte hat, danach wird der Wert in den Register geschieben.

Autor: Cimbom Gs (cimbomgs)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
kann mir niemand helfen :'( BITTEEEE

ich drehe noch durch %-(
      
I2C1_SetMode(master);
do
{
   I2C1_SelectSlave(slave_addr);
   Err = I2C1_SendBlock(&send_chr, 1, &send_temp);
} while( (Err != ERR_OK) );


oder


I2C1_SetMode(master);
do
{
   I2C1_SelectSlave(slave_addr);
   I2C1_SendChar(send_chr);
} while( (data_send != TRUE) ); // data_send wird in ISR auf TRUE gesetzt 

warum wird das Datum gesendet obwohl ich gar kein Slave verbunden habe?!
Ich habe die Verbinding zwischen Master und Slave getrennt aber der 
Master behauptet trotzdem er hätte an Slave das Datum gesendet....aaaaa 
das kann doch gar nicht sein -> es existiert überhaupt kein Slave

seid einer Woch bin ich dabei den Fehler zu finden, was kann es nur 
sein?

Bitte gibt mir paar Tipps, was ich Testen sollte bzw. wie ich den Fehler 
entdecken könnte BITTEEEEEEE...

Autor: Mike R. (thesealion)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Cimbom Gs wrote:
> warum wird das Datum gesendet obwohl ich gar kein Slave verbunden habe?!
> Ich habe die Verbinding zwischen Master und Slave getrennt aber der
> Master behauptet trotzdem er hätte an Slave das Datum gesendet....aaaaa
> das kann doch gar nicht sein -> es existiert überhaupt kein Slave
>


Hast du korrekte Pullups am Bus? Wenn man SDA extern mit Masse 
verbindet, denkt der Master immer die Slaves sind da. Außerdem Antworten 
die Slaves auf alles mit 0x00.

Und bei deinen verschobenen Antworten denke ich, du stellst die Daten 
nicht schnell genug bereit. Deshalb sendet der Slave mit dieser 
Verschiebung.

Autor: Cimbom Gs (cimbomgs)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mike S. wrote:
> Hast du korrekte Pullups am Bus?
ja habe ich


> Und bei deinen verschobenen Antworten denke ich, du stellst die Daten
> nicht schnell genug bereit. Deshalb sendet der Slave mit dieser
> Verschiebung.

ja aber auch wenn ich eine lange Warteschleife beim Master einfüge, 
passiert das Selbe..

o man o man ich weiß echt nicht mehr was ich machen soll :'(..

Kollege von mir hat sich das angeschaut, der hat sich auch gewundert wie 
das passieren kann..

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.