ich hab die Tage eine Experimental-Schaltung zusammengebastelt, um
zunächst die Anbindung Atmega <--> PC für sich zu testen, in
Vorbereitung für ein eigenes, komplexeres Projekt. Ich teste immer gern
alle Aspekte zunächst separat.
Die Schaltung besteht im wesentlichen aus einem mit 18,432 MHz
getakteten Atmega 644P und einem Pegelwandler MAX3232, letzterer
entsprechend Datenblatt mit 100nF Kondensatoren beschaltet.
Verbindung zum Terminal ohne Hardwarehandshake als
Drei-Leiter-Verbindung TxD, RxD über Kreuz, sowie Ground mit Ground.
Konfiguration an beiden Enden 9600,8N1, am Terminal ohne
Software-Flow-Control eingestellt.
Ich verwende die C Bibliothek von Peter Fleury. Soweit ich bisher
recherchiert habe ist das die meist-verwendete Bibliothek für diesen
Zweck(?)
Bisher sind meine Tests ausschliesslich auf dem Beispielcode von Peter
Fleury für das Hauptprogramm basiert.
Die Übertragungsrichtung Atmega --> Terminal klappt von Anfang an
problemlos, also sowas wie uart_puts("bla bla"\r\n); geht.
Solange die interrupt-basierte Abfrage des UART-Ports im Hintergrund vor
sich hinwerkelt, läuft auch alles stabil.
Aber sobald in der Hautpschleife des Peter-Fleury Beispiel main
Programms uart_getc() mit hoher Frequenz ausgeführt wird führt der
Atmega nach paar Tastendrücken am Terminal ein Reboot aus. Hab in jene
Schleife mal ein _delay_ms(5) eingebaut - und sofort läuft alles stabil.
Ich hab mich die letzten Tage fast zu Tode gegoogelt auf der Suche nach
Hinweisen zu diesem Problem.
Kann es sein dass die Funktion uart_getc() aus der Peter-Fleury
irgendwas unsauberes mit den Ringpuffer-Pointern macht wenn sie (schnell
getakteter Atmega und langsame Baud-Rate) viel öfter in Aktion tritt als
der UART-Recieve-Interrupt?
An sich ist alles möglich. Aber der Code von Peter ist schon relativ oft
verwendet worden und falls das öfter passiert, wäre es hier im Forum zu
finden. Such doch mal.
Um aber konkret auf Dein Problem einzugehen, wäre es gut zu wissen,
welchen Code Du genau verwendet hast. Es gibt nämlich verschiedene
Versionen davon und ein paar Leute haben den Code noch variiert. Poste
bitte mal einen Link genau auf den Beitrag wo Du den Code her hast.
Es wäre auch wichtig Deinen Code dazu zu sehen.
Ich kann mir aber auf Anhieb nicht vorstellen, das ein wildgewordener
Zeiger in den UART Funktionen von Peter das Problem ist.
na von dorten:
http://homepage.hispeed.ch/peterfleury/avr-software.html
Im code des test-Hauptprogramms, im unteren Teil, in der Endlosschleife
for(;;)
{
...
}
crasht das Programm nach paar Tastendrücken am Terminal, wenn ich es so
lasse wie es ist. Wenn ich entweder das uart_getc() auskommentiere oder
einen Delay einfüge läuft alles stabil - im ersten Fall natürlich
funktionslos ohne Eingabe.
Mein persönlicher Verdacht: da spielen 2 Faktoren eine Rolle:
1. verwenden die meisten Anwender sowieso nur die Datenrichtung Atmega
--> PC
2. verwenden die meisten wahrscheinlich höhere Datenraten als 9600.
Ich vermute das Problem besteht wenn uart_getc() häufiger auftritt als
die ISR, die Daten in den Ringpuffer tut...
Micha schrieb:> na von dorten:> http://homepage.hispeed.ch/peterfleury/avr-software.html
Welcher Code genau? Poste ihn doch einfach, statt irgendwelcher
Verweise.
Micha schrieb:> Ich vermute das Problem besteht wenn uart_getc() häufiger auftritt als> die ISR, die Daten in den Ringpuffer tut...
Dass das uart_getc der Fleury-Lib nicht blockierend arbeitet, und also
auch so was wie "kein Zeichen verfügbar" zurück geben kann, hast du aber
bedacht, oder?
Micha schrieb:> Im code des test-Hauptprogramms, im unteren Teil, in der Endlosschleife>> for(;;)> {>> ...>> }>> crasht das Programm nach paar Tastendrücken am Terminal,
Du verwendest den Code ohne irgendwelche Änderungen? Richtig?
> Mein persönlicher Verdacht: da spielen 2 Faktoren eine Rolle:> 1. verwenden die meisten Anwender sowieso nur die Datenrichtung Atmega> --> PC> 2. verwenden die meisten wahrscheinlich höhere Datenraten als 9600.
Antwort auf beide Vermutungen:
Spielt alles keine Rolle. Deswegen darf der Code nicht crashen.
Solange du händisch am Terminal tippst, kannst du tun was du willst,
diesen Code darfst du nicht zum Crashen bringen. So schnell kannst du
nicht tippen.
>na von dorten:
Was heisst "na"? Nur weil Du eine Quelle gefunden hast, heisst, das ja
nicht, das es die einzige ist. ;-) Ich z.B. hab meine Variante hier
aus dem Forum. Such mal hier im Forum nach Peter Fleury. Da findest Du
noch weitere Varianten.
Ich habe mal nachgeguckt, aber in der getc routine kann aus meiner Sicht
nichts crashen, egal wie häufig man die aufruft. Wenn kein Zeichen da
ist, ist halt keins da und wenn doch wird der Index UART_RxTail nur in
getc verändert.
Deine Vermutung muss deswegen nicht falsch sein, aber hat es doch nötig
durch Informationen erhärtet zu werden.
ja ich weiss, so ein Problem ist immer irgendwie ne komplexe Mischung
aus möglichen Hard- und Software- Ursachen. Ich hab leider vorläufig
nicht das Equipment (Speicher-Oszi, Logik-Analyzer) um Hardware-Probleme
zuverlässig einzukreisen.
Ich hänge mal unten den aktuellen Stand meines Experimental-Codes an.
Startpunkt für das Hauptprogramm war test_uart.c aus dem Archiv direkt
von Peter Fleury's Webpage. Strings vom Atmega zum Terminal hat von
Anfang an gut geklappt.
Hab zunächst mal die PROGMEM Sachen rausgetan um eine mögliche Ursache
zu eliminieren. Ohne Erfolg. Dann hab ich verschiedenes ausprobiert. Mit
dem Code wie angehängt resettet der Atmega jeweils nach ca. 2 bis 10
Tastaturanschlägen auf dem Terminal. Wenn ich die Zeile mit
*uart_getc()* auskommentiere läuft der Atmega stabil durch. Wenn ich ein
*_delay_ms(5)* in die Hauptschleife einfüge läuft es ebenfalls stabil,
dann bekomme ich sogar die Zeichen wieder aufs Terminal ge-echot. Läuft
stundenlang, ohne Zeichen-Verlust.
Ich hab die Zeile mit dem delay mit >>> <<< markiert, das ist
selbstverständlich nicht Teil des eigentlich verwendeten Quelltexts:
Ich denke, das es sich um eine Hardwareproblem handelt?
Bei welcher Spannung läuft Dein Prozessor und der Max?
Hast Du Abblockkkondensatoren am Prozessor?
mag ich überhaupt nicht ausschliessen dass es ein Hardware-Problem ist.
Ich hab zwei Varianten ausprobiert:
1) Mit 4,5V (Pack aus drei AA Batterien).
2) Mit einem käuflich erworbenen 5V Netzteil, in dem Fall hab ich einen
100uF Elko zwischen Netzteil und Schaltung. Ohne den Elko geht
garnichts, da gibts jede Menge Fehler bzw Resets, mit dem Elko geht
Senden stabil, und empfangen mit _delay auch.
Aus praktischer Sicht hab ich das Problem ja inzwischen gelöst, ein 5us
Delay reicht (im Listing waren es 10 us), würde mich aber trotzdem
interessieren wo das Problem liegt.
Der Maxim MAX3232 den ich verwende braucht laut Datenblatt "nur" 100nF
Kondensatoren um die Pegelwandlung von 0..5V auf -12..+12V hinzuzaubern.
Ist das womöglich fauler Zauber? Sollte ich mir doch dringend einen
Speicheroszi bzw. einen Logikananlyzer besorgen? Fragen über Fragen...
Also bei dem MAX3232 habe ich im Datenblatt andere Angaben zu den
Kondensatoren gefunden. Nicht alles 100nf sondern 47nF und 330nF resp.
100nF und 470nF. Siehe Seite 7, Bild 4.
Das
>Ohne den Elko geht>garnichts, da gibts jede Menge Fehler bzw Resets, mit dem Elko geht>Senden stabil, und empfangen mit _delay auch.
deutet auch darauf hin, das Du Probleme mit der Stromversorgung hast.
Nachdem Du die Kondensatoren am Max korrigiert hast, könntest Du da auch
mal mit anderen Kondensatoren spielen.
Was ist das für ein Netzteil? Schaltregler, Linearregler oder nur Trafo
mit Gleichrichter?
so messgeräte sind auf jeden fall nicht verkehrt..
neben dem 100µF elko hast du natürlich auch noch die obligatorischen
100nF kerkos zum abblocken an den vcc/gnd pins des µC?
>Aus praktischer Sicht hab ich das Problem ja inzwischen gelöst...
ist jedenfalls ein Irrtum. Die Software ist OK und wird durch ein Delay
in keiner Weise verbessert. Du beseitigst nicht die Ursache sondern die
Symptome.
Das Delay deutet übrigens auch auf Probleme mit der Stromversorgung und
zwar in Bezug auf den Max. Denn das Delay bedeutet das der Wandler mehr
Zeit hat, nach einer Belastung auf Sollausgangsspannung zu kommen.
>neben dem 100µF elko hast du natürlich auch noch die obligatorischen>100nF kerkos zum abblocken an den vcc/gnd pins des µC?
Ja. Genau. Das habe ich Dich ja auch gefragt, aber Du hast darauf nicht
geantwortet.
war nicht böse gemeint, ist nur verwirrend wenn alle "Noname" heissen.
Ja, ich hab nen 100nF am Prozessor. Aber ich muss mir wohl wirklich
dringend entsprechende Messtechnik zulegen. Ideal sind ja immer alles
Rechteck-Impulse. Aber was ich inzwischen so auf diversen Websiten zum
Thema Digitaltechnik und Signale gesehen hab macht mich schon
nachdenklich...
Ich war seit langen ein "Softie" der sich nur mit Programmierung
beschäftigt hat, in der Hardware Welt der Atmels bin ich erst seit rel.
kurzer Zeit unterwegs.
>war nicht böse gemeint, ist nur verwirrend wenn alle "Noname" heissen.
Verstehe ich nicht. Worauf beziehst Du Dich?
Ich bin immer derselbe Noname. Alle anderen sind billige Kopien. :-)
Was ist jetzt mit dem Max und den Kondensatoren? Was mit dem Netzteil?
Hallo Micha,
bitte mache auch noch ein paar Bilder.
Ist auch Port A == AVCC, AGND nach Datenblatt, AP beschaltet ?
Siehe: www.atmel.com/dyn/resources/prod_documents/doc8011.pdf
2.3.10
das Datenblatt des Herstellers MAXIM das mir bisher vorlag gibt für die
Beschaltung des MAX3232 durchgängig 100nF an. Das oben zitierte
Datenblatt ist von Texas Instruments, gibt tatsächlich teils andere
Werte vor. Ich glaub inzwischen die Chip-Hersteller sind teils noch viel
schlampiger als Du und Ich...
Mein Fehler. Hab ich nicht daran gedacht.
Hast Du den wirklich von MAXIM-Dallas? Schau mal auf den Chip welches
Logo zu sehen ist.
Die Hersteller sind aber durchaus nicht schlampig. Obwohl die Chips
gleich heissen, brauchen sie, je nach Hersteller unterschiedliche
Kondensatoren. Das ist schon ok so.
Trotzdem hast Du meiner Ansicht nach ein Problem mit der
Stromversorgung. Also auf jeden Fall noch 100nF parallel zu dem Elko am
Netzteil. Falls es nicht geht, anderes Netzteil probieren.
Was für ein Netzteil ist das denn jetzt? Hast immer noch nicht
geantwortet und ich werde nicht nochmal fragen.
>der MAX3232 den ich verwende (bei reichelt gekauft) trägt tatsächlich>das Logo von Maxim.
OK.
Hm. Das "Netzteil". Wie versorgst Du es? Über USB oder über die
Hohlsteckerbuchse? Falls USB, dann könnte es sein, das sich Dein Host
streng an die USB-Spec. hält und Dich nur wenig Strom ziehen lässt, vor
allem wenn es auf enumerationsanforderungen nicht reagiert. Offen gesagt
ist das Ding aus meiner Sicht sowieso Murks. Es gibt weder ein
Datenblatt noch funktioniert die auf der Platine angegebene Website. Da
sind noch so Halbleiter zu sehen, die sicher auch nicht für umsonst
arbeiten (soll heissen ohne Spannungsabfall).
Nimm lieber was richtiges. Das Ganze zeigt mit jedem bekannt werdenden
Detail immer weiter in Richtung Probleme mit der Stromversorgung.
Was hast Du für Messgeräte und alternative Stromversorgungen (ausser
Batterie).
>Wie schon gesagt, geht nur stabil mit einem 100uF Kondensator dahinter.
Nein. Es geht nicht stabil, da die UART-Kommunikation abbricht.
Denke Dir das nicht so zurecht, das es "fast" passt und nur noch das
Delay fehlt.
ich hab hier ehrlich gesagt ein massives Verständnisproblem: Die
Kommunikation zwischen RS232 und Atmel wird über Interrupt-Routinen
abgewickelt, die die ganze Zeit aktiv sind.
Wenn ich uart_getc() garnicht einbinde (oder mittels delay) in größeren
Zeitabständen, dann kann ich wie verrückt auf der Tastatur des
angeschlossenen Terminals herumtippen - ohne dass der Atmel in ein Reset
gerät. Kann auch beliebig Strings zur RS232 ausgeben mittels uart_puts()
zu Kontrollzwecken.
Erst wenn ich uart_getc() in schneller Folge ausführen lasse gibt es
nach paar Tastendrücken ein Reset. Aber uart_getc() macht doch nichts
mit der Hardware direkt sondern guckt nur in den Ringpuffer ob Zeichen
da sind. Hab ich einen Denkfehler? Nach meinem Verständnis deutet das
auf einen Konflikt zwischen Interrupt-Routine und uart_getc() hin?
Was Stromversorgung angeht hab ich bisher nichts "ordentliches". Über
Tips wär ich dankbar. Ist ein sog. "Labornetzteil" sinnvoll für solche
Versuche auf Breadboard-Basis?