Hallo, ich versuche gerade eine Lüftersteuerung zu schreiben, die per Telnet den aktuellen Zustand(Temperatur/Lüfterdrehzahl) ausgibt und Einstellungen für die Regelung entgegennimmt. Zur Ausgabe der Daten möchte ich per UART einfach Zeilenweise den Text senden. Da ich auch Zahlenwerte aus Variablen mitsenden möchte, habe ich mich für sprintf() entschieden. Die Ausgabe läuft so ab: char text[80]; //uart_putc(12);//FormFeed. Clearen des Terminals sprintf(text,"\n\rWakue-Steuerung Version 0.91\n\r\n\r"); uart_putstring(text); sprintf(text,"Temperaturen:\n\r"); uart_putstring(text); Das Uart ist Interruptbasierend und ich hab die Funktionen von Roboternetz (http://www.roboternetz.de/wissen/index.php/UART_mit_avr-gcc#Mit_Interrupts). Dahinter steht ein FIFO Buffer, in den die zu sendene Zeichenkette geschoben wird und dann nach und nach gesendet wird. Ich habe nur kommischerweise sehr Merkwürdiges Verhalten. Einige Teile werden problemlos ausgegeben, aber manchmal kommt nur Müll. Es ist auch teilweise so, dass der erste Teil wunderbar am Terminal ankommt und 2 Zeilen später ist die Formatierung hin(teilweise mit Zeichen, die nicht da sein sollten) Ich kann dabei aber kein Muster erkennen. Z.B. erzeugt sprintf(text,"Drehzahlregelung\n\r"); uart_putstring(text); sprintf(text,"Bottom: 30C = 50p \n\rUpper: 60C = 100p\n\r"); im moment gerade "Botto00p00Wakue-Steuerung Version 0.91) pDrae" und andere Zeilen produzieren keinen output. Bin ich vielleicht auf dem flaschen Weg? Gibts eine andere, einfachere Lösung? Oder sollte ich das Uart nicht Interruptgesteuert machen? Danke schonmal für jeden Tipp, denn mir gehen langsam die Ideen aus. Christian
baudrate richtig? hast du krasse störsender neben deiner leitung?
Bautrate ist richtig Störsender.... hmm meinen Rechner, sonnst nichts Christian
Ich habe die UART-Routinen nur überflogen, aber kann es sein, dass der FIFO zu klein ist? Soll heissen, kann es sein, dass du schneller Texte in den Buffer schreibst als gesendet werden können? Ich würde zum Testen mal vor jedem 'uart_putstring(text)' eine Warteschleife einbauen.
sehr guter Tipp ... ich hab mal die Bufferlänge hochgesetzt und sieheda: die Fehler verschwinden. Nur muss ich jetzt meine uart routine umändern, denn ich kann ja nicht die Bufferlänge auf 300 bis 400 byte setzen. Damit blockiere ich doch dann den ganzen Ram,oder sehe ich das falsch? vielen Dank Christian
Ich schätze mal, dein 'uart_putstring()' ist die 'uart_puts()' aus den UART-Routinen. In dieser wird 'uart_putc' verwendet, um die einzelnen Zeichen des Strings in den FIFO zu schreiben. 'uart_putc' gibt einen wert zurück, der angibt, ob das Zeichen in den FIFO geschrieben wurde oder ob der Puffer voll ist (steht so im Text). Dieser Wert wird aber nicht ausgewertet. Das funktioniert so nur mit kurzen Texten. Wenn du genügend RAM hast, würde ich den Puffer schrittweise vergrössern, bis es passt. 300 Byte weden wohl nicht gebraucht, denke ich. Ich tippe mal so auf 60 Byte. Alternativ kannst du natürlich den Return-Wert von 'uart_putc' auswerten und immer warten, bis der FIFO wieder frei ist. CB
Ja, meine uart_putstrin() ist die uart_puts() ich fand, dass muss man zur besseren Kennzeichnung umbennenen. Ich hab mich durch die Funktionen gekwühlt und hab das ganze anders gelöst. ich hab die uart_putc() um folgendes erweitert fifo_t *fn = &outfifo; while(fn->count >= fn->size){;}; also die Abbruchbedingung aus dem Fifo verwendet. so wartet er nun, wenn der Buffer voll ist. Ich denke, so ist es am einfachsten, da ich mir keine Gedanken über die Auswertung machen muss. Ich würd es ja auch im RN angeben, doch irgendwie hab ich keine Lust mich da jetzt erst groß anzumelden. Aber dir erstmal vielen Dank hast mein Wochenende gerettet :) Christian
> hast mein Wochenende gerettet :)
bitte bitte...
Ich hätte dass vielleicht so gemacht:
Die Zeile
int ret = fifo_put (&outfifo, c);
in 'uart_putc' ersetzt durch
int ret;
do
{
ret = fifo_put (&outfifo, c);
}
while (ret=0);
Sollte doch auch gehen, oder? Aber wenn deine Lösung funktioniert...
BC
also zu aller erst, ich will nicht besserwisserisch sein, nur zum Verständniss, aber ich glaube nicht, denn es wird immer zuerst einmal versucht das Zeichen in den Buffer zu schieben. Schlägt das fehl, ist das Zeichen verlohren. Es geht gut, bis einmal -1 zurückgeliefert wird. dann bricht die Schleife ab, und das Zeichen wird verworfen, oder? Also verhindert die Schleife zwar effektiv den Überlauf des Puffers, doch die Ausgabe wird dennoch verfälscht. Oder liege ich da gerade daneben? Christian
Es wird versucht, ein Zeichen in den FIFO zu schreiben ret = fifo_put (&outfifo, c); Wenn ret 0 ist, war der FIFO voll und es wird weiter versucht, bis ret nicht mehr 0 ist while (ret=0); ret wird 1, wenn das Zeichen im FIFO ist. Warum sollte das Zeichen verloren gehen? Ich denke nicht, das die Routine fifo_put das Zeichen ('c') ändert (weiss ich allerdings nicht, da ich fifo.h nicht kenne) CB
Ein Returnwert beim Senden ist Blödsinn, wer soll den denn auswerten ? Eine Sende-FIFO muß einfach immer solange warten, bis wieder Platz im Puffer ist. Nur so geht nichts verloren. Eine andere Möglichkeit wäre noch eine Funktion, die die aktuelle freie Pufferlänge zurückgibt. Dann kann man mit der Ausgabe solange warten, bis auch genügend Platz ist und die Zwischenzeit anderweitig nutzen. Trotzdem sollte die Sendefunktion warten, falls man sich mal mit der benötigten Paketlänge verschätzt hat. Lieber die Daten etwas später senden, als total falsch. Peter
> Eine Sende-FIFO muß einfach immer solange warten, bis wieder Platz im > Puffer ist. Nur so geht nichts verloren. Ja, aber genau dieses warten ist anscheinend nicht implementiert, was ich mit meinem Vorschlag nachholen wollte. Oder übersehe ich da irgendetwas?
Nabend ich glaub ich lag falsch. Ich bin davon ausgegangen, dass -1 zurückgeleifert wird, wenn die Funktion nicht erfolgreich war, deshalb hats keinen Sinn für mich gemacht. Hast also Recht. Habs aber so implementiert, wie oben und es läuft soweit. Wünsch euch noch ne gute Nacht und danke :) Christian
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.