Forum: Compiler & IDEs Uart Buffer verwenden


von Michael (Gast)


Lesenswert?

Hi,

ich stecke gerade etwas mit dem buffer der avrlib fest.

es kommt ein zeichen über uart0 rein, dann wird das zeichen in den 
buffer kopiert:

bufferAddToEnd(&uartRxBuffer[0], charIn);

und jetzt soll das zeichen wieder interruptgesteuert aus dem buffer an 
uart0 gesendet werden.

kann mir jemand helfen wie es weitergeht?

uartSendBuffer(0,???);

von Stefan B. (stefan) Benutzerseite


Lesenswert?

> bufferAddToEnd(&uartRxBuffer[0], charIn);
> uartSendBuffer(0,???);

Du meinst die Procyon AVRlib
http://www.mil.ufl.edu/~chrisarnold/components/microcontrollerBoard/AVR/avrlib/docs/html/uart_8c-source.html

Die gesuchte Funktion (Anhängen eines Zeichens an den zuvor 
eingerichteten Sendepuffer) wäre uartAddToTxBuffer(charIn)

> bufferAddToEnd(&uartRxBuffer[0], charIn);

Diese Konstruktion ist IMHO sehr ungewöhnlich. Ich würde vom 
Hauptprogramm aus den Empfangspuffer schön in Ruhe lassen. Normalerweise 
würde deine gesamte Abfrage (Emfangen und Echo zurücksenden) so aussehen
1
  {
2
    u08 charIn;
3
    if (uartReceiveByte(&charIn))
4
      uartAddToTxBuffer(charIn);
5
  }

von Michael (Gast)


Lesenswert?

uartAddToTxBuffer(0, charIn);

ok, jetzt ist das zeichen im buffer.

wie wird der buffer jetzt gesendet?

von Michael (Gast)


Lesenswert?

bei:

uartSendTxBuffer(0);
wird  \0\0\0\0 gesendet.

Es kommen aber Zeichen an.

von Stefan B. (stefan) Benutzerseite


Lesenswert?

Michael wrote:
> uartAddToTxBuffer(0, charIn);

Du hast meine Antwort nicht verstanden und bist dem Link nicht wirklich 
nachgegangen. Hättest du das gemacht, hättest du dort gesehen, wie die 
Funktion definiert ist:
1
// add byte to end of uart Tx buffer
2
u08 uartAddToTxBuffer(u08 data)
3
{
4
  //...
5
}

Schon die Zahl der Argumente in deinem Code passt nicht.

von Michael (Gast)


Lesenswert?

bei mir ist das so definiert:

void uartAddToTxBuffer(u08 nUart, u08 data)
{
  bufferAddToEnd(&uartTxBuffer[nUart], data);
}

von Stefan B. (stefan) Benutzerseite


Lesenswert?

Das ist aus uart2.c, d.h. die Library mit zwei Puffern.
http://www.mil.ufl.edu/~chrisarnold/components/microcontrollerBoard/AVR/avrlib/docs/html/uart2_8c-source.html
1
// Description  : This is a UART driver for AVR-series processors with two
2
//                hardware UARTs such as the mega161 and mega128

nUart ist die Nummer des UARTs (0 oder 1)
data ist das zu sendende Zeichen (0x00 bis 0xFF)
1
#include "buffer.h"
2
#include "uart2.h"
3
4
//...
5
6
  {
7
     char *s = "Hello world!";
8
9
     uartInit();
10
11
     while(*s)
12
       uartAddToTxBuffer(0, *s++); // UART0 TX Buffer füllen
13
14
     uartSendTxBuffer(0);          // UART0 Senden einschalten
15
  }
16
17
//...

von Michael (Gast)


Lesenswert?

Hi Stefan,

jetzt bin ich durch deine Hilfe schon etwas weiter.

Der buffer wird befüllt.

Aber das auslesen des buffers sollte anderst laufen.

Die Zeichen die über uart reinkommen sollen durchgeschleift werden, das 
heißt gleich wieder rausschicken auf die uart.

ohne buffer wäre das ja so:

1. Zeichen kommt rein   Zeichen = UDR1
2. Zeichen an uart      UDR0 = Zeichen

ich denke so soll man es nicht machen, wie mache ich das mit buffer?

1. uartAddToTxBuffer(0, Zeichen);
2.

mit uartSendTxBuffer(0); wir der buffer gesendet, aber aufruf in main 
kann doch zu oft, oder zu spät sein oder?

von Stefan B. (stefan) Benutzerseite


Lesenswert?

1
#define UART0 0
2
#define UART1 1
3
4
// ...
5
u08 TXaktiv;
6
7
  while(1)
8
  {
9
    u08 rxData;
10
11
    if (uartReceiveByte(UART1, &rxData))
12
    {
13
      uartAddToTxBuffer(UART0, rxData);
14
      TXaktiv++;
15
    }
16
17
    // irgendwann wenn z.B. genug Zeichen im TX-Puffer sind
18
    // TX starten
19
    if (TXaktiv >= 23)
20
      uartSendTxBuffer(UART0);
21
22
    // Anm.: Ich habe keine einfache Funktion gefunden, mit der 
23
    // man dieses interruptbasierte Senden aus dem Puffer nach
24
    // Wunsch stoppen kann. Man kann es wohl nur an schalten und
25
    // dann laufen lassen. Mehrfachaufruf schadet aber nicht.
26
  }
27
28
// ...

EDIT: Eine Alternative wäre TXaktiv++; wegzulassen und die if-Abfrage so 
zu machen, um den Mehrfachaufruf zu vermeiden.
1
    if (!TXaktiv)
2
    {
3
      uartSendTxBuffer(UART0);
4
      TXaktiv = 1;
5
    }

von Michael (Gast)


Lesenswert?

wo setzt du TXaktiv auf 0

von Stefan B. (stefan) Benutzerseite


Lesenswert?

Das Hochzählen in Alternative 1 ist eigentlich Käse. Ich habe mir 
irgendwas aus den Fingern gesogen, um ein Beispiel zu haben, das einen 
Puffer halbwegs rechtfertigt.

Bei der Alternative 2 (ohne Hochzählen) wird TXaktiv bewusst nirgends 
zurückgesetzt. Das Senden ist einmal angestossen worden und läuft ab 
dann im Interrupt nebenher immer weiter. TXaktiv != 0 verhindert 
einfach, dass das Senden noch mal angestossen wird (wäre aber folgenlos, 
wenn es doch geschähe).

von Bernd bömer (Gast)


Lesenswert?

Hallo,
ich arbeite auch mit dieser Lib und versuche mit einem ATMega128 ein 
String ("$BM,1666.123 m<CR>"aus 9..12 Zeichen(0.000 m ..1666.123 m) zu 
empfangen und daraus die Zahlen auf einem LC -Display daszustellen..
Wie kann ich das einlesen?
Mfg Bernd

von Stefan B. (stefan) Benutzerseite


Lesenswert?


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.