Forum: Mikrocontroller und Digitale Elektronik TXC Timing Frage


von Pepe (Gast)


Lesenswert?

Hallo,
ich verwende einen ATmega640 und versende über USART0 mit 115kb einen
Befehl. Kommunikation ist halb-duplex. Anschließend warte ich auf die
Antwort. Ich polle hier mit Absicht.

Aber ich habe ein Verständnisproblem:
Laut Datenblatt wird TXCn high wenn das Transmit Shift Register den 
Frame
komplett rausgeschoben hat und UDR0 kein neues Zeichen mehr hat.
Also warte ich im Quellcode, bis TXC0 high wird. Bei (1) im Code.

Jetzt sollte ich eigentlich den RS485 Treiber von senden auf empfangen
umschalten können. Mache ich dies sofort, fehlen mir einige Bits, da
zu diesem Zeitpunkt noch nicht alle Bits verschickt wurden. Kann ich
wunderschön im Logikanalyser sehen.

Ok. Ich kann eine entsprechende Wartezeit einbauen ( siehe (2) ). Dann 
läufst wieder.

Aber ich verstehe es trotzdem nicht.

Kann mir jemand helfen ? Danke. Pepe.


UCSR0B = (1<<TXEN0);              // Enable nur Transmitter

iPointer = 0;
do
{
    C = mOutBufferSF[iPointer];
    UDR0 = C;

    while ((UCSR0A & (1<<UDRE0)) == 0) // Warten solange UDR voll ist
    {
        wdt_reset();
    }
    iPointer++;
} while ((uint8_t) C > 10);         // Bis EOC verschickt wurde

asm volatile ("nop");
asm volatile ("nop");
asm volatile ("nop");
asm volatile ("nop");

while ((UCSR0A & (1<<TXC0)) == 0)  // Warten bis Zeichen raus sind
{
    wdt_reset();      (1) Warte bis TXC0 high ist
}

// Transmit ist durch, kompletter Befehl ist raus

(2) Hier wurde noch einige Bits nicht verschickt

_delay_us(Wartezeit damit das letzte Zeichen raus geht)

ioDisableTransmitter();    // RS485 Transmitter abschalten
ioEnableReceiver();    // Receiver aktivieren

... Warte auf Antwort ...

von spess53 (Gast)


Lesenswert?

Hi

Und wie ist die genaue Frage?

TXC wird gesetzt wenn ein Byte gesendet wurde und kein Byte mehr im 
Puffer vorhanden ist.

UDR sagt lediglich, das der Transmitter ein Byte aufnehmen kann.

MfG Spess

von Pepe (Gast)


Lesenswert?

Warum kommt TXC0 schon bevor das letzte Byte komplett raus ist ?

von Stefan E. (sternst)


Lesenswert?

Weil du das Flag anscheinend nie löschst.

von Karl H. (kbuchegg)


Lesenswert?

Ich würde auf jeden Fall erst mal das TXC Bit vor der Kommunikation 
löschen. Bedenke: Das Bit wird nur dann gelöscht wenn
* ein entsprechender Interrupt aufgerufen wird (ist bei dir nicht der 
Fall)
* du selbst es löscht (ist in dem Codeausschnitt auch nicht der Fall)

d.h nach der allerersten Übertragung stimmt das TXC Bit nicht mehr, weil 
es nie zurückgesetzt wurde.

Und dann gibt es noch den Fall, dass deine Kommunikationsschleife etwas 
zu langsam ist und daher zwischendruch immer wieder mal ein TXC 
auftreten kann. D.h. eigentlich bist du nur dann auf der sicheren Seite, 
wenn du VOR dem Einschreiben des letzten Zeichens das TXC löscht.

von Pepe (Gast)


Lesenswert?

Das wars. Danke.

von spess53 (Gast)


Lesenswert?

Hi

>Warum kommt TXC0 schon bevor das letzte Byte komplett raus ist ?

Wenn du den Transmitter schnell genug fütterst nicht. Allerdings musst 
du das Bit vor der Übertragung manuell zurücksetzen (Schreiben einer 1 
) wenn du keinen Interrupt benutzt.

MfG Spess

von Stefan E. (sternst)


Lesenswert?

Karl Heinz Buchegger schrieb:
> D.h. eigentlich bist du nur dann auf der sicheren Seite,
> wenn du VOR dem Einschreiben des letzten Zeichens das TXC löscht.

Na ja, so richtig auf der sicheren Seite ist man nur, wenn man es danach 
macht. Und natürlich müssen beide Schritte (UDR beschreiben, TXC 
löschen) in eine Interruptsperre.

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.