Hallo, ich hätte eine Frage. Kann man für UART eine scanf Funktion einbauen? Z.B für meinen Fall, dass ich Auswahloptionen 1, 2 und 3 habe und ich dann im Terminal z.B. 1 eingeben will, das ich in den nächsten Modus komme. Gibt es so eine Möglichkeit? Danke für alle Antworten. Mfg, Srdjan
Für diesen Fall ist scanf viel zu oversized. Bei einem Zeichen kann man zeichen -'0' rechnen.
1 | SetInputStream(usart); |
Genaueres verrät dir die Doku zu deinem System. Oliver
Srdjan S. schrieb: > In der Doku find ich nichts, das ist ja eine JAVA Funktion. Und das passt nicht?
Wir reden von einer 32bit maschine, gell ? Allenfalls ein Linux, oder RTOS dabei ?
Falls du es immer noch nicht mitbekommen hast: der C-Standard kennt keine UARTS - wie man ein File-Handle für eine UART erzeugt ist Systemabhängig und zu deinem System hast du bisher nichts gesagt. Falls es ein Atmel mit avr-libc ist, schau mal nach FDEV_SETUP_STREAM.
Srdjan S. schrieb: > In der Doku find ich nichts, das ist ja eine JAVA Funktion. Aha. Du hast den Hinweis also verstanden. Die Funktion musst du schon selber schreiben, und wie, verrät dir die Doku zu deinem System, welches ja nur du kennst. Oliver
Srdjan S. schrieb: > Hast du einen Beispielcode vielleicht dafür? http://stefanfrings.de/avr_hello_world/index.html
Tut mir Leid für die schlechte Fragenbeschreibung. Ich arbeite mit einem STM32F4.. Mikrocontroller.
Srdjan S. schrieb: > Ich arbeite mit einem STM32F4.. Mikrocontroller. Für Ausgabe mit printf() und puts() musst du die C-Funktion _write() implementieren. Ein Beispiel ohne Sende-Puffer:
1 | int _write(int file, char *ptr, int len) |
2 | {
|
3 | for (int i=0; i<len; i++) |
4 | {
|
5 | // Warte, bis das Sende-Register Platz hat
|
6 | while(!(USART2->SR & USART_SR_TXE)); |
7 | USART2->DR = *ptr++; |
8 | }
|
9 | return len; |
10 | }
|
Die C-Bibliothek puffert Textausgaben schon von sich aus bis zum Zeilenumbruch oder flush(). Für die umgekehrte Richtung muss du die Funktion _read() implementieren. Dafür habe ich kein Beispiel parat, deswegen hier ein unvollständiger Pseudo-Code:
1 | int _read(int file, char *ptr, int len) |
2 | {
|
3 | if (received_something) |
4 | {
|
5 | *ptr = the_received_character; |
6 | return 1; |
7 | }
|
8 | else
|
9 | {
|
10 | return 0; |
11 | }
|
12 | }
|
Oder du empfängst viele Zeichen in einer for Schleife (maximal so viele wie "len" vorgibt). Beides funktioniert. Für den Empfang empfehle ich dringend einen Puffer mit Interrupt-Handler.
Allenfalls waere es einfacher die paar Register und die funktionalitaet des UARTs im Kontext der CPU nachzuschauen. Es sind dann nur vielleicht 20 Zeilen Code.. dabei lernst du noch zu nicht-blockierendem Code zu denken. Waehrend ein sscanf eben doch meist blockierend ist.
>Kann man für UART eine scanf Funktion einbauen? Ja selbstverstaendlich. Z.B: Greif zu einem Motorola 68360 oder einem TI TMS320F069. Beide haben echt parallel arbeitende IO-Prozessoren. Die koennen natuerlich so ein pillepalle scanf locker nebenbei abhandeln. Es duerfen sogar mehrere UARTs sein, um den Luxus zu komplettieren. Top-Hersteller wie Cisco vertrauen dem 68360. Und lass dich nicht von den Laien hier verwirren, die soetwas natuerlich nicht kennen.
Pandur S. schrieb: > Waehrend ein sscanf eben doch meist blockierend ist. Das ist der Grund, warum es nur sehr selten benutze. Wenn man den UART Empfänger mit Puffer und Interrupt ausstattet, könnte man sich eine Funktion has_linefeed_in_rx_buffer() basteln und scanf nur dann aufrufen, wenn sich ein \n im Puffer befindet. Man muss dann aber auch garantieren, dass dieses Zeichen im Puffer bleibt, nicht dass es zwischenzeitlich aus irgend einem Grund verschwindet, z.B. weil man weitere Zeichen empfängt die zum Überlauf führen.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.