Hi,
ich hab hier grad ein merkwürdiges Problem.
Ich habe ein Lauflicht in Assembler programmiert. An PB1, PB2 und PB3 hängen jeweils eine LED dranne.
Hier erstmal der Code:
Code:
;Dieses Programm produziert ein Lauflicht. Jede halbe Sekunde geht die
;nächste LED an.
;Das Programm läuft in einer Endlosschleife durch.
.include "m8def.inc"
.equ time1 = 65536-1800 ;Damit wird der Timer1 vorgeladen, für die halbe Sekunde
.equ LED1 = PB1 ;LED an B.1
.equ LED2 = PB2 ;LED an B.2
.equ LED3 = PB3 ;LED an B.3
.def tmp = r16 ;Mein Universallregister
.org 0x000
rjmp reset ;Interruptvektor "reset:"
.org OVF0addr
rjmp hSekEnde ;Interruptvektor für Timer0 Überlauf, hier springt
;das Programm hin, wenn der Timer überläuft
reset:
;Stack einrichten
ldi tmp, HIGH(RAMEND) ;HIGH-Byte der obersten RAM-Adresse
out SPH, tmp
ldi tmp, LOW(RAMEND) ;LOW-Byte der obersten RAM-Adresse
out SPL, tmp
ldi tmp, 0b11111111
out DDRB, tmp ;PortB als Ausgang
sbi PORTB, LED1 ;Am Anfang LED1 an
;Timer Register für halbe Sekunde werden belegt, hier Timer1
ldi tmp, (1<<CS12) | (1<<CS10) ;Prescaler ist 1024
out TCCR1B, tmp
ldi tmp, HIGH(time1) ;Für den Timer1 (16Bit) benötigen
out TCNT1H, tmp ;wir 2 Register, in denen wir den Wert
ldi tmp, LOW(time1) ;für die 1/2 speichern ->
out TCNT1L, tmp ;"TCNT1H" und TCNT2L"
ldi tmp, (1<<TOIE1) ;Hier werden Interrupts nach Timer1 Überlauf eingeschaltet
out TIMSK, tmp ;Register TIMSK ist dafür zuständig
sei ;Interrupts zulassen
main:
rjmp main ;Immer wieder die main durchlaufen
;Jede halbe Sekunde wird geprüft, welche LED an ist und dementsprechen die
;nächste LED angemacht. Die aktuelle wird dabei natürlich ausgeschaltet
hSekEnde:
push tmp ;tmp-Register auf Stack sichern
in tmp, SREG
push tmp ;SREG auf Stack sichern
;TIMER1 wird neu geladen
ldi tmp, HIGH(time1) ;Für den Timer1 (16Bit) benötigen
out TCNT1H, tmp ;wir 2 Register, in denen wir den Wert
ldi tmp, LOW(time1) ;für die 1 Sekunde speichern ->
out TCNT1L, tmp ;"TCNT1H" und TCNT2L"
sbic PORTB, LED1 ;Ist LED1 aus?
rjmp LED2an ;LED1 ist an -> mach LED1 aus und LED2 an
sbic PORTB, LED2 ;Ist LED2 aus?
rjmp LED3an ;LED2 ist an -> mach LED2 aus und LED3 an
LED1an:
cbi PORTB, LED3
sbi PORTB, LED1
rjmp ende ;springe zum Ende der Interruptroutine
LED2an:
cbi PORTB, LED1
sbi PORTB, LED2
rjmp ende
LED3an:
cbi PORTB, LED2
sbi PORTB, LED3
ende:
pop tmp
out SREG, tmp ;SREG wiederherstellen
pop tmp ;tmp wiederherstellen
reti ;springe wieder dahin, wo du hergekommen bist
Habe es auf meinen Atmega8L draufgebrannt, klappt ja auch alles wunderbar. Nachdem ich dann ein Netzteil angeschlossen habe (9V) funktioniert das Lauflicht wunderbar. Doch wenn ich es ausschalte und nach einer Zeit wieder anschalte, leuchtet nur die LED an PB1 und wechselt nicht.
Ich hab schon probiert, die Zeit zu messen, bis ich wieder anschalte. Aber es ist immer unterschiedlich, wann das Lauflicht funktioniert und wann nicht.
Was kann die Ursache sein? Der Code sollte eigentlich richtig sein, sonst würde es ja gar nicht funktionieren oder?
Gruß
Thomas
Lesezeichen