Forum: Mikrocontroller und Digitale Elektronik I2C Kommunikation mit Quarz nicht möglich


von Jonas S. (joschmjs)


Lesenswert?

Hallo zusammen,

ich habe ein seltsames Problem, was mich schon einige Stunden gekostet 
hat.
Undzwar geht es um einen Atmega644PA, hier klappt die Kommunikation über 
I2C mit dem externen Quarz (14,7456MHz) nicht.
Mit dem interenen 8MHz RC-Osz. funktioniert es. Dort habe ich eine 
fehlerfreie Übertragung zu 97%.
Allerdings muss der Slave (Atmega8) auf 8MHz laufen. Ist das normal?
Uart funktioniert bei beiden Varianten einwandfrei.

Vielleicht hat jemand eine Idee, da ich den Quarz zwecks 
Fehleranfälligkeit und Temperaturdifferenz gerne verwenden wollte.

Für Einfälle bin ich dankbar.


Ps.: verwendet wird die lib von Peter Fleury

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


Lesenswert?

Jonas S. schrieb:
> Dort habe ich eine fehlerfreie Übertragung zu 97%.
Beim I²C muss die fehlerfreie Übertragung bei genau 100% liegen.
Wenn sie das nicht tut, dann hast du irgendwo einen bösen Fehler im 
System. DEN musst du finden. Und da ist der Quarz vermutlich bestenfalls 
ein Symptom, sicher nicht die Ursache.

Wie sieht dein Aufbau aus? Leitungslängen? Masseführung? Versorgung?

: Bearbeitet durch Moderator
von Jonas S. (joschmjs)


Lesenswert?

Hey Danke für die schnelle Antwort.

Kabellänge sind ca. 30cm Flachbandkabel und 10cm Flexkabel alles mit 
Micromatch Steckern und beim Flexkabel "normale" Stecker.
Masse liegt jeweils auf einer Ader.
Versorung ist ein Buck Converter von TI, die Spannung ist sauber 
geglättet.
SCL sieht auch sauber aus.
Ich habe aber gerade gesehen, dass auf SDA gelegentlich Spikes drauf 
sind.

von Jim M. (turboj)


Lesenswert?

Jonas S. schrieb:
> Allerdings muss der Slave (Atmega8) auf 8MHz laufen.

I²C Slave auf µC braucht funktionierendes Clock Stretching. Der 14,7 MHz 
Quarz könnte den Bus schlicht überfordern (zu schnell). Auch spielen 
Dinge wie der Wert der Pullups eine Rolle.

Näheres würde man vermutlich auf dem Oszi Bild sehen...

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

Jonas S. schrieb:
> Ps.: verwendet wird die lib von Peter Fleury

 F_CPU entsprechend geändert ?

von Jonas S. (joschmjs)


Angehängte Dateien:

Lesenswert?

F_CPU wurde natrülich geändert.
Im Anhang Screenshots von SDA und SCL mit int. 8MHz.

Pullups jeweils 3,3k an SCL und SDA.

: Bearbeitet durch User
von Joe F. (easylife)


Lesenswert?

Die "Spikes" sind normal. Sie sind das Resultat einer kurzen 
"Umschaltphase" auf SDA zwischen Master und Slave (z.B. vor einem ACK).

Interessanter wäre ein Screenshot der Kommunikation mit ext. Quarz, 
möglichst beide Signale gleichzeitig (SCL, SDA).

Ausserdem: bei 8 MHz hast du offenbar genau 100 KHz auf SCL. Um welchen 
I2C Slave handelt es sich genau? Vermutlich liegt bei 100 KHz genau das 
Limit des Slaves, und SCL wird mit dem externen Quarz entsprechend 
schneller (184 KHz).

: Bearbeitet durch User
von Jonas S. (joschmjs)


Angehängte Dateien:

Lesenswert?

Das könnte gut sein.

Was genau wolltest du zum Slave wissen?
Im Anhang ein Screenshot mit ext. Quarz auf 14,4756MHz

Im Assembler bin ich nicht so fit, für mich wäre es kein Problem mit der 
Frequenz runter zu gehen. Mir geht es ohnehin nur um 4 Bytes, die für 
das menschl. Gespür in echtzeitzeit übertagen werden sollen.

von Peter R. (Gast)


Lesenswert?

So hat bei mir ein SCL-Signal noch nie ausgesehen. Das war jedesmal eine 
gleichmäßige Gruppe von 9 Impulsen. Dann gabs meist einen sichtbaren 
Abstand zur nächsten CL-Impulsgruppe.

Die teilweise Überlappungen der Flanken von SCL und SDA sind nun 
absoluter Müll. SDA darf sich doch nur in der Zeit ändern, in der SCL hi 
ist. Sonst wird die SDA-Flanke als Start- oder Stop- Kommando erkannt.

Das kann  passieren, wenn SDA zu scnell nach der Flanke von SCL 
ausgegeben wird, sodass dabei der hi-Pegel von SCL noch garnicht 
erreicht ist.

Deswegen tauchen hier auch scheinbar Vierer-SCL-Gruppen auf: nach etwa 3 
oder 4 Takten kommt so ein scheinbares Stop-Kommando und ein neuer 
"Übertragungsversuch" wird gestartet.

Also schau Dir nochmal die für I2C festgelegte Folge von SCl und SDA an.

mit Erhöhung des Takts von 8M auf 14M dürfte der zeitliche Abstand so 
eng werden, dass SDA schon in die Flanke von SCL trifft.

Beim langsamen Takt gehts halt gerade noch gut, bei 14M nicht mehr. Man 
sollte  z.B. durch NOPs dafür sorgen, dass sich SDA erst bei stabilem 
SCL ändert. Eine andre Lösung (testweise) bestände darin, den bus 
schneller zu machen, indem man niedrigere pullup-Widerstände nimmt.

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

Peter R. schrieb:
> Die teilweise Überlappungen der Flanken von SCL und SDA sind nun
> absoluter Müll. SDA darf sich doch nur in der Zeit ändern, in der SCL hi
> ist. Sonst wird die SDA-Flanke als Start- oder Stop- Kommando erkannt.

 Umgekehrt.
 Jede Änderung der SDA Line wenn Clock High ist, wird als START oder
 STOP dekodiert, je nach Flanke.

von Peter R. (Gast)


Lesenswert?

Na gut, dann ist halt die low-Phase die kritische Zeit. Jedenfalls muss 
man am Zeitverlauf der Signale aufräumen, da offensichtlich ungewollte 
start- oder stop-Signale enstehen.

von Peter R. (Gast)


Lesenswert?

Peter R. schrieb:
> Na gut, dann ist halt die low-Phase die kritische Zeit. Jedenfalls
> muss
> man am Zeitverlauf der Signale aufräumen, da offensichtlich ungewollte
> start- oder stop-Signale enstehen.

grrr, schon wieder vertan. Die hi-Phase von SCL ist kritisch.

von Joe F. (easylife)


Lesenswert?

Jonas S. schrieb:
> Was genau wolltest du zum Slave wissen?

Na, um welchen Chip es sich handelt. Aus dem Datenblatt könnte man dann 
ersehen, ob das Ding mit SCL > 100 KHz klar kommt.

Jonas S. schrieb:
> Im Assembler bin ich nicht so fit

Assembler?
Ich dachte es geht um die C-library von Peter Fleury?

Wenn das so ist, guck mal ob du die Zeilen
1
/* define CPU frequency in Mhz here if not defined in Makefile */
2
#ifndef F_CPU
3
#define F_CPU 4000000UL
4
#endif

in "twimaster.c" bzw. das Makefile angepasst hast. Vermutlich nicht. 
Marc Vesely gab bereits den Hinweis.

Die Clock ist sichtbar schneller geworden, und offensichtlich gerät der 
I2C Master komplett ins Trudeln. Sieht man z.B. durch überlange 
Clock-Phase beim ACK. Clock-Stretching durch den Slave ist es nicht, 
denn dann wäre die Clock längere Zeit low.

Ich denke mal, wenn die Library korrekt konfiguriert ist, und I2C wieder 
mit 100 KHz arbeitet wird das Problem beseitigt sein (abgesehen davon, 
dass es eigentlich zu 100% und nicht zu 97% funktionieren soll).
Man könnte es dann mal mit 2.2K statt 3.3K pullups probieren.

: Bearbeitet durch User
von Jonas S. (joschmjs)


Lesenswert?

Ein Atmega8.
Laut Datenblatt sind für 100KHz bereits 6MHz nötig. Das erklärt wieso es 
mit weniger als 8MHz nicht funktioniert.

Es gibt von von Peter Fleury auch eine I2C-Master Library in Assembler, 
die Slave wohl nur in C.

Die F_CPU ist nur einmal und passend zu den Fuses definiert.
Kleinere Pullup Widerstände werde ich mal probieren.

von Joe F. (easylife)


Lesenswert?

Jonas S. schrieb:
> Ein Atmega8.
> Laut Datenblatt sind für 100KHz bereits 6MHz nötig. Das erklärt wieso es
> mit weniger als 8MHz nicht funktioniert.
>
> Es gibt von von Peter Fleury auch eine I2C-Master Library in Assembler,
> die Slave wohl nur in C.

Ok. Und in welcher Sprache ist dein Programm? Warum nutzt du nicht die 
C-Library?

> Die F_CPU ist nur einmal und passend zu den Fuses definiert.

Auf welchen Wert, und wo?

> Kleinere Pullup Widerstände werde ich mal probieren.

Die werden das momentan existierende Problem erstmal nicht lösen. Die 
CLK muss stabil werden und 100 KHz haben.

Die Frage nach dem Slave-IC ist unbeantwortet.

von Jonas S. (joschmjs)


Lesenswert?

Mein eigener Code ist in C.
Hab jetzt erst gesehen, dass es den Master auch in C gibt.
In der 1. Zeile in meinem Code auf 8000000UL (int. Osz. auf 8MHz) wo es 
ja funktioniert, bzw. 14745600UL mit dem ext. Quarz wo nichts geht.
Wieso SCL nicht angepasst wird, weiß ich nicht, im i2cmaster.S ist so 
ein Abschnitt eigentlich vorhanden.

Ich werde es mal mit der C Library probieren.


Das Slave IC ist ein Atmega8a

von A. S. (Gast)


Lesenswert?

Wo genau sehe ich, dass jeder komplette Clock-Impuls 10µs lang ist? Sind 
das 10µs pro Kästchen?

von Jonas S. (joschmjs)


Lesenswert?

Es sind 10µs/div Frequenz vom SCL sind eben deutlich mehr als 100kHz

von Joe F. (easylife)


Lesenswert?

Jonas S. schrieb:
> In der 1. Zeile in meinem Code auf 8000000UL

Setze F_CPU sicherheitshalber zusätzlich mal in deinem Makefile.

von Sascha W. (sascha-w)


Lesenswert?

Jonas S. schrieb:
> Mein eigener Code ist in C.
> Hab jetzt erst gesehen, dass es den Master auch in C gibt.
> In der 1. Zeile in meinem Code auf 8000000UL (int. Osz. auf 8MHz) wo es
> ja funktioniert, bzw. 14745600UL mit dem ext. Quarz wo nichts geht.
> Wieso SCL nicht angepasst wird, weiß ich nicht, im i2cmaster.S ist so
> ein Abschnitt eigentlich vorhanden.
>
> Ich werde es mal mit der C Library probieren.
>
>
> Das Slave IC ist ein Atmega8a

Wenn ich deine Oszibilder sehe gehe ich mal davon aus das du 
Software-TWI machst - warum? Beide Controller haben auch Hardware-TWI.

Sascha

von Jonas S. (joschmjs)


Lesenswert?

Das Makefile konnte ich auf die schnelle nicht ändern.
Das Makefile wird automatisch wieder überschrieben und wenn ich es 
manuell angebebe, findet er die *.elf nicht.
Ich nutze AS7.

@Sascha Weber Ich versuche den Hardware TWI in Betrieb zu nehmen ;)

Ah ich vergas, ich habe den Beispiel-Code von 
http://rn-wissen.de/wiki/index.php?title=TWI_Slave_mit_avr-gcc 
verwendet.

: Bearbeitet durch User
von Peter D. (peda)


Lesenswert?

Jonas S. schrieb:
> Ps.: verwendet wird die lib von Peter Fleury

Das ist nicht hilfreich.
Warum erwartest Du, daß sich jeder erstmal den Code selber 
zusammensuchen und ausdenken muß, was Du verzapft hast?
Häng einfach Deinen exakten Code als Dateianhang an und gut.

Peter R. schrieb:
> So hat bei mir ein SCL-Signal noch nie ausgesehen. Das war jedesmal eine
> gleichmäßige Gruppe von 9 Impulsen.

Stimmt, die Oszi-Bilder sind eindeutig fehlerhaft. Und ohne den exakten 
Code kann niemand feststellen, wieso.

Und nächstes mal die Signale untereinander und nicht überschreibend. 1 
Kästchen hoch reicht dicke.

von Jonas S. (joschmjs)


Angehängte Dateien:

Lesenswert?

Ich war nicht davon ausgegangen, dass es am Code liegt.
Im Anhang der verwendete Code vom Master.

: Bearbeitet durch User
von Peter D. (peda)


Lesenswert?

Jonas S. schrieb:
> Im Anhang der verwendete Code vom Master.

Und warum in Assembler?
1997 hätte ich das ja noch verstanden, aber nicht 2015 0-:

Das ist zwar SW-Master, aber kann unmöglich zu dem Oszibild passen. 
Woher kommen die Lücken alle 4 SCLs?

Die 5ms können auch nicht stimmen.
Ich komme auf: 14e6 / 1024 / 256 / 2000 = 35s

von Joe F. (easylife)


Lesenswert?

Ich vermute im Makefile ist F_CPU auf einen anderen Wert als in main.c 
definiert, und i2cmaster.S hält sich an das Define im Makefile.

Setze doch einfach mal
1
#undef F_CPU
2
#define F_CPU 14745600UL

an den Anfang von i2cmaster.S
Vielleicht hilft das ja schon.

von Jonas S. (joschmjs)


Lesenswert?

Bisher hatte ich keine Probleme Assembler Bibliotheken zu nutzen, also 
wieso nicht?

5ms sind es nicht, habe nicht daran gedacht den Kommentar zu ändern, ich 
komme auf 15e6/1024/2000 = 7Hz.

Joe F. schrieb:
> Ich vermute im Makefile ist F_CPU auf einen anderen Wert als in main.c
> definiert, und i2cmaster.S hält sich an das Define im Makefile.
>
> Setze doch einfach mal#undef F_CPU
> #define F_CPU 14745600UL
>
> an den Anfang von i2cmaster.S
> Vielleicht hilft das ja schon.

Heiliger Bimbam! Jetzt sind keine Lücken mehr im SCL Signal und die 
Übertragung klappt!
Den Tipp habe ich gebraucht.

Ich werde mir dann mal die Hardware Implementierung ansehen, wenn das 
wider Erwarten die in Software war.

Vielen Dank an alle Beteiligten!!

: Bearbeitet durch User
von Peter D. (peda)


Lesenswert?

Jonas S. schrieb:
> Bisher hatte ich keine Probleme Assembler Bibliotheken zu nutzen, also
> wieso nicht?

Wenn Du sie nicht verstehen willst, sondern nur als Black-Box und auch 
nicht vorhast, den Code auf andere CPUs zu portieren, dann geht auch 
Assembler.

Ich benutze SW-I2C in C mit nur geringen Anpassungen auf 8051, AVR und 
Cortex M3. Der Vorteil gegenüber HW-I2C ist, daß es keine HW-Bugs haben 
kann und damit einfacher und zuverlässiger ist.
HW-I2C lohnt sich erst bei viel I2C-Traffic bzw. ist notwendig für Slave 
oder Multimaster.

Jonas S. schrieb:
> 5ms sind es nicht, habe nicht daran gedacht den Kommentar zu ändern, ich
> komme auf 15e6/1024/2000 = 7Hz.

Und wo sind die 256 Zyklen (8Bit-Zähler) bis zum Überlaufinterrupt?

von Jonas S. (joschmjs)


Lesenswert?

Peter D. schrieb:
> Jonas S. schrieb:
>> 5ms sind es nicht, habe nicht daran gedacht den Kommentar zu ändern, ich
>> komme auf 15e6/1024/2000 = 7Hz.
>
> Und wo sind die 256 Zyklen (8Bit-Zähler) bis zum Überlaufinterrupt?

Da hast du recht.
Ich hatte es einfach nur angepasst ohne weiter zu denken um einen Timer 
zu haben.
Dass es so daneben war, lag daran dass ich beim Beschreiben des TCCR 
Registers die beiden Bits nicht bitweise verundet hab, sondern logisch 
verundet.

Danke für die Aufklärung.

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.