Ich habe jetzt schon alles was mir einfiel versucht, das Datenblatt hin
und her gewälzt aber ich komme nicht drauf. Assembler auf dem Atmega
mache ich jetzt allerdings auch nicht jeden Tag sondern nur bei Bedarf,
bin also für Anmerkungen zum Code offen. Der Ausschnitt ist Teil eines
größeren Programms, aber hier liegt irgendwo ein Fehler von mir. Es
sollen eigentlich nur alle Pins auf einem Port high gesetzt werden und
dann nach einer definierten Zeit der Reihe nach ausgehen. Im Debugger
alles kein Problem, es funktioniert wie ich will aber in real sieht es
anders aus. Bleibt der Atmega an der ISP Schnittstelle nach dem
Programmieren hängen geht alles, nehm ich die Schnittstelle ab sehe ich
die LEDs erst gar nicht angehen. Als ob der Prescaler nicht richtig
gesetzt ist und ich mit maximalen internen Takt (für mich nicht
sichtbar) alle LEDs ausgeschaltet werden. Der Atmega soll übrigens mit
1MHz internem Takt laufen.
> Bleibt der Atmega an der ISP Schnittstelle nach dem Programmieren> hängen geht alles, nehm ich die Schnittstelle ab sehe ich die LEDs> erst gar nicht angehen. Als ob der Prescaler nicht richtig gesetzt ist
.... so als ob es ein Problem mit dem Reset Pin gibt
.... so als ob es ein Problem mit der Spannungsversorgung gibt
Hi
Nun, ein Setzen des Stackpointers ist beim Atmega8 nicht unbedingt
erforderlich, da der SP beim Start auf 0 steht und durch PUSH erst dec.
und dann beschrieben wird. Dennoch kommen die paar Befehle auch bei mir
grundsätzlich vor dem ersten CALL in das Programm:
1
LDI Reg_A ,high(RAMEND) ; Stack Pointer setzen
2
OUT SPH, Reg_A ; "RAMEND" ist in m8def.inc festgelegt
3
LDI Reg_A, low(RAMEND)
4
OUT SPL,Reg_A
Soviel zum Stack. Der Fehler liegt vermutlich in der Hardware, obwohl
genug am Programm zu meckern gibt.
Wenn du einen Timer mit Interrupt benutzt, dann arbeite anders:
Im Timer- Interrupt zählst du deine Variable hoch. Dann vergleichst du
den Wert mit einer Konstanten und bei Übereinstimmung setzt du ein Bit
(Job-Flag). Dieser Programmteil hat mit deiner Programmschleife
überhaupt nix zu tun und läuft dann autark.
Nun zum Job-Flag. Soll bei einem bestimmten Zählerstand eine Bearbeitung
stattfinden, so kannst du natürlich auch außerhalb der ISR den Wert
vergleichen. Das erfolgt unter Umständen aber mehrmals mit positivem
Ergebnisin der Programmschleife (Zykluszeit < Bearbeitung im Timer).
Nicht immer ist das erwünscht und wenn dieses Ereignis nur einmal
bearbeitet werden soll, nimmt man ein Job-Flag. Ist dieses gesetzt, dann
führst du die beabsichtigten Schritte durch und setzt anschließend das
Job-Flag zurück. Nun wird dieses Programm erst wieder aufgerufen, wenn
im Timer das Bit gesetzt wird. Dein Programm läuft also immer durch alle
Abfragen und bleibt nicht wie beim vorgestellten Code in einer
Unterschleife hängen. So ist es niemals über normale Eingänge bedienbar
und du wärest gezwungen, bei Tastereingaben z.B. mit einer ISR zu
arbeiten. Schau mal über die Suchmaschine, ob du irgend welche Beiträge
zu Jobflags findest. Dann wird dir vermutlich auch deutlich, welche
Struktur du beim Programmieren, grad in Assembler, dir angewöhnen
solltest.
Ansonsten schau mal zur Konkurenz AVR-Praxis.de. Dort ist in der Rubrik
FAQ ein Beitrag "keine Angst vor Assembler" mit hoffentlich
interessanten Hinweisen.
Sie mal nach, ob vom Reset-Pin ein Widerstand von ca. 10 KOhm nach VCC
geht. Auch evtl. die GND-Leitung überall richtig verschaltet ist.
Gruß oldmax
So, an RESET, VCC und AVCC liegen saubere 5V DC. An 8 und 22 sauberer
Ground. Der Rest des Programms nach dem oberen Codeauszug funktioniert
ja auch, der Fehler sollte demnach im Programm liegen. Versorgung beim
Programmieren kommen auch aus der Schaltung. Es wird also nichts
fremdgespeist, weshalb es nur mit angeschlossenem ISP funktioniert.
Initialisieren des Stack Pointers werde ich dann auch mit aufnehmen.
Arbeiten mit Job Flags kenne ich, werde dann das Programm gleich mal
umstricken.