Ich nutze die UAART von Peter Fleury aber mit dem uart_getc komme ich
nicht richtig klar es werden immer zeichen verschluckt.
Das Senden klappt wubderbar.
wenn ich den Empfang auf Polling umstelle bekomme ich jedes zeichen was
Empfangen wird.
Vielleicht könntet ihr mir sagen wie ihr das macht mit dieser Lib,
ich bin noch Anfänger.
mfg
1
intmain(void)
2
{
3
unsignedintc;
4
charbuffer[7];
5
intnum=134;
6
7
uint8_tLinein[10];
8
uint8_tj;
9
10
/*
11
* Initialize UART library, pass baudrate and AVR cpu clock
Uwe schrieb:> Vielleicht könntet ihr mir sagen wie ihr das macht mit dieser Lib,
Mit Sorgfalt!
> c = uart_getc();> //Hier wird doch schon ein zeichen> //aus dem Puffer geholt somit fehlt doch schon> //ein zeichen> if ( c & UART_NO_DATA )> {> /*> * no data available from UART> */> }> else> {> /*> * new data available from UART> * check for Frame or Overrun error> */> j = 0;> while( ( c = uart1_getc() ) != '\r'&& j < sizeof(Linein)
wieso auf einmal uart1_getc (mit der Betonung auf 1!). Von der 1 weißt
do doch an dieser Stelle gar nicht, ob da ein Zeichen gekommen ist oder
nicht. Weiter oben hast du die andere UART befragt, ob sie was hat. Und
die hat nicht mit UART_NO_DATA geantwortet und daher weißt du das DIESE
Uart ein Zeichen vorrätig hat. Aber von der UART 1 weißt du an dieser
Stelle erst mal nichts, bzw. du müsstest auch hier testen, ob da
UART_NO_DATA gesetzt ist oder nicht.
Bei JEDEM Aufruf von getc() kann die Lib mit UART_NO_DATA antworten!
Dein Benutzer kann angefangen haben zu tippen und noch ehe er Return
tippt, geht er aufs Klo. Die Fleury Lib liefert dann 20 Minuten lang bei
jedem getc() Aufruf UART_NO_DATA, denn sie hat ja wirklich nichts
gekriegt. Die lügt dich ja nicht an, oder schneidet sich was aus den
Rippen. Erst dann, wenn der Benutzer zurück kommt und auf Return haut,
dann liefert den auch das getc() ohne gesetztes UART_NO_DATA Bit.
oje ein Fehler hat sich eingeschlichen,
in seiner Doku steht ja dazu;
Returns: lower byte: received byte from ringbuffer
higher byte: last receive error
Müsste ich das dann nicht so machen, denn ich brauche doch nur die daten
die im LowByte sind.
ich sitz da nun schon stunden dran und bekomme den empfang einfach nicht
hin.
wie macht ihr denn das.
mfg
c = uart_getc();
uint8_t HighByte = c >> 8;
uint8_t LowByte = c;
ich bekomme jetz meine zeichen bis das Return kommt, aber die hälfe
fehlt.
scheinbar nutzten diese Lib nich viele.
vielleicht kann mir einer von euch noch weiterhelfen der diese LIB auch
nutzt
mfg
1
c=uart_getc();
2
//Hier wird doch schon ein zeichen
3
//aus dem Puffer geholt somit fehlt doch schon
4
//ein zeichen
5
if(c!=UART_NO_DATA)
6
{
7
8
//Da ich ja vor der IF-Abfrage ja schon ein zeichen geholt habe
Uwe schrieb:> ich bekomme jetz meine zeichen bis das Return kommt, aber die hälfe> fehlt.> scheinbar nutzten diese Lib nich viele.
Kein Wunder.
Dein Hauptproblem besteht immer noch
> while( ( c = uart_getc() ) != '\r'&& j < sizeof(Linein) )> {> Linein[ j++ ] = LowByte;> }
Hast du das hier nicht gesehen?
Beitrag "Re: uart_getc von Peter Fleury"
Die Library kann nichts dafür, dass du sie nicht benutzen kannst. Das in
der Fleury Lib enthaltene uart_getc() ist nun mal kein wartendes getc().
Du kannst dieses Faktum ignorieren, solange du willst. Das ändert nichts
daran, dass es so ist.
(Allerdings ist es trivial, sich eine uart_getc_wait() Funktion zu
machen, die tatsächlich solange Däumchen dreht, bis dann tatsächlich ein
Zeichen über die UART reinkommt. Der Weg uart_getc() -> uart_getc_wait()
ist trivial. Die Umkehrung aber nicht. Und genau aus dem Grund ist in
der Fleury Lib ein nicht wartendes getc() enthalten und nicht anders
rum)
> Die Library kann nichts dafür, dass du sie nicht benutzen kannst.
Deshalb habe ich ja gefragt wie mann es richtig macht,
Aber durch das erste c = uart_getc(); geht mir doch schon ein zeichen
verloren oder irre ich mich da.
Uwe schrieb:> Deshalb habe ich ja gefragt wie mann es richtig macht,> Aber durch das erste c = uart_getc(); geht mir doch schon ein zeichen> verloren oder irre ich mich da.
Richtig, deshalb rufe uart_getc auch nur einmal auf! Teste ob
UART_NO_DATA gesetzt ist und wenn nicht, dann nutze eben genau dieses
einmal erhaltene c! Wo ist das Problem?
>Wo ist das Problem?
es werden 2 Byte gesendet und das return zeichen,
die ersten beiden Bytes sollten dann in Linein[0] und Linein[1] .
aber ich muss doch auch überprüfen bis das Return zeichen kommt,
oader andersrum es soll sollange in Linein[] geschrieben werden bis das
return zeichen kommt.
Aber das umzusetzten habe ich meine Probleme,Deshalb fragte ich ja hier.
mfg
Michi schrieb:> Uwe schrieb:> Aber das umzusetzten habe ich meine Probleme,Deshalb fragte ich ja hier.>> Wieso machst du es nicht einfach so? (Beispielcode)> Sobald die Schleife verlassen wurde, steht alles, bis einschließlich des> Returns, im Array.
Vielen Dank,
Leider funktioniert das bei mir auch nicht,
Uwe schrieb:> Leider funktioniert das bei mir auch nicht,
Was funktioniert nicht?
Zeig doch einfach mal deinen aktuellen Code und schreibe, was du
erwartest und was tatsächlich geschieht. Woran machst du fest, dass es
nicht funktioniert?
Uwe schrieb:> also void Getin(void ) wird einmal aufgerufen und soll nun die 2 Bytes> empfangen aber leider klappts nich
Wie soll denn das bei EINEM Aufruf ZWEI Bytes empfangen?
Da ist keine Form einer Schleife oder dergleichen in deinem Code. EIN
Aufruf von uart_gets(), EIN empfangens Zeichen (wenn überhaupt).
ABer ich seh schon. Dz hast dich einfach nur schleicht ausgedrückt, denn
natürlich existier die Schleife. Sie ist beim Aufrufer.
...
while( 1 ) {
GetIn();
}
und damit wird dann GetIn tatsächlich öfter aufgerufen und wenn es etwas
zu tun gibt, dann macht GetIn das auch.
Soweit ist das OK. Großes Lob. Du bist auf dem richtigen Weg.
Du hast nur etwas übersehen.
Und zwar deine Variablen j und LineIn.
Das sind lokale Variablen. Und als solche existieren sie nur, während
die Funktion arbeitet. Geht der Programmfluss aus der Funktion heraus,
dann wird j zerstört. Wird die Funktion durch den nächsten Aufruf erneut
betreten, dann wird ein NEUES j angelegt, das nichts mit dem j vom
vorhergehenden Aufruf zu tun hat. Das ist eine neue Variable!
Das bedeutet aber auch, du kannst derartige Variablen nicht dazu
benutzen, um dir Werte von einem Aufruf zum nächsten zu merken!
Aber es gibt einen Ausweg daraus. Tatsächlich gibt es 2 Auswege.
* du könntest LinIn und j als globale Variablen anlegen.
dann sind sie unabhängig vom Funktionsaufruf. Die Funktion kann etwas
tun, oder auch nicht und die Programmausführung kann die Funktion
verlassen. Wird GetIn das nächste mal aufgerufen, dann haben diese
Variablen immer noch denselben Wert und du kannst dort weiter machen
wo du aufgehört hast. Zum Beispiel eben damit, das nächste
Zeichen dir zu holen (sofern eines existier) und es in LineIn zu
speichern
* oder aber du kannst die beiden Variablen als 'static' Variablen
ausführen. Dann werden sie ebenfalls von diesem "Variablen werden
bei Verlassen einer Funktion zerstört" - Dingens ausgenommen und
überleben, bis die Funktion erneut betreten wird.
So - your choice.
Dieter schrieb:> Scheinbar haben doch viele schwierigkeiten bei der benutzung der Lib> auch hier.
Eigentlich ist die ganz einfach zu benutzen.
Aber viele gehen von falschen Voraussetzungen aus. Das uart_getc() in
der Fleury Lib ist ein nicht wartendes getc(). Das hat den Vorteil, dass
es wunderbar in das übliche Konzept von "Wir warten auf niemanden und
nichts" passt. Nur muss man dieses Konzept dann aber auch programmieren
können.
Sich selbst damit ein wartendes getc() zu machen, ist trivial (wenn man
Fehlerbehandlung weg lässt)
1
charuart_getc_wait()
2
{
3
unsignedintc;
4
5
do{
6
c=uart_getc();
7
}while(c&UART_NO_DATA);
8
9
returnc;
10
}
und schon kann er seine getline mit dieser Hilfsfunktion so
programmieren, wie er das am Anfang vorhatte. (Ich hab die Funktion
jetzt absichtlich in der 'ausführlichen Form geschrieben. Persönlich
würde ich das für mich 'dichter' schreiben. Also: Kein Grund das jetzt
zu reklamieren)
Was natürlich auch ein Problem ist: Das Vorwissen ist meistens viel zu
mangelhaft. Viele glauben dann: "Ja, da nehm ich einfach etwas
'Fertiges', dann hab ich keine Probleme.". Falsch. Auch wer auf
vorgefertigte Baukästen setzt, muss immer noch wissen, wie die Teile
funktionieren. Immerhin muss er ja die Einzelteile zusammenschrauben.