Forum: Mikrocontroller und Digitale Elektronik Ringbuffer in 'C' beim USART


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Norbert L. (Gast)


Lesenswert?

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.

von Oryx (Gast)


Lesenswert?

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

von crazy horse (Gast)


Lesenswert?

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.

von Norbert L. (Gast)


Lesenswert?

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

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]
  • [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.