Hallo Gemeinde,
ich hab da mal ein Problem, bei dem ich langsam verzweifle.
Ich möchte einen Komandoparser in meinen Mega32 bauen und dazu zunächst
einmal einen String über die ser. Schnittstelle einlesen. Ich verwende
Peter Fleury's uart.c um die Daten zu senden bzw zu empfangen.
Da in seiner Lib keine funktion enthalten ist um Strings zu lesen habe
ich folgende Routine hinzugefügt:
1
#include <stdio.h>
2
#include <stdlib.h>
3
#include <string.h>
4
#include <avr/io.h>
5
#include <avr/interrupt.h>
6
#include <avr/pgmspace.h>
7
8
#include "uart.h"
9
10
/* define CPU frequency in Mhz here if not defined in Makefile */
11
#ifndef F_CPU
12
#define F_CPU 16000000UL
13
#endif
14
15
/* 38400 baud */
16
#define UART_BAUD_RATE 38400
17
18
19
void uart_gets( char* Input )
20
{
21
char c = uart_getc();
22
uart_putc( c ); // und gleich wieder zurückschicken, damit
uart_gets( Buffer, 50); // Auf eine Zeile vom Benutzer warten
48
49
//
50
// Testweise die komplette Zeile zurückschicken, so wie
51
// sie vom µC empfangen wurde
52
//
53
uart_puts( "Ich habe verstanden : " );
54
uart_puts( Buffer );
55
uart_putc( '\n' );
56
57
// war die Eingabe vom Benutzer der Text 'Test'
58
if( strcmp( Buffer, "Test" ) == 0 ) {
59
// Wenn ja, dann begrüsse ihn
60
uart_puts( "Hallo Test\n" );
61
uart_puts( "Wie gehts\n" );
62
}
63
}
64
}
Leider funktioniert das nicht so wie gedacht sondern es passieren zwei
Dinge:
1. der Prompt wird angezeigt:
Hier gehts los
>>
2. bei der Eingabe werden die Buchstaben im Terminalfenster ausgegeben.
Wenn ich Enter drücke springt die Anzeige an den Anfang der Zeile. Aber
es wird nichts ausgegeben.
3. Wenn ich erneut Buchstaben eingebe werden diese wieder im Terminal
dargestellt. Wenn ich dann zum zweiten Mal Enter drücke scheint sich der
Controller zu reseten, denn ich bekomme wieder den Prompt
Hier geht es los
>>
angezeigt.
Kann mir mal einer einen Tipp geben, was ich da ggf. falsch mache?
Es macht übrigens auch keinen untershcied, ob ich mit Int arbeite
(welches in der lib ja im oberen Byte eventuelle Fehler anzeigt) und den
unteren Teil für den String nutze oder ob ich (wie oben) direkt mit char
arbeite.
Gruß
mws
He, he, hallo mws :D
Du hast das hier durchgearbeitet ?
http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial/Der_UART#einzelne_Zeichen_empfangen
Denk' mal es ist nicht so perfekt, void uart_gets( char* Input ) mit
einem Argument zu definieren, aber mit 2 Argumenten aufzurufen:
uart_gets( Buffer, 50);
Gibt's da nicht Mecker vom Compiler ?
Interessant ist auch laut Tutorial:"...daher mit einem Return ('\n')
abgeschlossen wird."
Was hat dann das hier in Deinem Quelltext zu bedeuten: while( c != '\r'
)
Hi,
also ich hab die Variante mit dem MAXLEN natürlich auch ausprobiert aber
wenn ich die verwende wartet wie Endlosschleife in main nicht bis ein
kompletter String eingegeben ist sondern es läuft immer die "Ich habe
verstanden:" Anzeige durch und man kann gar nichts eingeben.
Das ich auf '\r' prüfen muss weil mein Terminalprogramm scheinbar kein
'\n' sendet hat auch ne Weile gedauert.
Das Gleiche Problem tritt aber auch auf, wenn ich als Zeilenende z.B das
Semikolen verwende. :-(
mws
mws schrieb:
> Hallo Gemeinde,>> ich hab da mal ein Problem, bei dem ich langsam verzweifle.>> Ich möchte einen Komandoparser in meinen Mega32 bauen und dazu zunächst> einmal einen String über die ser. Schnittstelle einlesen. Ich verwende> Peter Fleury's uart.c um die Daten zu senden bzw zu empfangen.
Dann sieh dir das Demo vom Peter an oder lies dir wenigstens die Doku
dazu durch.
uart_getc ist kein wartendes getc sondern kehrt auch dann zurück, wenn
kein Zeichen vorliegt.
Je nachdem woher ein String kommt, kann man sich's einfacher machen
anstelle eines Null-terminierten Strings einen mit der Laenge am Anfang
zu verwenden.
dabei gibts dann wieder andere probleme, z.b. wenn während der
übertragung ein zeichen verloren geht. ich bevorzuge bei textübertragung
daher die variante mit endmarkierung. das gibt zwar auch probleme wenn
die endmarkierung verloren geht, aber wenn du 200 zeichen überträgst
(davon 199 zeichen nutzdaten, eines länge oder endmarke) ist bei der
endmarkierung-lösung nur das letzte zeichen kritisch. der controller
kann auch ggf. sofort anhand einer prüfsumme feststellen, daß es einen
übertragungsfehler gab, während man bei einer vorgegebenen länge erst
auf ein timeout warten muß. großer nachteil: funktioniert nicht bei
unbekannten binären daten, weil das als endmarkierung verwendete zeichen
hier auch in den nutzdaten vorkommen kann. ohne umkodierung (entfernen
des endmarkierungs-zeichen aus den nutzdaten) gehts hier nur mit
bekannter länge.
Eine eigene Frage?
Dieser Thread ist über 16 Jahre alt.
Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.