mikrocontroller.net

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


Autor: Norbert L. (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Oryx (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: crazy horse (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Norbert L. (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [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.