Forum: Mikrocontroller und Digitale Elektronik Reset des UART Empfangspuffers in Bascom


von Michael E. (mertl)


Lesenswert?

Hallo,

ich verwende einen Mega328P um serielle Daten zu verarbeiten. Der uC 
empfängt vom HUART, verarbeitet die Daten und sendet sie via SUART. 
Umgekehrt das gleiche vorgehen. Das Projekt ist auch schon fertig und 
tut was es soll, nur bei einer Kleinigkeit bräuchte ich etwas Hilfe:

Der UART empfängt so lange bis die Steuerzeichen Cr und Lf empfangen 
werden. Der Inhalt der empfangenen Daten wird in einer String-Variable * 
30 gespeichert. Um zu verhindern, dass die Variable im Fehlerfall 
überläuft, überprüft die Routine bei jedem Empfangenen Zeichen, ob die 
30 Zeichen schon voll sind. Würde dieser Fehlerfall eintreten, soll 
folgendes passieren:

- Interrupts deaktivieren -> kein Problem
- Diverse Variablen zurücksetzen -> kein Problem
- Fehlercode 2 Sek. per LEDs ausgeben -> kein Problem
- UART Empfangspuffer leeren, d.h. alle Daten die empfangen wurden, 
innerhalb der letzten 2 Sekunden (also während der Fehlercode via LEDs 
angezeigt wird) sollen verworfen werden -> hier bin ich etwas Ratlos
- Interrupts wieder aktivieren -> kein Problem

Ich möchte also nicht, dass der Interrupt für den Empfang eines Bytes 
ausgelöst wird, nachdem dieser reaktiviert wurde. Dazu habe ich mir das 
Datenblatt angesehen (S. 192), bin mir aber nicht sicher, ob das so 
funktionieren kann:
1
Sub ClearBuffers()
2
   Get #2 , byCurCharSW 'SUART Puffer leeren
3
   byCurCharSW = 0
4
   UCSR0B.RXCIE0 = 0 'Status-Register des HUART zurücksetzen
5
   Enable URXC
6
End Sub

Hier noch die Ausschnitte aus dem Datenblatt, die ich zu Rate gezogen 
habe:

20.11.2 UCSRnA – USART Control and Status Register n A

Bit 7 – RXCn: USART Receive Complete
This flag bit is set when there are unread data in the receive buffer 
and cleared when the receive buffer is empty
(i.e., does not contain any unread data). If the Rece
iver is disabled, the receive buffer will be flushed and
consequently the RXCn bit will become
 zero. The RXCn Flag can be used
 to generate a Receive Complete
interrupt (see description of the RXCIEn bit).

20.11.3 UCSRnB – USART Control and Status Register n B

Bit 7 – RXCIEn: RX Complete Interrupt Enable n
Writing this bit to one
enables interrupt on the RXCn Flag. A
USART Receive Complete interrupt will be
generated only if the RXCIEn bit is written to one, the
Global Interrupt Flag in SREG is written to one and the
RXCn bit in UCSRnA is set.

Kann das so funktionieren, wie ich es umgesetzt habe, oder gibt es einen 
anderen Weg für diese Problemstellung?

Schon mal Danke und schönen Gruß,
Michael

von spess53 (Gast)


Lesenswert?

HI

>Hier noch die Ausschnitte aus dem Datenblatt, die ich zu Rate gezogen
>habe:

Du hast noch

20.7.7 Flushing the Receive Buffer

vergessen.

MfG Spess

von Michael E. (mertl)


Lesenswert?

Danke für die super schnelle Antwort!

Ich habe ehrlich gesagt etwas Probleme den Code
1
void USART_Flush( void )
2
{
3
unsigned char dummy;
4
while ( UCSRnA & (1<<RXCn) ) dummy = UDRn;
5
}

zu übersetzen, speziell den Teil "UCSRnA & (1<<RXCn)"

kannst du mir vielleicht auf die Sprünge helfen?

von Falk B. (falk)


Lesenswert?

Man muss einfach nur 3x UDR auslesen und das Ergebnis wegwerfen. Eine 
Prüfung des Statusbits ist nicht nötig.

Sub ClearBuffer()
Dim A As Byte

   A = Udr
   A = Udr
   A = Udr
   Enable URXC
End Sub

von spess53 (Gast)


Lesenswert?

Hi

>speziell den Teil "UCSRnA & (1<<RXCn)"

Das einzige was ich dazu sagen kann ist, daß das für den ATMega328p 
übersetzt heißt:  "UCSR0A & (1<<RXC0)".

MfG Spess

von Falk B. (falk)


Lesenswert?

@ spess53 (Gast)

>>speziell den Teil "UCSRnA & (1<<RXCn)"

>Das einzige was ich dazu sagen kann ist, daß das für den ATMega328p
>übersetzt heißt:  "UCSR0A & (1<<RXC0)".

Ob das den OP weiterbringt? Hallo, das ist ein BASCOMer ;-)

>while ( UCSRnA & (1<<RXCn) ) dummy = UDRn;

Das ist eine while-Schleife, in es auch in BASCOM gibt.

UCSRnA & (1<<RXCn) ist eine Bitmanipulation, genauer, eine 
Bitabfrage von Bit RXCn im Register UCSRnA, wobei n durch die passende 
Zahl ersetzt werden muss.

von Michael E. (mertl)


Lesenswert?

@ Frank Brunner: Wenn ich das richtig verstehe, dann ist der Buffer also 
3 Byte. Durch das 3 x Auslesen wird dieser also auf jeden Fall gelöscht, 
oder?

Nochmal zu dem C-Code:

würde ich Versuchen, diesen in Basic zu übersetzen, würde das so 
aussehen:
1
Do
2
   byCurCharHW = UDR0
3
   wtmp = Shift 1 Left RXC0
4
   wtmp = UCSR0A And wtmp
5
Loop Until wtmp = 0

So ganz erschließt sich mir der Code noch nicht, aber wäre er denn 
generell richtig?

von Falk B. (falk)


Lesenswert?

@Michael Ertl (mertl)

>@ Frank Brunner:

Wie schafft man es immer wieder, ein so einfach Namen wie Falk mit 
gerade mal 4 Buchstaben zu verdrehen? Sollte ich mir einen einfacheren, 
kürzeren Namen zulegen? Al? Q? M? Dr. Z?

> Wenn ich das richtig verstehe, dann ist der Buffer also
>3 Byte.

Bei allen neueren AVRs der letzten 10 Jahre.

> Durch das 3 x Auslesen wird dieser also auf jeden Fall gelöscht,
>oder?

Ja.

>Do
>   byCurCharHW = UDR0
>   wtmp = Shift 1 Left RXC0
>   wtmp = UCSR0A And wtmp
>Loop Until wtmp = 0

falsch. Du musst einfach das Bit abfragen, das kann man in BASCOM direkt 
hinschreiben. Die UND-Verknüpfung ist nur in C bzw. dem avr gcc nötig, 
weil dort die IO-Register mittels definierter Bitnummern angesprochen 
werden. Lange Geschichte, für dich unwichtig.
1
Sub Clearbuffer()
2
Dim A As Byte
3
4
  While Ucsra.rxc = 1
5
    A = Udr
6
  Wend
7
  Enable Urxc
8
End Sub

Aber die Schleife incl. Abfrage ist überflüssig, sagte ich bereits.

von Michael E. (mertl)


Lesenswert?

Ok super, habe soweit alles verstanden, vielen Dank und Entschuldigung 
wegen des Namen Fauxpas

Es scheint nun alles bezüglich des o.g. Codes zu funktionieren. Nur an 
einer anderen Stelle gibt es noch Probleme, aber das schaue ich mir nach 
einer Pause noch einmal an.

Schönen Gruß,
Michael

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


Lesenswert?

Falk B. schrieb:
> gerade mal 4 Buchstaben zu verdrehen? Sollte ich mir einen einfacheren,
> kürzeren Namen zulegen? Al? Q? M? Dr. Z?

 Darf ich einen Vorschlag machen ?

von Paul B. (paul_baumann)


Lesenswert?

Marc V. schrieb:
> Darf ich einen Vorschlag machen ?

Lieber nicht...

-Paul-

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.