Forum: Mikrocontroller und Digitale Elektronik 1-Wire und UART, wie kann man mein Problem mit dem UART-Interrupt lösen?


von Johann (Gast)


Lesenswert?

Hallo,

ich möchte meine zwei Mikrocontrollerschaltungen mit jeweils einem 
DS18S20 erweitern. In der Beschreibung der 1-Wire-Bausteine steht, dass 
man während der Kommunikation mit diesen Bausteinen keinen Interrupt 
auslösen darf.
Das ist insofern doof, weil die Mikrocontrollerschaltungen zyklisch der 
Reihe nach angesprochen werden.
Der UART-Empfang ist mit einem Interrupt gelöst, soll heißen, wenn der 
Mikrocontroller ein Zeichen empfängt, löst das ein Interrupt im 
Mikrocontroller aus. Wenn dieser aber gerade mit dem DS18S20 
kommuniziert, wird dieser nicht richtig angesprochen bzw. ausgelesen.
Die Möglichkeit den DS18S20 erst anzusprechen, wenn ein Interrupt vom 
UART ausgelöst wird, fällt flach, da dieser Vorgang den gesamten Bus 
verzögert.

Ich stelle mir sowas vor:
Alle 10 Sekunden wird eine Kommunikation mit dem DS18S20 aufgebaut und 
speichert den Wert in der Variable 'temp'.
Der UART gibt nur den Inhalt von 'temp' aus und stößt nie die 
Kommunikation mit dem DS18S20 an.
Aber da kommt mir wieder der UART-Empfangs-Interrupt in die Quere, der 
mir womöglich die Kommunikation mit dem 1-Wire-Sensor stört.
Oder habe ich einen Denkfehler?

Johann

von Jens M. (dl4aas) Benutzerseite


Lesenswert?

Hallo Johann,

so kannst Du es lösen - es besteht aber immernoch Kollisionsgefahr.

Kannst Du die nächste Messung nicht auslösen, nachdem die letzte 
UART-Kommunikation abgewickelt ist? Oder, wenn die Abfragen zyklisch 
sind und Du aktuellere Werte haben möchtest, mit einer Zeitverzögerung. 
So verzögert, dass die Messung fertig ist, wenn die nächste Abfrage 
kommt.

Die beiden Dinge einfach nebeneinander her laufen zu lassen, solltest Du 
vermeiden, wenn es möglich ist.

Gruß
Jens

von ps (Gast)


Lesenswert?

Du kannst zwischen den 1wire bit's dein interrupt abarbeiten nur nicht 
wärend eins 1wire bit's, solang du die Interruptroutine kurz hälst.

von ps (Gast)


Lesenswert?

Heist vor jedem bit die Interrupt abschalten und danach wieder 
einschalten.
Wenn dazwischen ein interrupt aufgetreten ist wird er dann abgearbeitet.

von Olaf (Gast)


Lesenswert?

Schreib dir einfach eine 1Wire Routine die selber im Interrupt laeuft 
und lass die selber mit einer sehr hohen Interruptprioritaet laufen.

Der 1Wire Interrupt laeuft selber mit einem TimerInterrupt und besteht 
aus einer Statemaschine die nacheinander immer nur ein Bit abarbeitet 
und dann die Zeit im Timer fuer das naechste Bit setzt.

Olaf

von Johann (Gast)


Lesenswert?

Jens Mundhenke schrieb:
> Kannst Du die nächste Messung nicht auslösen, nachdem die letzte
> UART-Kommunikation abgewickelt ist?
Naja, in der Regel schon, aber die Kommunikation über UART ist 
"schneller" als das "Warten" auf den 1-Wire-Wert.
Ich habe das mit meinen Mikrocontrollern so gelöst:
Mikrocontroller wird angesprochen, dieser sendet seine Daten.
Hat der PC die Daten empfangen, so spricht er direkt danach den zweiten 
Mikrocontroller an usw. Es läuft alles automatisch...

ps schrieb:
> Heist vor jedem bit die Interrupt abschalten und danach wieder
> einschalten.
> Wenn dazwischen ein interrupt aufgetreten ist wird er dann abgearbeitet.
Also zwischen den einzelnen Bits des 1-Wire-Sensors? Dann würde ich doch 
auch wieder die Kommunikationszeit für den Sensor verfälschen und 
erhalte falsche Werte?!

Wie wäre es, wenn ich einen weiteren Mikrocontroller einsetze?
Der erste ist für die UART-Kommunikation, der andere für das Auslesen 
des 1-Wire-Sensors. Da nur ein Sensor angeschlossen wird, könnte ich 
doch die Sensordaten auf die Ausgänge des einen Mikrocontrollers legen 
und diese dann parallel mit dem anderen Mikrocontroller einlesen.

Johann

von Axel L. (axel_5)


Lesenswert?

Da es sich nur um Temperaturen handelt, die sich nicht sprungartig 
ändern, sollte es kein Problem sein, wenn mal eine Übertragung in die 
Hose geht.

Und dem 18S20 macht es auch nix, wenn da mal eine Übertragung 
abgebrochen wird. Die nächste wird ja mit einem Reset komplett neu 
angestartet.

Solange Deine Interrupts also nicht zu oft kommen, sollte das kein 
Problem sein.

Gruss
Axel

von Johann (Gast)


Lesenswert?

Olaf schrieb:
> Der 1Wire Interrupt laeuft selber mit einem TimerInterrupt und besteht
> aus einer Statemaschine die nacheinander immer nur ein Bit abarbeitet
> und dann die Zeit im Timer fuer das naechste Bit setzt.

Klingt kompliziert, hört sich aber auch gut an.

von Detlev T. (detlevt)


Lesenswert?

Da der µC auf dem 1Wire-Bus der Master ist, startet er ja stets die 
Übertragung und muss ihn nicht ständig überwachen. Wie ps schon 
geschrieben hat, kann er zwischen zwei Bits problemlos unterbrochen 
werden, nur eben nicht mitten drin.

Solltest du den avr-gcc-Compiler verwenden, gibt es in <util/atomic.h> 
die Macros, um das elegant zu lösen.

von Johann (Gast)


Lesenswert?

Axel Laufenberg schrieb:
> Da es sich nur um Temperaturen handelt, die sich nicht sprungartig
> ändern, sollte es kein Problem sein, wenn mal eine Übertragung in die
> Hose geht.
Es handelt sich um eine Innenraum-Temperaturmessung, bei der keine 
sprungartige Änderung zu erwarten ist.

Axel Laufenberg schrieb:
> Und dem 18S20 macht es auch nix, wenn da mal eine Übertragung
> abgebrochen wird. Die nächste wird ja mit einem Reset komplett neu
> angestartet.
Ja, das stimmt auch.

Axel Laufenberg schrieb:
> Solange Deine Interrupts also nicht zu oft kommen, sollte das kein
> Problem sein.
Mein "Bus" läuft mit 9600 Baud, die kürzeste Zeit zwischen Zeichen 
empfangen und Zeichen senden beträgt 100ms (musste ein Delay einbauen).
Wie definierst du "nicht zu oft"?

von Olaf (Gast)


Lesenswert?

> Klingt kompliziert, hört sich aber auch gut an.

Laeuft auch sehr gut und zuverlaessig in einigen meiner Regelungen. :-)
Braucht vor allem auch kaum Rechenzeit weil die meiste Zeit ja
fuers warten draufgeht und die macht dann der Timer alleine.

Olaf

von Johann (Gast)


Lesenswert?

Olaf schrieb:
> Laeuft auch sehr gut und zuverlaessig in einigen meiner Regelungen. :-)
Gibt es ein Programmier-Beispiel? ;)

Detlev T. schrieb:
> Wie ps schon
> geschrieben hat, kann er zwischen zwei Bits problemlos unterbrochen
> werden, nur eben nicht mitten drin.
Ach, aus dieser Sichtweise habe ich das noch gar nicht betrachtet.
Es ist also problemlos möglich vor einem Bit ein cli zu setzen und nach 
dem Übertragen des Bits wieder mittels sbi die Interrupts zu aktivieren.
Interessant...

Detlev T. schrieb:
> Solltest du den avr-gcc-Compiler verwenden, gibt es in <util/atomic.h>
> die Macros, um das elegant zu lösen.
Ja, den Compiler benutze ich. Die atomic.h kenne ich noch gar nicht, 
muss ich mir mal genauer anschauen.

von Karl H. (kbuchegg)


Lesenswert?

Johann schrieb:

> Axel Laufenberg schrieb:
>> Solange Deine Interrupts also nicht zu oft kommen, sollte das kein
>> Problem sein.
> Mein "Bus" läuft mit 9600 Baud, die kürzeste Zeit zwischen Zeichen
> empfangen und Zeichen senden beträgt 100ms (musste ein Delay einbauen).
> Wie definierst du "nicht zu oft"?

Du wirst deinen DS1820 sowieso nicht zu oft auslesen wollen. Denn 
ansonsten ist die Eigenerwärmung des Sensors während der Arbeit schon 
nicht mehr zu vernachlässigen.
Wenn du daher alle (hausnummer) 1 Minute den DS1820 einmal ausliest und 
da zufällig in 10 Minuten mal ein Ausleseversuch dabei ist, der von der 
UART tatsächlich abgewürgt wird und deine Komplettschaltung daher wieder 
auf einen Messwert zurückgreifen muss, der schon 1 Minute alt ist, dann 
wird das in den meisten Fällen auch kein Beinbruch sein.

von Axel L. (axel_5)


Lesenswert?

Bin jetzt nicht so sicher, wie lange das Auslesen komplett dauert. Aber 
1 Bit übertragen dauert zwischen 60-120 us.

Mir scheint also, in den 100ms sollte man das Scratchpad auslesen 
können. Man kann das Timing ja an die untere Grenze legen. Mehr als 1000 
Bits (100ms/100us pro Bit) hat so eine Übertragung sicher nicht.

Gruss
Axel

von Johann (Gast)


Lesenswert?

Karl heinz Buchegger schrieb:
> Wenn du daher alle (hausnummer) 1 Minute den DS1820 einmal ausliest und
> da zufällig in 10 Minuten mal ein Ausleseversuch dabei ist, der von der
> UART tatsächlich abgewürgt wird und deine Komplettschaltung daher wieder
> auf einen Messwert zurückgreifen muss, der schon 1 Minute alt ist, dann
> wird das in den meisten Fällen auch kein Beinbruch sein.
Indoor-Temperaturen sind in der Regel träge und haben eine niedrige 
Priorität. Darum wird der Wert, der in der Variable temp steht, eh ein 
"veralteter" Wert sein.
Im Grunde würde das bedeuten, dass, wenn ich den Interrupt beim Auslesen 
des 1-Wire-Sensors auschalte, ich in 1 Minute maximal eine Verzögerung 
von ca. 1 Sekunde habe. Damit kann ich leben.
Ich will eh nicht alle 2 Sekunden den Sensor auslesen, da es bei einer 
Temperaturmessung nichts bringt.

von Johann (Gast)


Lesenswert?

Axel Laufenberg schrieb:
> Mir scheint also, in den 100ms sollte man das Scratchpad auslesen
> können.
Die Umwandlungszeit (Zeitbedarf für eine Messung) soll angeblich ca. 
750ms dauern.

von Olaf (Gast)


Lesenswert?

> Gibt es ein Programmier-Beispiel? ;)

Darf ich leider nicht.

> Du wirst deinen DS1820 sowieso nicht zu oft auslesen wollen.

Ich hab das mal ausprobiert. Liesst man ihn 1/s aus und der
Sensor befindet sich freistehend in Luft, so erhoeht sich dadurch
dessen Temperatur um 0.3Grad.
Sobald er aber irgendwo angebracht ist oder in Wasser eintaucht
kann man das IMHO vernachlaessigen.

> Die Umwandlungszeit (Zeitbedarf für eine Messung) soll angeblich
> ca. 750ms dauern.

Das ist der offizielle Wert laut Datenblatt. Gemessen habe ich mal 
580ms.

Olaf

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.