Forum: Mikrocontroller und Digitale Elektronik UART und 1-Wire


von Steffen (Gast)


Lesenswert?

Hallo zusammen

Ich möchte einen 1-Wire Master mit dem UART eines AVR programmieren.
Dazu müssen bekannterweise der RX- und der TX-Pin zusammengeschaltet
werden, damit man sowohl Senden als auch Empfangen kann. Wenn man dann
beispielsweise einen Reset sendet, schaut man hinterher im
Empfangsregister, ob auf den Reset geantwortet wurde.

Aber:
Wie kann ich ermitteln, ob der UART überhaupt fürs Senden bereit ist?
Ich darf ja erst mit dem Senden beginnen, wenn das vorige "alte" Byte
aus dem Schieberegister vollständig gesendet wurde. Ich könnte zwar
schon mein neues Byte in den Sendepuffer (UDR) schreiben, aber dann
weiß ich ja nicht, ob ich beim Auswerten des Empfangsregisters (UDR)
fälschlicherweise das vorige "alte" Byte auswerte, oder bereits das
Neue!

Ich vermute, ich muss das TXC Bit auslesen, oder? Wenn das TXC Bit
gesetzt ist ('1'), sind sowohl Sendepuffer (UDR) als auch
Schieberegister leer. Es liegt also keine Datenübertragung an. Wenn das
Bit gesetzt ist ('1'), kann ich also mein Byte senden und gleich
wieder als empfangenes Byte auswerten.  Dummerweise wird das TXC Bit
aber mit '0' initialisiert!!! D.h., wenn ich nach einem µC-Reset
etwas Senden möchte, und darauf warte, dass das Senderegister frei wird
und das TXC Bit gesetzt wird, hängt sich die Schleife auf :-((

Wie macht mans richtig? Ich kann das Bit leider auch nicht manuell,
etwa bei der Initialisierung nach einem Reset, auf '1' setzen. Oder
bin ich mit dem TXC Bit ganz auf dem Holzweg?

Danke und Gruß,
Steffen

von Clemens (Gast)


Lesenswert?

Nimm einfach das UDRE (Usart Data Register empty) Flag! Das wird gesetzt
wenn Daten gesendet werden können! Und wird auch nach einem RESET
gesetzt.


Grüße Clemens

von Steffen (Gast)


Lesenswert?

Hallo Clemens

Das UDRE ist aber leider auch dann gesetzt, wenn das Senderegister
(UDR) zwar frei ist, aber das interne Schieberegister noch am Senden
ist!

Das Problem ist dann, dass ich nicht weiß, welche Daten ich im Anschluß
im Empfangsregister auswerte! Sind es die Daten, die noch im internen
Schieberegister waren, als ich ins Senderegister geschrieben habe? Oder
war das Schieberegister leer und es sind die richtigen Daten?

Hmm, schwierig zu erklären... Verstehst Du, wie ich das meine?

Gruß,
Jasper

von Kurt (Gast)


Lesenswert?

Hallo Steffen,

das ist im neuen Buch von Claus Kühnel sehr gut beschrieben.
(BASCOM für AVR)

Gruss Kurt

von Steffen (Gast)


Lesenswert?

Kurt, verrätst Du mir auch, was Herr Kühnel dazu meint? Ich programmiere
z.Z. mit Assembler und möchte mir nun kein BASCOM Buch kaufen. Außerdem
brennt mir das Problem unter den Nägeln ;-)

P.s.: Sorry, für den doppelten Eintrag oben!

von Rahul (Gast)


Lesenswert?

TXC (Transmit Complete) ist schon das richtige.
Seite 166 des DAtenblatts zum ATmega162 (hatte ich gerade zur Hand):
"The Transmit Complete (TXC) Flag bit is set to one when the entire
frame ... has been shifted out... The TXC Flag bit is automatically
cleared when transmit complete interrupt is executed, or it can be be
cleared by writing a one to to its bit location."

Im nächsten Absatz steht dann noch was davon, dass sich bei einer
TXC-Interrupt-Routine nicht um das Bit gekümmert werden muß. Das
erledigt die ISR...
Vielleicht hilft es. Bei mir läuft es seit über einem Jahr stabil in
einem RS485-Netzwerk.

Gruß Rahul

von Steffen (Gast)


Lesenswert?

Das Problem ist doch, dass ich wissen muss, ob der Transmitter mit
Senden beschäftigt ist. Das zeigt mir das TXC Bit auch an, wenn es
gesetzt ist, dann ist die "Transmission" (TX) "completed" (C).

Einzige Ausnahme: wenn seit dem letzten Reset noch überhaupt kein Byte
gesendet wurde. Dann ist die Übertragung natürlich noch nicht beendet
(="Transmission completed"), eben weil es gar keine Übertragung gab!
Deshalb wird das TXC Bit nach einem Reset mit '0' initialisiert.

Meine Empfangsroutine ist aber dumm, sie soll immer funktionieren,
unabhängig davon ob schon einmal was gesendet worden ist, oder nicht.
Soll ich ein Dummy-Byte senden? Aber da muss es doch noch eine elegante
Lösung geben...!

Gruß,
Steffen

von Rahul (Gast)


Lesenswert?

UDRE muß 1 sein, dann TXC testen. Hast du es auch freigeschaltet?
Ich habe die Routinen gerade nicht da, aber bei mir klappt das
wunderbar...

von Steffen (Gast)


Lesenswert?

Nein, das funktioniert nicht. Nach einem Reset ist UDRE mit '1'
initialisiert und TXC mit '0'. Obwohl ich mit dem Senden beginnen
könnte (das Senderegister ist ja leer), tritt meine Bedingung
(UDRE='1' & TXC='1') nie ein.

Aber ich habe das Problem jetzt von hinten aufgerollt. Bisher wollte
ich abfragen, ob der Bus fürs Senden frei ist. Jetzt gehe ich einfach
davon aus, dass er frei ist. Ich muss nur dafür sorgen, dass meine
"Senden" Routine auch erst dann verlassen wird, wenn ich mit dem
Senden tatsächlich fertig bin! Dann ist der Bus logischerweise
automatisch frei.

Vielleicht ist das auch Deine damals angewendete Lösung, Rahul. Wenn
Dir die Routinen nochmal in die Hände fallen, wäre ich sehr an Deiner
Lösung interessiert!

Ansonsten vielen Dank für Deine und Eure Hilfe :-)

Steffen

von Peter D. (peda)


Lesenswert?

Das geht so nicht, die UART-Funktion hat einen Gegentaktausgang, Du
brauchst aber einen open-drain Ausgang !

Warum machst Du das nicht einfach in Software (siehe Codesammlung) ?


Ansonsten hast Du recht. Du brauchst ein Zusatzbit um das allererste
Senden-Ende zu erkennen, da Du Interruptbits nicht setzen kannst.


Peter

von Clemens (Gast)


Lesenswert?

Hallo Steffen!

Meiner Meinung nach kannst du das UDRE bit trotzdem verwenden!

Du merkst dir einfach was du geschickt hast und sobald es zurückkommt
löscht du es! Wenn der Slave dasselbe schickt empfängst du es trotzdem
2x. Müsste doch gehn oder?

Grüße

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.