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


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.

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.