Hallo Forum, ich möchte bei einem Ausfall der Versorgungsspannung den Zustand von PORTB im EEPROM abspeichern. Ich habe hierfür den internen Analog-Komparator verwendet. Am ADC1 ist im Moment ein Poti angschlossen, mit dem ich das Absinken der Spannung simuliere. Später hängt dann die 24V Versorgung über einem Spannungsteiler daran. Fällt die Spannung unter 1,1V, wird die analog-comp ISR aufgerufen und der Zustand von PORTB wird mit der Funktion eeprom_write_byte der AVRlibc abgespeichert. Ich habe das EEPROM mehrfach ausgelesen und es funktionier einwandfrei. Soweit so gut. Bei einem Power-up wird geprüft, ob im EEPROM ein Wert abgespeichert wurde. Wenn ja, wird der Wert an PORTB gegeben und das Byte im EEPROM wieder "rückgesetzt" (s. BOOKMARK 1 im Quelltext). Im Simulator funktioniert alles bestens, in der Realität leider nicht. Der Wert 0 wird nicht ins EEPROM geschrieben. Ich hab dann den Write-Befehl auskommentiert und die komplette if-Abfrage weiter unten ( nach sei() ) reinkopiert (s. BOOKMARK 2). Jetzt wird der Wert 0 geschrieben, allerdings funktioniert hier der Read-Befehl nicht - also habe ich ihn wieder auskommentiert. Sprich: so wie das Programm im Moment aussieht, macht es genau das was ich will. Nur, warum funktioniert einmal eeprom_write_byte (BOOKMARK 1) und einmal eeprom_read_byte (BOOKMARK 2) nicht? Bin vollkommen verwirrt und hoffe auf Antworten. Leider habe ich über die Suchfunktion nichts in Erfahrung bringen können. Mit den neusten Versionen von AVRStudio und WINavr haut es übrigens auch nicht hin. Das ganze läuft auf einem ATmega168. Ich benutze AVRStudio 4.12 SP4 und WinAVR 20060421.
Verzwickte Geschichte nicht war ;) Simulation und Realität sind meistens zwei unterschiedliche Dinge. Eine konkrete Lösung hab ich für dich jetzt nicht, aber vieleicht ein paar Tips. eeprom_write_byte(); wartet nicht auf das Ende des Schreibvorganges. Man sollte aber besser darauf warten: eeprom_write_byte(EEP_VOLUME,volume); eeprom_busy_wait(); Hast du den Brown-Out Reset aktiviert ? Evtl. schlägt der zu bevor du in die Analog-Komparator ISR kommst. Das schreiben ins EEPROM dauert ein paar Millisekunden. Wenn die Versorgungsspannung zu schnell fällt kann das Probleme machen. Das hier ist auch problematisch: ISR ( ANALOG_COMP_vect) { eeprom_write_byte(&output_backup, PINB); } Da fehlt auf jeden Fall das eeprom_busy_wait(); Das Programm kann bei langsam fallender Spannung auch SEHR oft hier reinspringen. Das ist nicht gut fürs EEPROM ! Evtl. einfach ne Endlosschleife hinter eeprom_write_byte(); setzen und hoffen das entweder der Brown-Out Reset oder der WDT einen sauberen Reset hinlegt. Oder die ISR abschalten.
Hallo Holger, vielen Dank für deine Antwort. Leider verbessert sich durch eeprom_busy_wait() nichts. Brown-out ist die ganze Zeit deaktiviert. Mir ist klar, dass der Komparator am Schwellwert etwas zu klappern anfängt und dann evtl. mehrfach das gleiche Byte beschrieben wird. Das wollte/will ich noch korrigieren. Unverständlich bleibt für mich, dass die read/write Funktionen an den Stellen, wo ich sie verwende so merkwürdige Dinge veranstalten. In der ISR funktioniert das Schreiben in 100% der Fälle. Ok, vielleicht ist das so, weil durch mein Poti die ISR mehrmals getriggert wird und der Wert in die Zelle reingehämmert wird :-) Ich habe zwischenzeitlich herausgefunden, dass häufiges reseten machnmal den Wert 0 ins EEPROM schreibt. Also manchmal klappts. Delays haben mich auch nicht weiter gebracht :-(
@ Jochen Ruf (Gast) >eeprom_busy_wait() nichts. Brown-out ist die ganze Zeit deaktiviert. Mir Das ist eher schlecht. Welche AVR Fuses hast du denn gesetzt? Du sollte auf jeden Fall die längste Startup-zeit einstellen, Brown Out wäre noch besser. >ist klar, dass der Komparator am Schwellwert etwas zu klappern anfängt >und dann evtl. mehrfach das gleiche Byte beschrieben wird. Das Nöö. Wie holger schon sagte, nach dem Erkennen des Spannungsausfalls muss deine CPU auf ihre Ende warten. So.
1 | ISR ( ANALOG_COMP_vect) |
2 | {
|
3 | eeprom_write_byte(&output_backup, PINB); |
4 | while(1); |
5 | }
|
Hier wird ggf. der Compiler mosern, muss man aber ignorieren. Denn wenn die Schaltschwelle einmal unterschritten ist, darf das Programm keinen Schritt weiter laufen sondern muss auf das Ende aller Tage warten. Mit Brown Out wird das Solide, ohne eine Zitterpartie. >wollte/will ich noch korrigieren. Unverständlich bleibt für mich, dass >die read/write Funktionen an den Stellen, wo ich sie verwende so >merkwürdige Dinge veranstalten. In der ISR funktioniert das Schreiben in Das sind wahrscheinlich sporadische Resets, wenn die Spannung fällt. IOhne Brouwn Out kann die CPU komische Dinge veranstalten. >machnmal den Wert 0 ins EEPROM schreibt. Also manchmal klappts. Delays >haben mich auch nicht weiter gebracht :-( Daran liegt es selten. MfG Falk
Ahhh... jetzt hab ich's kapiert. Jungs ihr seid spitze! Ist ja eigentlich logisch, dass der Controller nach der Unterspannungserkennung definiert hängen bleiben muss/sollte. Holger hats ja schon geschrieben, bei Falks Erklärung ist dann der Groschen gefallen. Ich habe gestern nach meinem Post die ANALOG_COMP ISR mal komplett deaktiviert und siehe da, die read/write Funktionen machen genau was sie sollen, egal wo sie im Programm vorkommen. Hätte mich auch gewundert. Mit der Endlosschleife in der ISR und der Brown-out Abschaltung sollte es jetzt funktionieren. Vielen Dank und schönes Wochenende.
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.