Hi Im Titel steht eigentlich schon alles. Ich sende Daten an meinen ATMEGA32 über das Programm "COM Terminal". Dieser schickt genau die Zeichen wieder zurück. Wenn ich bei "Pause zwischen den Zeichen" 0ms einstelle und einen längeren Text sende, resettet sich der AVR selbstständig. Woran kann das liegen? Ciao Tobias
> Woran kann das liegen?
An deinem Program
meine Glaskugel ist leider in der reperatur. Kannst du auch den Quellecode mit schicken.
void uart_senden_einzeln(unsigned char zeichen) { loop_until_bit_is_set(UCSRA,UDRE); //Bereit zum Senden? UDR=zeichen; //Sende } void uart_senden(char *zeichen) { while (*zeichen) { uart_senden_einzeln(*zeichen); zeichen++; } } void uart_entleeren() { unsigned char dummy; while (UCSRA & (1<<RXC)) dummy=UDR; } unsigned char uart_empfangen(void) { while (!(UCSRA & (1<<RXC))); // warten bis Zeichen verfuegbar uart_senden_einzeln(UDR); //Sende Zeichen zur Bestätigung zurück return UDR; // Zeichen aus UDR an Aufrufer zurueckgeben } void uart_initialisieren(unsigned long baud_rate) { UCSRB |= (1<<TXEN|1<<RXEN); //UART TX und RX einschalten UCSRC |= (1<<URSEL)|(1<<UCSZ0|1<<UCSZ1); //Asynchron 8N1 unsigned long ubrr_calc; ubrr_calc=F_CPU/(16*baud_rate)-1; //Berechne Wert, aus dem der AVR die Baudrate generiert UBRRH=(unsigned char)(ubrr_calc>>8); //schreibe den oberen Teil des Werts in die Schnittstelle UBRRL=(unsigned char)(ubrr_calc); //schreibe den unteren Teil des Werts in die Schnittstelle uart_entleeren(); //Puffer entleeren, damit keine Störungen vor den Daten zu Fehlern führen } int main(void) { uart_initialisieren(19200); while (1) //Endlosschleife { uart_empfangen(); } return 1; }
> Marco Schwan (masterof)
Gar kein "*abo*"?
Woran merkst du, dass ein Reset erfolgt ist? Das Pgm sieht nicht so schlecht aus.
Ich habe noch eine LCD Routine und schalte 2 Relais. Dies tue ich, bevor dann der oben gepostete Code ausgeführt wird. Ich höre dann plötzlich ein Klacken und sehe wieder den Startbildschirm. An den Fuses kann sowas nicht liegen, oder? Ach ja, bei Bedarf poste ich auch den LCD Code usw...
> An den Fuses kann sowas nicht liegen, oder?
Eher nicht.
Ein Reset könnte durch Spikes in der Stromversorgung
ausgelöst werden.
Lass doch den ganzen Rundumkram (LCD, Relais) weg und
schreibe ein Testprogramm, dass nur die UART initialisiert
und empfangene Zeichen wieder zurückschickt. Hast du
dann immer noch die unerklärlichen Resets?
(Zur Kontrolle ob ein Reset erfolgt, kannst du ja
folgendes machen: Beim Einschalten eine Led einschalten,
etwas warten und Led wieder ausschalten).
Was ist Henne was ist Ei? Will sagen: Klackt das Relais als Folge des Reset oder kommt der Reset als Folge fehlerhafter Ansteuerung des Relais?
Relais klackt in Folge des Resets. Das Relais wird vor dem Beginn der seriellen Routinen angeschaltet und bleibt so "für immer". Eigentlich zumindestens. Beim Reset wird es dann natürlich abgeschaltet und aufgrund eine Warteeinrichtung, die ich beim Start drin hab, erst nach 1 sek. wieder angeschaltet. >Eher nicht. >Ein Reset könnte durch Spikes in der Stromversorgung >ausgelöst werden. > >Lass doch den ganzen Rundumkram (LCD, Relais) weg und >schreibe ein Testprogramm, dass nur die UART initialisiert >und empfangene Zeichen wieder zurückschickt. Hast du >dann immer noch die unerklärlichen Resets? >(Zur Kontrolle ob ein Reset erfolgt, kannst du ja >folgendes machen: Beim Einschalten eine Led einschalten, >etwas warten und Led wieder ausschalten). gute Idee! Probier ich bei Gelegenheit mal! An einem Portpin hängt ein Buzzer, der komplett ohne externe Beschaltung funktioniert (direkt am Portpin) - den kann ich dafür ja nehmen. Ciao Tobias
Das Programm zum Testen jetzt: #ifndef F_CPU #define F_CPU 16000000UL //Prozessor Frequenz in Hz #endif #include <avr/io.h> #include <util/delay.h> void uart_senden_einzeln(unsigned char zeichen) { loop_until_bit_is_set(UCSRA,UDRE); //Bereit zum Senden? UDR=zeichen; //Sende } void uart_senden(char *zeichen) { while (*zeichen) { uart_senden_einzeln(*zeichen); zeichen++; } } void uart_entleeren() { unsigned char dummy; while (UCSRA & (1<<RXC)) dummy=UDR; } unsigned char uart_empfangen() { while (!(UCSRA & (1<<RXC))); // warten bis Zeichen verfuegbar return UDR; // Zeichen aus UDR an Aufrufer zurueckgeben } void uart_initialisieren(unsigned long baud_rate) { UCSRB |= (1<<TXEN|1<<RXEN); //UART TX und RX einschalten UCSRC |= (1<<URSEL)|(1<<UCSZ0|1<<UCSZ1); //Asynchron 8N1 unsigned long ubrr_calc; ubrr_calc=F_CPU/(16*baud_rate)-1; //Berechne Wert, aus dem der AVR die Baudrate generiert UBRRH=(unsigned char)(ubrr_calc>>8); //schreibe den oberen Teil des Werts in die Schnittstelle UBRRL=(unsigned char)(ubrr_calc); //schreibe den unteren Teil des Werts in die Schnittstelle uart_entleeren(); //Puffer entleeren, damit keine Störungen vor den Daten zu Fehlern führen } //Ton Routine void ton(int laenge) //gibt einen Ton mit der Länge "lange" in ms aus { PORTA |= (1<<PA1); _delay_ms(laenge); PORTA &= ~(1<<PA1); } int main(void) { DDRA |= (1<<PA1);//Anschluss des Summers als Ausgang ton(10);//gibt kurz einen Ton aus, zur Bestätigung der Funktionstüchtigkeit uart_initialisieren(19200); int zeichen; while (1) //Endlosschleife { zeichen=uart_empfangen(); uart_senden_einzeln(zeichen); } return 1; } schmiert auch bei längeren Texten ab! Aber immer nur zu Beginn einer Übertragung. Dafür machmal gleich mehrfach (höhre mehrere der kurzen Töne)... Ciao Tobias
hab mal die Stromversorgung gezeichnet. Hoffe, das funktioniert, ansonsten im Anhang! Die 100nF Dinger sitzen alle direkt an den ICs. Die beiden Elkos sitzen aus Platzgründen irgendwo anders auf der Platine. Hier erstmal der Plan: 1N4004P .----------------------------. .-----|<------. | .------. | | __ | | .-----o Reset| | 12V= | | | | | | | | | --o----o-o---|7805|----o----o----------o------)-----o VCC | .---o--' | + | |____| | | + --- | | GND o-)-. | ### --- | --- ### 100nF --- ---| | | |--- --- --- | --- --- | ---| | | |--- | | | | | | | | AVCC o-' | | --o----o-------o-------o----o--------------o--o---o-o µC | '-o---. 100nF 100nF | |GND | | | 100nF| | 100nF| 1000µF 470µF | | | | | | | | | | | | | | | | | | | | | '------' | | | | | | | '-------------------------' (created by AACircuit v1.28.6 beta 04/19/05 www.tech-chat.de) Kann das auch am Max232N liegen? Oder an dessen Kondensatoren? Hab nämlich ein Max232N "geröstet" und ausgetauscht - können vielleicht beim Rösten die Kondensatoren einen Schlag weg bekommen haben? Aber wie könnte das wiederum einen Reset am AVR auslösen? Der MAX232N hat auch einen 100nF Kondensator zwischen VCC und GND und halt die 4 Stück 1µF Kondensatoren... Ciao Tobias
der Anhang... aber ich glaube, es geht schon!
unbeschreiblicher Rahul wrote: >> Marco Schwan (masterof) > > Gar kein "*abo*"? braucht man dank der neuen software nicht mehr. @Tobias H. änder mal bei deinem "normalen" Programm die Funktion uart_empfangen folgend um unsigned char uart_empfangen(void) { unsigned char a = ; while (!(UCSRA & (1<<RXC))); // warten bis Zeichen verfuegbar a = UDR; uart_senden_einzeln(a); //Sende Zeichen zur Bestätigung zurück return a; // Zeichen aus UDR an Aufrufer zurueckgeben } Weil die UART vom AVR mag es nicht 2 mal ausgelesen zu wrden hat mich mal 5 Stunden an Zeit gekosten das raus zufinden.
Kann das mal sein, daß durch die vielen schnellen Zeichen das Prog nicht mehr aus den Schleifen kommt und der Watchdog zuschlägt? Nur so ´ne Vermutung....
>Kann das mal sein, daß durch die vielen schnellen Zeichen das Prog nicht >mehr aus den Schleifen kommt und der Watchdog zuschlägt? Nur so ´ne >Vermutung.... Mit dem Watchdog hab ich mich noch nie beschäftigt - muss ich den nicht erst explizit einschalten, damit der arbeitet? Außerdem stürzt der Prozessor schon nach Sekundenbruchteilen ab. Ist aber auch verschieden. Manchmal reichen 5 Zeichen, manchmal auch erst 10. Wenn ich einzeln mit Pausen sende, passiert eben nichts. Außerdem müssten 19200 Baud für einen AVR bei 16Mhz zu packen sein, oder? >unbeschreiblicher Rahul wrote: >>> Marco Schwan (masterof) >> >> Gar kein "*abo*"? > > >braucht man dank der neuen software nicht mehr. > >@Tobias H. > >änder mal bei deinem "normalen" Programm die Funktion uart_empfangen >folgend um > >unsigned char uart_empfangen(void) >{ > unsigned char a = ; > while (!(UCSRA & (1<<RXC))); // warten bis Zeichen verfuegbar > a = UDR; > uart_senden_einzeln(a); //Sende Zeichen zur Bestätigung zurück > return a; // Zeichen aus UDR an Aufrufer zurueckgeben >} > > >Weil die UART vom AVR mag es nicht 2 mal ausgelesen zu wrden hat mich >mal 5 Stunden an Zeit gekosten das raus zufinden. Ich probiers mal... Ciao Tobias
Vieleicht produzierst du aber auch nen Stack überlauf? Zudem ist 16mhz auch kein sher Tauglicher Quarz für UART
Hmm nein, stürzt immer noch ab. Komisch nur, dass er das immer nur zu Beginn einer Übertragung tut... Wenn die dann erstmal läuft, dann gibs keine Probleme mehr. So lange, bis ich die nächste lange Kette sende. Es sei denn, ich warte lange. Dann stürzt er auch dabei dann wieder ab. Also sende ich 10 Zeichen, sag ich mal schmiert er nach 5 ab. Sende ich 100 Zeichen, schmiert er auch nach 5 ab, vielleicht nochmal nach 10, aber der Rest geht... Ich versuch mal weiter, die serielle Schnittstelle am STK500 in Gang zu bekommen. Dann könnte ich es damit mal testen... Kann mir irgendjemand sagen, warum die nicht geht? ;-) (Glaskugel repariert?) Ciao Tobias
>Vieleicht produzierst du aber auch nen Stack überlauf? >Zudem ist 16mhz auch kein sher Tauglicher Quarz für UART Wie finde ich das raus und behebe das?
ich würde das Programm einfach mal vereinfachen! Ohne Unteraufrufe etc. Also nur im Mainloop # warten auf ein Zeichen --> empfangen # warten bis sendepuffer leer --> senden
>>Zudem ist 16mhz auch kein sher Tauglicher Quarz für UART > Wie finde ich das raus und behebe das? Im Datenblatt ist am Unterpunkt "USART" eine Tabelle mit den Baudratenfehlern bei verschiedenen Taktfrequenzen zu finden. Laut der Liste hast du bei 16MHz und 19,2k eine Abweichung von 0,2%. Diese Abweichung sollte aber eigentlich noch im Rahmen sein.
>ich würde das Programm einfach mal vereinfachen! >Ohne Unteraufrufe etc. > >Also nur im Mainloop ># warten auf ein Zeichen --> empfangen ># warten bis sendepuffer leer --> senden Auch dieses Programm schmiert laufend ab... Kann das wirklich nicht irgendwie am MAX232N liegen? Einen Fehler/Defekt an der Stelle könnte ich mir nämlich erklären... Aber kann das einen Reset auslösen? P.S.: Bei meiner Stromversorgungsschaltung oben hab ich eins vergessen: Der 10k Pull-up am Reset-Pin ist natürlich vorhanden! Ciao Tobias
@Läubi
> Zudem ist 16mhz auch kein sher Tauglicher Quarz für UART
Immer diese Baudratenquarzfetischisten. Mann!!! ;-)
Mit 16 MHz kann ich alle normalen Baudratenm ausser 57k6 und 115k2 mit
einem Fehler klener als 0,8% generieren.
MFG
Falk
poste mal das Program. Klar kans am MAX liegen, wenn z.B: deine Stromversorgung zusammenbricht oder so.
#ifndef F_CPU #define F_CPU 16000000UL //Prozessor Frequenz in Hz #endif #include <avr/io.h> #include <util/delay.h> int main(void) { DDRA |= (1<<PA1);//Anschluss des Summers als Ausgang PORTA |= (1<<PA1); _delay_ms(10); PORTA &= ~(1<<PA1);//gibt kurz einen Ton aus, zur Bestätigung der Funktionstüchtigkeit UCSRB |= (1<<TXEN|1<<RXEN); //UART TX und RX einschalten UCSRC |= (1<<URSEL)|(1<<UCSZ0|1<<UCSZ1); //Asynchron 8N1 unsigned long ubrr_calc; ubrr_calc=F_CPU/(16*19200L)-1; //Berechne Wert, aus dem der AVR die Baudrate generiert UBRRH=(unsigned char)(ubrr_calc>>8); //schreibe den oberen Teil des Werts in die Schnittstelle UBRRL=(unsigned char)(ubrr_calc); //schreibe den unteren Teil des Werts in die Schnittstelle unsigned char dummy; while (UCSRA & (1<<RXC)) dummy=UDR; //Puffer entleeren, damit keine Störungen vor den Daten zu Fehlern führen unsigned char a; while (1) //Endlosschleife { while (!(UCSRA & (1<<RXC))); // warten bis Zeichen verfuegbar a = UDR; //Sende Zeichen zur Bestätigung zurück loop_until_bit_is_set(UCSRA,UDRE); //Bereit zum Senden? UDR=a; //Sende } return 1; }
>Klar kans am MAX liegen, wenn z.B: deine Stromversorgung zusammenbricht >oder so. Ich habe heute gerade 3 STück MAX232N und 2 Stück 16 polige Sockel bekommen. In einer Stunde denke ich, hab ich das Ding ausgewechselt (das ist immer ein Gefriemel, ungesockelte ICs auszulöten...). Diesmal würd ich die Kondensatoren außen rum gleich mit auslöten. Dann hätte ich die komplette Beschaltung des seriellen Ports ausgewechselt. Sinnvoll oder nicht? Ciao Tobias
Wenn deine Stromversorgung zu schwach ist ---> Nö :)
Hi Soo, ich habe jetzt mal den Prozessor auf ein Steckbrett gesteckt. Gleiche Beschaltung, Kondensatoren selbigen Typs, eins von den neuen Max ICs. Spannungsregler ist auch der gleiche Typ. Einzige Unterschiede: Der Spannungsregler ist komplett unbeschaltet (kein Kondensator, keine Diode) und als Kabel verwende ich die andere Hälfte des in der Mitte durchgeschnittenen Nullmodemkabels. Damit gehts ohne Absturz - Fehler ist also in meiner Schaltung zu suchen... Ciao Tobias
In deiner Schematic fehlt der Pull Up Widerstand am RST Pin.
Autor: Tobias H. (Gast) Datum: 04.01.2007 12:30 > >[...] > >P.S.: Bei meiner Stromversorgungsschaltung oben hab ich eins vergessen: >Der 10k Pull-up am Reset-Pin ist natürlich vorhanden! > >Ciao Tobias Wie ich schon sagte, der ist natürlich eingebaut! Da fällt mir gerade och ein Unterschied ein. Auf dem Steckbrett ist der Resetpin direkt mit VCC verbunden. Auf meiner Platine über den 10k Widerstand, damit man noch programmieren kann. Könnte der zu groß sein?
> Resetpin direkt mit VCC verbunden. Auf meiner Platine über den 10k > Widerstand, damit man noch programmieren kann. Könnte der zu groß sein? Nein. MfG Falk
Ich stelle nun gerade keinen Reset mehr fest, dafür kommen vollkommen falsche Zeichen zurück... hmmm...
Aus "test" wird "t{}|" 116 101 115 116 wird zu 116 125 123 124 das klingt nach falscher Baudrate, oder?
ich wieder: jetzt passt es wieder - dafür schmiert er jetzt wieder ab :-(
irgendwie hab ich das Gefühl, den Fehler gefunden zu haben. Entweder das Quarz, oder die Kondensatoren am Quarz haben einen defekt... Ich löte mal!
yyyyyeeeeeeeeeeeeeeeeeeeeeehhhhhhhhhaaaaaaaaaaaaaaaaaaaaaaa Einer der beiden 22pF Kondensatoren am Quarz war offensichtlich defekt. Hab nur den einen ausgewechselt, jetzt wieder getestet und: ES GEHT!! Ohne Absturz! Ciao Tobias
nein, der war schon richtig (steht ja drauf) - aber ich glaube der hat einiges mechanisch mitgemacht. Erstmal ist das Rastermaß 2,54 und ich musste ihn auf das doppelte hinbiegen. War extra vorsichtig eigentlich. Und außerdem ist er mir mal "umgeklappt" also platt umgebogen auf die Platine rauf. Beides zusammen hat ihn wohl rzerstört. Jetzt hab ich die Schaltung so angepasst, dass ich ihn direkt mit 2,54mm anlöten konnte. Ciao Tobias
@Tobias So etwas kann einen wahnsinnig machen. Ich fühle mit Dir ;-) Ich habe mal 22nF als 22pF geliefert bekommen, der Effekt war ähnlich lustig. Daraufhin ein Reim: Vor dem Löten, nach dem Essen Messen nicht vergessen! :-) MfG Paul
Hi Paul Danke für dein Mitgefühl :-) Darauf hab ich jetzt noch nicht geachtet - hab nur die 22 gesehen. Ob eine "Niete" zwischen den 22pF Dingern war, kann ich nicht sagen. Auf jeden Fall hats insgesamt mehr als 1 Tag quasi dauerhafter Suche gebraucht, den defekt zu finden... Ich sollte mir mal ein Messgerät für Kapazitäten kaufen/bauen! Ciao Tobias
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.