Hallo! In gutgläubiger Marnier habe ich folgenden Code "geschrieben". Leider sind die ausgegebenen Strings (ab dem zweiten) nicht vollständig. Der FIFO arbeitet jedenfalls tadellos. Sieht jemand handwerkliche Fehler? int main(void) { init_stk600(); while(1) { if ((UART0_RxHead != UART0_RxTail) && (uart0_complete == 0))readout_uart0(); if (uart0_complete == 1) uart0_ready(); } } void readout_uart0 (void) { while (!(UART0_RxHead == UART0_RxTail) && (uart0_complete == 0)) { uart0_newchar = uart0_getc(); if ((uart0_newchar != '\r') && (uart0_count < UART_RX_BUFFER_SIZE )) { uart0_array[uart0_count] = uart0_newchar; uart0_count++; } else { uart0_array[uart0_count] = '\0'; uart0_count = 0; uart0_complete = 1; } } } void uart0_ready(void) { uart0_puts(uart0_array); //oder den String anders bearbeiten uart0_complete = 0; }
Ich kann dem µC einen ununterbrochenen String mit 200 Zeichen schicken, er sendet ihn fehlerlos zurück. Nur wenn die FIFO ins Spiel kommt, hakts. Spricht dass nicht für die Quali des intOC?
Stephan schrieb: > Ich kann dem µC einen ununterbrochenen String mit 200 Zeichen schicken, > er sendet ihn fehlerlos zurück. Nur wenn die FIFO ins Spiel kommt, > hakts. > Spricht dass nicht für die Quali des intOC? Nö, nur für Glück. Nimm einen anständige Taktquelle, ansonsten ist jede Fehlersuche vergebens.
Fertig! Stk600 sei dank ganz einfach, Ergebnis: gleiches Verhalten.
Stephan schrieb: > Fertig! > Stk600 sei dank ganz einfach, Ergebnis: gleiches Verhalten. Na, dann hast jetzt eine Fehlerquelle ausgeschlossen. Ist doch ein Schritt in die richtige Richtung :)
Eumel schrieb: > Ist doch ein > Schritt in die richtige Richtung :) Ha! Den Satz hab ich vor zwei Wochen schon mal gehört! (Da wurd ich Papa.) Ich hab das Gefühl, das wird heut nix mehr mit meiner UART. Zu viel BabyBier.
Erläuterung: Die Ausgabe auf die direkte Eingabe des ABC (abgeschlossen mit \r) lautet abcdefghijklmnopqrstuvwxyz<\n> abcvwxyz <\n> abdefghijklmnopqrstuvwxyz<\n> abcvwxyz<\n> abcdefghijklmnopqrstuvwxyz<\n>
Ist dein Ringpuffer zu klein? Gruß Oliver
Stephan schrieb: > Erläuterung: > > Die Ausgabe auf die direkte Eingabe des ABC (abgeschlossen mit \r) > lautet Gibst du das händisch ein, oder werden die Texte per Programm eingespielt?
Karl Heinz Buchegger schrieb: > Gibst du das händisch ein, oder werden die Texte per Programm > eingespielt? Die sende ich per HTerm in direkter Folge: ABC...XYZ<13>ABC...XYZ<13>ABC...XYZ<13>
Achso: mit der Größe des Ringbuffers habe ich schon gespielt, selbst wenn er 200Bytes groß ist, das gleiche.
Stephan schrieb: > Karl Heinz Buchegger schrieb: >> Gibst du das händisch ein, oder werden die Texte per Programm >> eingespielt? > > Die sende ich per HTerm in direkter Folge: > ABC...XYZ<13>ABC...XYZ<13>ABC...XYZ<13> Also händisch. (Es geht darum abzuschätzen, ob es irgendwo eine race condition ist, die aufgrund Übertragungsgeschwindigkeit sichtbar wird. Denn wenn während des uart0_puts(uart0_array); der Sender weitersendet, dann muss die FIFO das aufnehmen können, weil ja keiner in dieser Zeit die Zeichen aus der FIFO abholt. Mit händischer Eingabe ist das kaum zu machen. Aber ein Sendeprogramm schafft das natürlich mit links, wenn die FIFO zu klein dimensioniert ist. Wie groß ist die FIFO eingestellt? (in dem Codeausschnitt seh ich erst mal nichts. Kannst du mal alles posten?)
Noch was: Wenn ich einen GPS-Empfänger anschließe, der einen String mit zwei Stringzeilen sendet, nämlich $GPGGA,120035.000,2400.0000,N,12100.0000,E,0,00,0.0,0.0,M,0.0,M,,0000*6C <\r><\n> $GPVTG,000.0,T,,M,000.0,N,000.0,K,N*02<\r><\n> (danach ist 1s Pause) kommt als Antwort zuerst $GPGGA,120040.000,2400.0000,N,12100.0000,E,0,00,0.0,0.0,M,0.0,M,,0000*6E <\n> <\n> und anschließend nur noch $G$GPGGA,120041.000,2400.0000,N,12100.0000,E,0,00,0.0,0.0,M,0.0,M,,0000* 6F<\n> <\n>
uart.h #define UART_RX_BUFFER_MASK ( UART_RX_BUFFER_SIZE - 1) #define UART_TX_BUFFER_MASK ( UART_TX_BUFFER_SIZE - 1) #define UART0_TRANSMIT_INTERRUPT USART0_UDRE_vect #define UART0_RECEIVE_INTERRUPT USART0_RX_vect #define UART0_STATUS UCSR0A #define UART0_CONTROL UCSR0B #define UART0_DATA UDR0 #define UART0_UDRIE UDRIE0 #define UART_RX_BUFFER_SIZE 300 #define UART_TX_BUFFER_SIZE 300 ISR(UART0_RECEIVE_INTERRUPT) { unsigned char tmphead; unsigned char data; unsigned char usr; unsigned char lastRxError; usr = UART0_STATUS; data = UART0_DATA; lastRxError = (usr & (_BV(FE0)|_BV(DOR0)) ); tmphead = ( UART0_RxHead + 1) & UART_RX_BUFFER_MASK; /* calculate buffer index */ if ( tmphead == UART0_RxTail ) { lastRxError = UART_BUFFER_OVERFLOW >> 8; /* error: receive buffer overflow */ } else { UART0_RxHead = tmphead; /* store new index */ UART0_RxBuf[tmphead] = data; /* store received data in buffer */ } UART0_LastRxError = lastRxError; }
so so 300 Bytes Puffer und dann den Index per and berechnen wollen ?
Stephan schrieb: > > #define UART_RX_BUFFER_SIZE 300 > #define UART_TX_BUFFER_SIZE 300 Wenn du schon bei Fleury Code klaust (wogegen ich nichts habe), dann musst du das auch konsequent machen. Im Original heißt es nämlich
1 | /** Size of the circular receive buffer, must be power of 2 */
|
2 | #ifndef UART_RX_BUFFER_SIZE
|
3 | #define UART_RX_BUFFER_SIZE 32
|
4 | #endif
|
und das 'must be a power of 2' steht da nicht ohne Grund.
Oh. Geändert auf 200. Es hat sich was an der Ausgae getan: $GPVTG$GPGGA,095701.060,5417.2093,N,01006.3587,E,1,09,1.0,36.1,M,41.8,M, ,0000*60<\n>
Karl Heinz Buchegger schrieb: > und das 'must be a power of 2' steht da nicht ohne Grund. Grübelgrübel.. das hab ich jetzt flux mit "Vielfachem von zwei" übersetzt. Stimmt das nicht?
gemeint ist damit 2 hoch n , 2^n. Das sind die Zahlen 2,4,8,16,32,..
Stephan schrieb: > In gutgläubiger Marnier habe ich folgenden Code "geschrieben". Karl Heinz Buchegger schrieb: > Wenn du schon bei Fleury Code klaust (wogegen ich nichts habe) Dann sollte er zumindest sagen wo er den Code herhat und nicht behaupten ihn selbst geschrieben zu haben. Das hätte dir und anderen dann ggf. einiges an Zeit erspart.
Udo Schmitt schrieb: > Dann sollte er zumindest sagen wo er den Code herhat und nicht behaupten > ihn selbst geschrieben zu haben. Nicht ohne Grund habe ich die Anführungszeichen gemacht. Dass das bei Fleury geklaut ist -dacht ich- sieht man. Update: mein geklauter Code funktioniert nun tadellos. Aber Frage zum Handwerk: mir gefällt selbst nicht, die Abfrage, ob der Buffer teilgefüllt ist, in der mainloop unterzubringen. Macht das Sinn, diese ständig und unsichtbar durch einen Timer zu machen?
Stephan schrieb: > Nicht ohne Grund habe ich die Anführungszeichen gemacht. > Dass das bei Fleury geklaut ist -dacht ich- sieht man. Scroll zum Eröffnungsposting. Woran soll man da erkennen, dass du den Fleury Code umgearbeitet hast. Das einzige was da steht ist, dass deine FIFO tadellos arbeitet, was ja dann wohl doch nicht der Fall war. Warum hast du eigentlich den Fleury Code umgearbeitet? So wie ihn Peter veröffentlicht hat, funktioniert der tatsächlich wunderbar. Eventuell muss man einen neueren Prozessor einarbeiten, aber mehr muss man nicht tun, um eine erstklassige und gut funktionierende UART zu haben- > Aber Frage zum Handwerk: mir gefällt selbst nicht, die Abfrage, ob der > Buffer teilgefüllt ist, in der mainloop unterzubringen. Macht das Sinn, > diese ständig und unsichtbar durch einen Timer zu machen? Was soll denn der Quatsch schon wieder? Dein GPS ballert dir 1 mal pro Sekunde 80 Zeichen bei 4800 Baud rüber. Das kann eine 128-er FIFO locker zwischenspeichern und wahrscheinlich brauchts noch nicht mal das. Denn wenn das Programm die Daten nicht schneller wieder lowird (weitergibt, verarbeitet) als sie vom GPS geliefert werden, dann hilft auch die größte FIFO nix. Das einzige was mir nicht gefällt, das ist dass du da hemmungslos auf Head und Teil in main zugreifst. Das hat niemanden zu interessieren, wie das UART MOdul seine Zeichen verwaltet. Maximal gibt es im UART MOdul eine Funktion mit Namen "cAvailable" (das c ist das Pendant zum c in getc), die die main() benutzen kann. Aber eigenttlich ist die Variante die Fleury vorgegeben hat eine gute Lösung, dass die getc Funktionen einen Returnwert hat, aus dem man ablesen kann, ob ein Zeichen vorliegt oder nicht.
@Karl Heinz Buchegger damit kann der Thread ja geschlossen werden - der Fehler wurde gefunden.
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.