siehe Anhang:Progamm ISR´s "key_scan:" und "beat:" In beiden Fällen werden sowohl das im Prog permanent benutzte Temp/scratch Register namens uni00 als auch das Statusregister gesichert (push-pop Sequenz). Ist das so korrekt? Konkretes Problem:(siehe auskommentierte Zeilen in "beat:") Ich muss gegen die Regel "sichere temp und sreg bei ISR´s" verstoßen,damit der rol Befehl funktioniert,denn der benutzt das Carry Flag zum Zwischenspeichern. Vermute hier die Ursache für seltsame "Programmabstürze". (fehlende sreg Sicherung bei "beat:"),aktiviere ich die ;Zeilen ist der "Absturzfehler" weg,aber auch der rol Befehl "tot". Habe die Module und Unterprogramme einzeln entwickelt und getestet.Beim Zusammenfügen zur Gesamtfunktion treten jedoch seltsame Nebeneffekte auf (gegenseitige Beeinflussung durch unsaubere Anfängerprogrammierung?). Auch AVR Studio Simulator hilft nur begrenzt bei diesem zeitkritischen prog mit 2 ints,das vonexternen Tastendrücken "lebt" weiter. Verliere trotz strukturierter Programmierung die Übersicht. Wie lösen Profis solche Probleme ? Dank vorab Uli
Hallo, ich bin zwar kein Profi sondern Anfänger, aber wenn Du noch irgend ein unbenutztes Register hast, dann sichere den Stack doch darin. Gruß, Arno
Ja,Arno,danke,kenn ich. Das sreg auf Stack oder in Exclusivregister retten sind 2 Möglichkeiten.Aber:Bei Registervariante 2 Regs für 2 ISR,s ? "Verbrate" ungern Register,wer weiß wozu ich die noch brauche ? Ist der Stack nicht u.A. genau dafür vorgesehen ? Es geht darum,ob ich in der ISR "beat:" das sreg sichern SOLL oder NICHT.Entweder ich sichere und der rol Befehl fällt aus, oder ich sichere nicht und habe seltsame Effekte. Eine Zwickmühle. Wiederhole auch die Frage,ob die Arbeitsregister und SREG Sicherung so OK ist ? Danke Uli
Um die Sicherung von sreg und uni00 wirst du nicht herum kommen. Kannst Du die Auswertung von uni01 auch in der "beat"-Routine machen ? Dann wäre das mit dem sreg auf dem Stack kein problem mehr. Mir ist aufgefallen das du uni00 zwischendurch auf Null setzt, das kostet aber unnötig Zeit. Ich finde es übrigens nett, das du dem Prozessor zwischendurch ein paar Takte Ruhe gönnst durch die "nop" Befehle. :-) Gruß, Arno P.S. Wie gesagt ich bin Anfänger und versuche daraus auch was zu lernen.
hi uni00 auf 0 setzen:Das ist ein "verkappter" nop,denn es dauert einen Zyklus,bis die Bits vom Portlatch zu den PortPins übertragen werden.->"stabilize i/o_adress". Zwischen 2 out Befehlen auf 2 Ports muß (bei meiner Hardware) ein "Pausebefehl" z.b. nop stehen.Alternativ cleare ich uni00. "Besser irgendwas (sinnloses?) tun als nichts". oder zitat:ALF,das Alien: "Besser nichts tun als garnichts!" --nun denn-- Auswertung uni01 in "beat": Du meinst,den Befehl "out uni01" in "beat" zu verlagern. Gute Idee,mal versuchen.Werde berichten. "beat" wird ja mit ca. 64Hz aufgerufen (Tasterrentprrrelellung). Das reicht. Gelernt:Bei ISR´s NIEMALS auf die SREG und Arbeitsregister Sicherung (bei mir nur uni00) verzichten. Also alle Register,die in der ISR verändert wurden,so wie vor dem Einsprung in die ISR wiederherstellen. "Als wär die ISR garnicht drangewesen" Nochwas:Darf ich Hardwaretimer Register von T0 und T1 bei aktiviertem lokalen (timsk) und globalen (sei) Interrupt, also praktisch im laufenden Betrieb,manipulieren ? Es scheint zu gehen,bin aber nicht sicher,aber wenn keiner meckert,"Never change a running System",ists wohl erlaubt. Dauernd ints an und abzuschalten ist wohl auch nicht so gesund. Lasse T1 lieber durchlaufen. Was hältst Du von der Art der Tasterentprellung,also per Timer0 mit 64Hz abzufragen ? Die Abtastung erfolgt so schnell,das die erste Flanke erfaßt wird,Preller sind danach 15.6ms lang ausgeblendet. Durch den Prescale von T0 läßt sich die Abtastrate an Taster verschiedener Prellhäufigkeit anpassen. Je mehr Prellen,desto langsamer. Nochwas:Siehe "port_init" -> portc. Portc ist als in und hochohmig definiert. Trotzdem kann ich mit "out" auf diesen Port schreiben,wie angeschlossene Led beweisen.Benutze den Port im Prog als in UND out ohne out-Umschaltung! Könnte unbekannte Nebeneffekte haben.Aber:"Never change..." Noch offen:Wie findet man Fehler in komplexen,zeitkritischen Programmen? Angenommen,ich verzichte testweise auf die SREG Sich. bei ISR´s. Dann läuft es trotzdem.Aber wehe,ich drücke Taster! Stürzt dann ab,blinkt sinnlos rum. Dabei sind pro Versuch verschieden viele Tastendrücke nötig. Ein voll übler,"sporadischer" (zufälliger) Fehler. Dann nützt mir AVR Studio Simulator m.E. wenig,weil das Prog in Echtzeit laufen muß,um den Fehler zu zeigen. Dauert auch so lange,sich durch die ganzen Timer-Schleifen durchzutracen,bis das Prog endlich in einem bestimmten Zustand ist,wo ich den Fehler vermute. Wie die "Suche nach der Nadel im Heuhaufen". Hat mich schon Stunden gekostet.Das kann es nicht sein. Uli
"Als wär die ISR garnicht drangewesen" Du hasts genau erfaßt. Wer das nicht beachtet, wird mit Nichtfunktionieren und langer Fehlersuche bestraft. "Darf ich Hardwaretimer Register von T0 und T1 bei aktiviertem lokalen (timsk) und globalen (sei) Interrupt, also praktisch im laufenden Betrieb,manipulieren ?" Das geht schon. Allerdings ist ein freilaufender Timer weitaus leistungsfähiger, da er ja für viele verschiedene Zeitfunktionen verwendet werden kann (jeder kann ihn lesen und damit die vergangene Zeit seit dem vorherigen Lesen ermitteln). "Was hältst Du von der Art der Tasterentprellung,also per Timer0 mit 64Hz abzufragen ?" Das ist doch die übliche Methode, es gibt keine andere gleich gut funktionierende und universelle. Hier ein Beispiel sogar mit 4-fach Abtastung für die labrigsten Tasten der Welt: http://www.mikrocontroller.net/forum/read-4-20549.html "Trotzdem kann ich mit "out" auf diesen Port schreiben,wie angeschlossene Led beweisen." Du hast Dir wohl nicht dei Portbeschreibung im Datenblatt durchgelesen, der Pull-Up kann durchaus eine LED schwach leuchten lassen. "Wie findet man Fehler in komplexen,zeitkritischen Programmen?" Immer schön modular schreiben und die Module einzeln testen. Peter
Hallo Peter! ----------------------------------------------------------- "Trotzdem kann ich mit "out" auf diesen Port schreiben,wie angeschlossene Led beweisen." Du hast Dir wohl nicht die Portbeschreibung im Datenblatt durchgelesen, der Pull-Up kann durchaus eine LED schwach leuchten lassen. ----------------------------------------------------------- Doch,hab gelesen.Was Du nicht wissen konntest: Am Portc hängen 74373 ParallelLatches,Portd selektiert über Decoder 74154 (4-16) die Latches.Portc ist Data Output. Die Leds hängen an den Latchausgängen,von +5V 330 Ohm an Anode, Katode an LatchPin (Geschaltete Masse),wie immer. Portc dient alternativ auch als Input für 74254 Bustreiber, ebenfalls 74154 selektiert. Dort sind Taster mit Pullup 5K R´s angeschlossen. Taster schalten gegen Masse. Portc,wie gesagt,als Input,hi-Z, definiert. Trotzdem Schreiben mit "out" über portc in die 74373 Latches möglich.Genau da ist der Widerspruch. Passiert z.B. in "io_write:" Zeile: "out portc,data" Die Daten kommen problemlos im 74373 Latch an (Led Beweis). Wie kann das sein,wenn portc als IN und HI-Z definiert ist ? -------------------------------------------------------------- "Wie findet man Fehler in komplexen,zeitkritischen Programmen?" Immer schön modular schreiben und die Module einzeln testen. -------------------------------------------------------------- Genau das hab ich getan und beachtet. Der Fehler zeigt sich erst beim Echzeitlauf aller zusammengefügter Module und Benutzung zweier Ints, also im komplexen Zusammenspiel in Echtzeit. Irgendwas vergessen,von dem ich nichts ahne. (Das mit der SREG Push-Pop Sicherung weis ich auch erst seit Kurzem). Danke Uli
Hallo Uli, ich benutze zum üben auch AVR-Studio 4, weil ich noch keine Hardware habe. Du könntest zum testen des Programms an verdächtigen Stellen einen Breakpoint setzen und dann Schrittweise weiter testen. Zum Glück hat der Peter Dir schon geantwortet, denn ich hätte Dir da nicht viel weiterhelfen können. :-) Gruß, Arno
Danke,Arno. Habe schon mit Breakpoints gearbeitet,z.B. bei "beat:" Damit kommt man m.E. weiter,wenn man den Fehler an einer bestimmten Stelle vermutet. Mein Fehler ist "zufällig" ,d.h. nach einer bei jedem Reset verschiedenen Anzahl von Tasterdrücken,läuft das Prog. ins Nirvana,ebenso überraschend wie ein Win-Bluescreen. Als Ursache kommt im Prinzip das Gesamtprog. in Frage. Werds weiter überarbeiten,warte auf neue Version vor Antwort. Gruß Uli
Wie man sieht,konnte ich bei "beat:->test_rotator" das Carry Flag über das Transfer-Flag retten und trotzdem die sreg Sicherung durchführen. Arno: "Um die Sicherung von sreg und uni00 wirst du nicht herum kommen. Kannst Du die Auswertung von uni01 auch in der "beat"-Routine machen ? Dann wäre das mit dem sreg auf dem Stack kein problem mehr." An Arno: Die einfache Verlagerung der Auswertung brachte keine Verbesserung. Problem aber gelöst.(siehe oben). Portc Init auf default "in/hi-z" für Tasterabfrage gesetzt und beim Schreiben auf I/O Devices Umschaltung auf "out",dann Schreiben,wieder auf "in/hi-z" zurück für erneute Tasterabfrage (Default Status). Auch die sporadischen Fehler (Abstürze) sind bisher nicht wieder aufgetaucht. Als Ursache kommt eine jetzt gelöschte Warteschleife in der ISR "beat:" infrage. Vermutung:Die Schleife wartete länger,als der nächste T0 Int kam.Hätte eigentlich trotzdem gutgehen müssen,egal. Hauptsache:Fehler weg. Uli
Ja,nett. Jetzt kenne ich auch das T-Flag. So kommt man langsam weiter. Folgerung:Es muß noch eine Menge "Tricks" geben. Lese im Forum oft von Dingen,deren Bedeutung ich nur erahne,wie: "Parameterübergabe über Stack" "Arbeiten mit x y z Pointer" "Arten des Speicherzugriffs (Offset,Displacement)" Was dort geschieht ist schon klarer als die Frage, warum man das tut. Uli
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.