Forum: Mikrocontroller und Digitale Elektronik Zwischen 2 USART Schnittstellen umschalten


von Knut (Gast)


Lesenswert?

Hi,

ich habe einen XMega128A3 (eigentlich egal) und möchte an beide USART 
Schnittstellen nutzen um Daten an zei Geräte zu schicken (LCD und PC).

Ich habe beide Schnittstellen initialisiert und sie funktionieren auch. 
Jetzt ist nur die Frage wie ich die printf Routine in die beiden USARTs 
umleiten kann.

Ich habe folgende Funktionen:
1
  int uart_putchar_PC (char c, FILE *stream)
2
{
3
  if (c == '\n')
4
    uart_putchar_PC('\r',stream);          
5
  loop_until_bit_is_set(USARTE1.STATUS, USART_DREIF_bp);
6
  USARTE1.DATA = c;                  
7
  return 0;
8
}
9
10
11
//  ****************************************************************************
12
13
  int uart_putchar_LCD (char c, FILE *stream)
14
{
15
  //Ausgabe des Zeichens
16
  USARTE0.DATA = c;                    
17
  loop_until_bit_is_set(USARTE0.STATUS, USART_DREIF_bp);
18
  return 0;
19
}

Dann habe ich mir gedacht die Ausgabe über:
1
void select_UART (uint8_t channel)
2
{
3
  if (channel == PC)  {fdevopen (uart_putchar_PC, NULL);}
4
  if (channel == LCD) {fdevopen (uart_putchar_LCD, NULL);}
5
}

zu selektieren. Das klappt aber leider nicht, offensichtlich
kann ich eine einmal gewählte Ausgabe nicht überschreiben.

Kann mir jemand helfen?



Gruß
Knut

von Oliver J. (skriptkiddy)


Lesenswert?

Wenn du mit dem avr-gcc und der avr-libc arbeitest, dann schau mal auf 
folgender Seite nach:
http://www.nongnu.org/avr-libc/user-manual/group__avr__stdio.html
Speziell das erste Beispiel.

Gruß Oliver

von Knut (Gast)


Lesenswert?

Hallo,

danke erstmal. Somit könnte ich mit
1
static FILE lcd = FDEV_SETUP_STREAM(uart_putchar_LCD,NULL,_FDEF_SETUP_WRITE);
2
static FILE pc = FDEV_SETUP_STREAM(uart_putchar_PC,NULL,_FDEF_SETUP_WRITE);
und dann über:
1
 stdout = &"lcd oder pc";
wählen?

Ich habe gerade den Beitrag Beitrag "Infomationen zu fdevopen"
gefunden der sich genau damit beschäftigt.

Welche Lösung ist die elegantere bzw. gibt es irgendwo Probleme?


Gruß
Knut

von Knut (Gast)


Lesenswert?

Hmmm.. klappt nicht, wenn ich fdev_setup_stream GROSS schreibe erkennt 
er es nicht, wenn ich es als klein Schreibe fehlt im ein Argument, er 
will 4 statt 3.
1
  static FILE lcd = fdev_setup_stream(uart_putchar_LCD,NULL,_FDEF_SETUP_WRITE);
2
  static FILE pc = fdev_setup_stream(uart_putchar_PC,NULL,_FDEF_SETUP_WRITE);
3
4
if (channel == PC)  {stdout = &pc;}
5
if (channel == LCD) {stdout = &lcd;}

Wieso?


Knut

von Knut (Gast)


Lesenswert?

Der Komiler erkennt es auch nicht wenn ich es klein schreibe.
Inlcuded habe ich die
1
#include <avr/interrupt.h>
2
#include <stdio.h>
3
#include <avr/io.h>
4
#include <util/delay.h>
5
#include <string.h>
6
#include <stdint.h>

Knut

von Knut (Gast)


Lesenswert?

Ok, obigen Fehler gefunden:
1
  static FILE lcd = fdev_setup_stream(FILE,uart_putchar_LCD, NULL, _FDEV_SETUP_WRITE);
 aber nun habe ich einen Neuen:#
error: expected expression before 'do'

Wo wird da noch ein "do" aufgerufen?


Knut

von Oliver J. (skriptkiddy)


Lesenswert?

Knut schrieb:
> Hmmm.. klappt nicht, wenn ich fdev_setup_stream GROSS schreibe erkennt
> er es nicht
Kann ich mir kaum vorstellen. Wenn du die avr-libc verwendest, dann hat 
die stdio.h beide Varianten inklusive.

Eventuell hilft es die Zeilen mal von Hand einzutippen - stimmt vllt. 
mit dem Font-Encoding was nicht.

Gruß Oliver

von Knut (Gast)


Lesenswert?

Mit dem erkennen hat wie um 12:09 geklappt, jedoch erwartet er noch 
einen Ausdruck vor einem do?

Damit kann ich nichts anfangen


Knut

von Knut (Gast)


Lesenswert?

Oliver J. schrieb:
> Eventuell hilft es die Zeilen mal von Hand einzutippen
Hat geklappt, warum auch immer.

Werde später gucken obs auch auf der Hardware läuft

Danke sehr.


Gruß
Knut

von Karl H. (kbuchegg)


Lesenswert?

> if (channel == PC)  {stdout = &pc;}
> if (channel == LCD) {stdout = &lcd;}

Das würde ich nicht so machen.

Um printf mitzuteilen, auf welchen Stream die Ausgabe erfolgen soll, 
gibt es fprintf.

So gesehen ist ein printf nichts anderes als ein

   printf( .... )   <==>  fprintf( stdout, ..... )

Das kannst du aber genausogut

   fprintf( pc, ".....

oder

   fprintf( lcd, "....

von Knut (Gast)


Lesenswert?

Danke für den Tip Karl Heinz,

mal gucken wie es mache, schön das es beim compilieren erstamal keine 
Fehler mehr
gibt. Mal gucken ob's auf der Hardware auch läuft.


Knut

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.