Mh, da spuckt mir AVRCalc nen Baudratenfehler von 0.16% aus..das sollte keine Probleme machen.
Beschaltung von MAX232 passt, Ground verbunden und Kabel nicht zu lang?
Ansonsten muesste man mal einen Blick auf die Software werfen.
Werbung
Mh, da spuckt mir AVRCalc nen Baudratenfehler von 0.16% aus..das sollte keine Probleme machen.
Beschaltung von MAX232 passt, Ground verbunden und Kabel nicht zu lang?
Ansonsten muesste man mal einen Blick auf die Software werfen.
Nam et ipsa scientia potestas est..
Eine kalte oder nicht vollständig leitende Lötstelle oder ein Kabelbruch wäre auch eine Möglichkeit. Ansonsten hat der Wastel schon Recht, da hilft nur ein Blick in die Software. Ist das Zeug irgendwie aus einer Firma oder Ähnlichem? Also dass das nicht öffentlich gemacht werden darf?
Sonst hättest du auch einfach hier im Forum Fragen können, ohne Kohle locker zu machen.
Grüße,
Daniel
Sind in gewisser Weise schon sensible Daten. Daher ungern veröffentlichen.
Für mich hört sich das etwas nach Pufferüberlauf an.
Addressieren die verwendeten Pointer wirklich nur die reservierten Bereiche, oder könnte auch aus Versehen ein Bereich dahinter angesprochen werden?
Beispiel: Puffergröße 128 Byte, Pointer hat den Wert 130!
Dann wird eine nachfolgende Variable überschrieben was nicht gut sein kann!
Werden Daten vom PC zum Mega 8 gesendet, oder umgekehrt, oder beides?
Wie ist die Sende bzw. Empfangsroutine angelegt?
Polling oder Interrupt?
Ich mach da gerne Empfangsinterrupts um jeweils ein Byte in einem Puffer abzulegen.
Im Hauptprogramm wird dann immer wieder geschaut, ob in dem Puffer was Neues drin ist.
( Schreib / Lesezeiger oder Marker = Bit Variable ).
Beim Senden wird dann auch immer wieder ein Puffer beschrieben und dieser Puffer dann per Interrupt byteweise versendet.
Wenn die Puffer nicht zu klein sind und der µC genügend Zeit zu Abarbeitung hat, macht das eigentlich keine Probleme.
Ich Merge mit diesem Prinzip 4 MiDi Eingänge ( 31250 Bit/s ) auf einen Ausgang zusammen. Allerdings mit einem ATMEGA1280 an 16MHz.
Um den Controller nicht auszubremsen würde ich keine! delay_ms Aufrufe für Zeitschleifen verwenden, sondern Variablen im einem Timer Interrupt hoch bzw. runter zählen lassen.
Diese Puffer sind im Prinzip String Variablen, da sie auch im Interrupt behandelt werden müssen sie Volatile sein.bzw. wo diese Puffer festgelegt werden?
volatile unsigned char uc_receivepuffer[128]; // Wäre ein Puffer mit 128Byte Speicherkapazität.
Bei mir schaut dann die komplette Initialisierung für den Empfangspuffer so aus ( CodeVision AVR! )Initialisierung des USART muss natürlich auch noch gemacht werden.Code:// USART Receiver buffer #define RX_BUFFER_SIZE 514 volatile char rx_buffer[RX_BUFFER_SIZE]; #if RX_BUFFER_SIZE<256 unsigned char rx_wr_index,rx_rd_index,rx_counter; #else unsigned int rx_wr_index,rx_rd_index,rx_counter; #endif // This flag is set on USART Receiver buffer overflow bit rx_buffer_overflow; // USART Receiver interrupt service routine interrupt [USART_RXC] void usart_rx_isr(void) { char status,data; status=UCSR0A; data=UDR0; if ((status & (FRAMING_ERROR | PARITY_ERROR | DATA_OVERRUN))==0) { rx_buffer[rx_wr_index]=data; if (++rx_wr_index == RX_BUFFER_SIZE) rx_wr_index=0; //Diese Zeile setzt den Pointer am Pufferende wieder auf 0 if (++rx_counter == RX_BUFFER_SIZE) //Diese Zeile setzt das Flag für einen Overflow { rx_counter=0; rx_buffer_overflow=1; }; }; }
Die Daten aus diesem Puffer kann man sich dann mit getchar Byteweise abholen.
Getchar wird im Main Loop natürlich nur dann aufgerufen, wenn auch tatsächlich Daten im Puffer sind.Code:#ifndef _DEBUG_TERMINAL_IO_ // Get a character from the USART Receiver buffer #define _ALTERNATE_GETCHAR_ #pragma used+ char getchar(void) { char data; while (rx_counter==0); data=rx_buffer[rx_rd_index]; if (++rx_rd_index == RX_BUFFER_SIZE) rx_rd_index=0; #asm("cli"); --rx_counter; #asm("sei"); return data; } #pragma used- #endif
Das Byte steht nun in der Variable c zur weiteren Verarbeitung.Code:if(rx_counter>0) { //Ein Byte wird geschrieben c=getchar(); }
Die Code Beispiele sind für CodeVision AVR, bei AVR GCC wird das eventuell etwas anders aussehen.
Kann es sein, dass dieser Pufferbereich dann auch beim Programmieren des uC angegeben werden muss?
Kann es sein, dass wenn dieser Bereich im Mikrocontroller falsch (garnicht) gewählt ist, der oben genannte Fehler auftritt?!
Ich habe nämlich im Galep noch ein Feld Pufferbereich Start-Stop.
Ich denke, dass der Fehler eher hier liegt...?!?
Geändert von Azzidodabass (17.10.2012 um 07:19 Uhr)
Ich würd mal sagen ja. Es ist aber auch ein Softwareproblem.Kann es sein, dass wenn dieser Bereich im Mikrocontroller zu klein gewählt ist, der oben genannte Fehler auftritt?!
Der GALEP ist doch eigentlich nur ein Programmer, um ein fertiges Maschinencode File in den Controller zu übertragen. Was hat der mit dem compilierten Code zu tun?Ich habe nämlich im Galep noch ein Feld Pufferbereich Start-Stop.
Du schreibst ja noch nicht mal in welcher Programmiersprache Du den Controller programmierst.
Der Controller muss so viel Rechenzeit frei haben, das er diesen Puffer abarbeitet bevor er vollaufen kann.
Wenn Du deinen Controller in unsinnigen Warteschleifen oder beim Pollen ewig auf irgendwelche Ereignisse warten lässt, läuft ja in dieser Zeit der Datenempfang im Interrupt weiter. - Wenn Du das so gelöst hast.
Irgendwann ist dann der Ringpuffer voll und wird im günstigsten Fall einfach von vorne her überschrieben = Datenverlust.
Wenn Deine Software nichts taugt wird eventuell auch ein anschließender Speicherbereich überschrieben, der gar nicht für die Pufferung von dieser Daten vorgesehen war, sondern Variablen oder sonstwas enthält. Im schlimmsten Fall wird Dir der Stack überschrieben und der Controller findet die Rücksprungadressen aus Subroutinen und Interrupts nicht mehr und hängt sich auf.
Das Brachialmittel in solchen Fällen ist, einen Watchdog einzusetzen, wenn das von Deiner Anwendung her geht.
Der Controller muss dabei immer wieder mal das Kommando "WDR" bekommen. Kriegt er das nach einer einstellbaren Zeit nicht, führt er einen Reset aus.
Bei einem Datenlogger dürfte das weniger ein Problem sein, bei einer Schrittmotorsteuerung kanns eine sein.
Ich hatte einmal so ein Problem mit einer FAT zum Schreiben auf einer SD Karte.
Die Karte wird immer in Blöcken zu 512Byte beschrieben. Das dauerte aber so lange, das bei 38400Bit/s der maximale Pufferbereich von 280Byte schon voll war, bevor die Daten daraus vollständig ausgelesen werden konnten. - Folge Datenverlust.
Da die Schreiberei auf die SD Karte nicht beschleunigt werden konnte, war da Softwaretechnisch nichts zu machen.
Erst als ich diesen Puffer auf 520Byte durch einen größeren Controller aufgemotzen konnte, lief die Beschreiberei fehlerfrei ohne Datenverlust.
Es wäre dann schon mal sinnvoll, das Du hier zumindest mal deine Routinen für die Verarbeitung der seriellen Daten offenlegst, weil die meisten Leute hier Ihre Glaskugel verlegt haben. Schmeiss auch wo möglich alle delay_xy Befehle raus. Wenn was gepollt wird, warte nicht ewig sondern mach da irgendwo ein Timeout in die Schleife mit rein. Halte alle Interruptroutinen so kurz wie möglich.
Sehr viel mehr Tipps kann ich Dir ohne Blick auf den Quellcode eigentlich nicht mehr geben.
Lesezeichen