Datum:
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
int main(void) { unsigned int c; char buffer[7]; int num=134; uint8_t Linein[10]; uint8_t j; /* * Initialize UART library, pass baudrate and AVR cpu clock * with the macro * UART_BAUD_SELECT() (normal speed mode ) * or * UART_BAUD_SELECT_DOUBLE_SPEED() ( double speed mode) */ uart_init( UART_BAUD_SELECT(UART_BAUD_RATE,F_CPU) ); /* * now enable interrupt, since UART library is interrupt controlled */ sei(); /* * Transmit string to UART * The string is buffered by the uart library in a circular buffer * and one character at a time is transmitted to the UART using interrupts. * uart_puts() blocks if it can not write the whole string to the circular * buffer */ uart_puts("String stored in SRAM\n"); /* * Transmit string from program memory to UART */ uart_puts_P("String stored in FLASH\n"); /* * Use standard avr-libc functions to convert numbers into string * before transmitting via UART */ itoa( num, buffer, 10); // convert interger into string (decimal format) uart_puts(buffer); // and transmit string to UART /* * Transmit single character to UART */ uart_putc('\r'); for(;;) { /* * Get received character from ringbuffer * uart_getc() returns in the lower byte the received character and * in the higher byte (bitmask) the last receive error * UART_NO_DATA is returned when no data is available. * */ 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) ) { Linein[ j++ ] = c; } if ( c & UART_FRAME_ERROR ) { /* Framing Error detected, i.e no stop bit detected */ uart_puts_P("UART Frame Error: "); } if ( c & UART_OVERRUN_ERROR ) { /* * Overrun, a character already present in the UART UDR register was * not read by the interrupt handler before the next character arrived, * one or more received characters have been dropped */ uart_puts_P("UART Overrun Error: "); } if ( c & UART_BUFFER_OVERFLOW ) { /* * We are not reading the receive buffer fast enough, * one or more received character have been dropped */ uart_puts_P("Buffer overflow error: "); } /* * send received character back */ uart_putc( (unsigned char)c ); } } } |
Datum:
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.
Datum:
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;
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 = uart_getc() ) != '\r'&& j < sizeof(Linein) )
{
uint8_t HighByte = c >> 8;
uint8_t LowByte = c;
Linein[ j++ ] = LowByte;
}
|
Datum:
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
c = uart_getc();
//Hier wird doch schon ein zeichen
//aus dem Puffer geholt somit fehlt doch schon
//ein zeichen
if ( c != UART_NO_DATA)
{
//Da ich ja vor der IF-Abfrage ja schon ein zeichen geholt habe
//Fehlt mir ja schon ein zeichen
Linein[ 0 ] = c ;
j = 1;
while( ( c = uart_getc() ) != '\r'&& j < sizeof(Linein) )
{
Linein[ j++ ] = LowByte;
}
|
Datum:
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)
Datum:
> 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.
j = 0; 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 */ c = uart_getc(); Linein[ j++ ] = c; if( (c != '\r') ) { j = 0; } } |
Datum:
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?
Datum:
>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
Datum:
Uwe schrieb: > Aber das umzusetzten habe ich meine Probleme,Deshalb fragte ich ja hier. Wieso machst du es nicht einfach so? (Beispielcode)
int n, c; n = 0; for (;;) { c = uart_getc(); if (!(c & UART_NO_DATA)) { Linein[n++] = c; if ((c & 0xFF) == '\r') { break; } } } |
Sobald die Schleife verlassen wurde, steht alles, bis einschließlich des Returns, im Array.
Datum:
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,
Datum:
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?
Datum:
also void Getin(void ) wird einmal aufgerufen und soll nun die 2 Bytes empfangen aber leider klappts nich
void Getin(void ) { uint8_t Linein[10]; uint8_t j; unsigned int c; c = uart_getc(); if ( c & UART_NO_DATA ) { /* * no data available from UART */ } else { /* * new data available from UART * check for Frame or Overrun error */ if( (c != '\r') ) { j = 0; uart_puts (Linein[ 0]); uart_puts (Linein[ 1]); } else { Linein[ j++ ] = c; } } } |
Datum:
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.
Datum:
Scheinbar haben doch viele schwierigkeiten bei der benutzung der Lib auch hier. Dieter
Datum:
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)
char uart_getc_wait() { unsigned int c; do { c = uart_getc(); } while( c & UART_NO_DATA ); return c; } |
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.