www.mikrocontroller.net

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


Autor: Johann (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Jens Mundhenke (dl4aas) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: ps (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: ps (Gast)
Datum:

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

Autor: Olaf (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Johann (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Axel Laufenberg (axel_5)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Johann (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Detlev T. (detlevt)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Johann (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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"?

Autor: Olaf (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Johann (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Axel Laufenberg (axel_5)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Johann (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Johann (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Olaf (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

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.