Ringbuffer in 'C' beim USART

Gast #132677
Hallo Gemeinde,

Der CodeVision-ProgramWizard liefert mir folgende
Receiver-Interrupt-Sequenz:

// USART0 Receiver interrupt service routine
interrupt [USART0_RXC] void usart0_rx_isr(void)
{
char status,data;
status=UCSR0A;
data=UDR0;
if ((status & (FRAMING_ERROR | PARITY_ERROR | DATA_OVERRUN))==0)
   {
   rx_buffer0[rx_wr_index0]=data;
   if (++rx_wr_index0 == RX_BUFFER_SIZE0) rx_wr_index0=0;
   if (++rx_counter0 == RX_BUFFER_SIZE0)
      {
      rx_counter0=0;
      rx_buffer_overflow0=1;
      };
   };
}

Das Prinzip ist mir klar, jedoch bei den Details blicke ich nicht
durch. - Drum ein paar Fragen:

1. Die gesendete Bytefolge steht im Buffer(rx_buffer). Wie kann ich
diesen Inhalt in mein Programm einarbeiten?

2. Der Indexzähler 'rx_wr_index0' muß doch sicher nach Ende der
Übertragung auf '0' gesetzt werden,oder?

3. Am Ende der Funktion sieht man geschlossene Klammern mit Semikolon.
Was bedeutet das?

Gruß   Norbert L.
Gast
Hi,

1. Evtl. Interrupt sperren
   rx_buffer[index] bis zum Wert von rx_wr_index0 auslesen
   Interrupt gegebenenfalls wieder freigeben

2. rx_wr_index0 kannst du nach dem Auslesen der Zeichen auf 0 setzen.
   Interrupts wieder sperren
   Kann man schön mit 1 kombinieren.

3. Das Simikolon scheint nur nach den if-Abfragen an Ende der }
aufzutauchen. Ich sehe dafür keinen grund. Einfach mal weglassen.
Soll evtl. Übersichtlixher sein.


Die Interrupts sollten nie zu lange gesperrt sein.

Ich hoffe, etwas geholfen zu haben.

Oryx
Gast
um die Interrupts brauchst du dich nicht kümmern, wird schon mit
behandelt.
Du prüfst einfach, ob rx_counter>0, wenn ja, sind Zeichen da, wenn ==0,
dann eben nicht.
Die Zeichen selbst liest du mit
temp=getchar();
Dabei wird automatisch der Buffer aktualisiert und rx_counter
decrementiert.
Falls die Möglichkeit besteht, dass der buffer überläuft, kannst du
noch das buffer_overflow_flag testen, kommt auf dein Programm an, ob
das nötig ist.
Gast
hallo oryx, hallo crazy horse,

ich bin ja auch ein Dappes;-),

CodeVision liefert mir zum Auslesen des Ringzähler auch eine Funktion:

#ifndef DEBUG_TERMINAL_IO
// Get a character from the USART0 Receiver buffer
#define ALTERNATE_GETCHAR
#pragma used+
char getchar(void)
{
char data;
while (rx_counter0==0);
data=rx_buffer0[rx_rd_index0];
if (++rx_rd_index0 == RX_BUFFER_SIZE0) rx_rd_index0=0;
#asm("cli")
--rx_counter0;
#asm("sei")
return data;
}
#pragma used-
#endif

Die habe ich doch übersehen. Aber mit Eurer Hilfe verstehe ich jetzt
die Zusammenhänge.

Besten Dank    Norbert L.

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 21 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.