toeoe
20.08.2005, 15:59
Hallo,
hab da ein ziemlich dummes Problem.
Hab ein Programm geschrieben, was ich nun auf meinen Atmega8L brennen wollte. TwinAVR meldet mir dann aber bei "66 of 73 Instructions" --> Flash memory write error"
Das komische ist aber, dass ich andere Programme noch wunderbar draufbrennen kann. Also kann es ja schonmal nicht am Chip liegen denk ich (der ist ja auch neu).
Hier mal der Code:
;Dieses Programm produziert ein Lauflicht. Jede halbe Sekunde geht die
;nächste LED an. Drückt man den Taster, ändert sich die Richtung des Lauflichtes
;Das Programm läuft in einer Endlosschleife durch.
;Problem des Prellens soll hier nicht mehr auftreten.
.include "m8def.inc"
.equ time1 = 65536-1 ;Damit wird der Timer1 vorgeladen, für 100ms
.equ Taster = PD2 ;Taster an D.2
.equ sperre = 7 ;Taster sperren (Hilfsvariable)
.equ laufrichtung = 0
.def tmp = r16 ;Mein Universallregister
.def statusLED = r17 ;In diesem Register wird gespeichert, welche LED gerade leuchtet
.def statusTaster = r18 ;Statusregister, wo die Sperre gespeichert ist
.def zaehler = r19 ;Mein Zählregister, hier zähl ich hoch,
;damit ich auf eine halbe Sekunde komme
.org 0x000
rjmp reset ;Interruptvektor "reset:"
.org OVF1addr
rjmp zeitum ;Interruptvektor für Timer1 Überlauf
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 PIND, Taster ;D.2 Pullups aktivieren
cbi PIND, Taster ;D.2 als Eingang
ldi statusLED, 0b00000100
out PORTB, statusLED ;Am Anfang soll erste LED leuchten
ldi zaehler, 0b00000000 ;Zähler auf 0 stellen
;Timer Register für 100ms 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)
out TIMSK, tmp
sei ;Interrupts zulassen
main:
cpi zaehler, 0b00000101 ;Ist zaehler = 5?
breq lauflicht ;JA -> springe zu lauflich
rjmp main ;NEIN -> springe zu main
lauflicht:
clr zaehler ;zaehler auf 0 setzen
sbrs statusTaster, laufrichtung ;Ist Bit0 = 1?
rjmp pruefRechts ;NEIN -> laufe rechtsrum
;JA -> lauf linksrum
pruefLinks:
cpi statusLED, 0b00000100 ;Leuchtet 3. LED?
breq wiederholenLinks ;Wenn JA, spring zu "wiederholen"
lsl statusLED ;Wenn NEIN´, Bit nach links verschieben -> nächste LED
rjmp ende ;spring zu ende
pruefRechts:
cpi statusLED, 0b00000001 ;Leuchtet 1. LED?
breq wiederholenRechts ;Wenn JA, spring zu "wiederholen"
lsr statusLED ;Wenn NEIN, Bit nach rechts verschieben -> vorherige LED
rjmp ende ;spring zu ende
wiederholenLinks:
ldi statusLED, 0b00000001
rjmp ende
wiederholenRechts:
ldi statusLED, 0b00000100
ende:
out PORTB, statusLED ;nächste LED leuchtet
rjmp main ;springe wieder zur main
;*****************INTERRUPTROUTINE FÜR TIMER1***************************
zeitum:
push tmp ;Rette Universallregister
out SREG, tmp ;Rette Statusregister
push tmp
inc zaehler ;Zähler erhöhen
sbis PIND, Taster ;Ist Taste gedrückt?
rjmp zeitum1 ;NEIN -> springe zu zeitum1
zeitum0: ;JA -> hier weiter machen
sbrs statusTaster, sperre ;Ist Sperre gesetzte?
rjmp zeitum2 ;NEIN -> springe zu zeitum1
rjmp zeitum3 ;JA -> springe zu zeitum2
zeitum1:
cbr statusTaster, (1<<sperre) ;Sperre löschen
rjmp zeitum3
zeitum2:
sbr statusTaster, (1<<sperre) ;Sperre setzen
;Aktion durchführen die beim Drücken des Tasters passieren soll
sbrs statusTaster, laufrichtung ;Ist Bit0 = 1?
rjmp setzeBitLauf ;NEIN -> auf 1 setzen
cbr statusTaster, (1<<laufrichtung);JA -> auf 0 setzen
rjmp zeitum3 ;Ende der Routine
setzeBitLauf:
sbr statusTaster, (1<<laufrichtung)
zeitum3:
;Timer1 neu laden
ldi tmp, HIGH(time1)
out TCNT1H, tmp
ldi tmp, LOW(time1)
out TCNT1L, tmp
pop tmp ;stelle SREG wieder her
out SREG, tmp
pop tmp ;stelle Universalregister wieder her
reti ;die Interrupt-Routine wird verlassen
;und es wird weiter im Hauptprogramm gearbeitet
An was kann das denn noch alles liegen?
Sagt mir nun bitte nicht, dass ich mal PonyProg oder yaap benutzen soll, diese beiden Programme gingen von Anfang an nicht, auch nicht mit dem alten Chip.
Ich hoffe ihr könnt mir weiterhelfen, denn ich bin kurz vor der Verzweiflung :(
Gruß
Thomas
hab da ein ziemlich dummes Problem.
Hab ein Programm geschrieben, was ich nun auf meinen Atmega8L brennen wollte. TwinAVR meldet mir dann aber bei "66 of 73 Instructions" --> Flash memory write error"
Das komische ist aber, dass ich andere Programme noch wunderbar draufbrennen kann. Also kann es ja schonmal nicht am Chip liegen denk ich (der ist ja auch neu).
Hier mal der Code:
;Dieses Programm produziert ein Lauflicht. Jede halbe Sekunde geht die
;nächste LED an. Drückt man den Taster, ändert sich die Richtung des Lauflichtes
;Das Programm läuft in einer Endlosschleife durch.
;Problem des Prellens soll hier nicht mehr auftreten.
.include "m8def.inc"
.equ time1 = 65536-1 ;Damit wird der Timer1 vorgeladen, für 100ms
.equ Taster = PD2 ;Taster an D.2
.equ sperre = 7 ;Taster sperren (Hilfsvariable)
.equ laufrichtung = 0
.def tmp = r16 ;Mein Universallregister
.def statusLED = r17 ;In diesem Register wird gespeichert, welche LED gerade leuchtet
.def statusTaster = r18 ;Statusregister, wo die Sperre gespeichert ist
.def zaehler = r19 ;Mein Zählregister, hier zähl ich hoch,
;damit ich auf eine halbe Sekunde komme
.org 0x000
rjmp reset ;Interruptvektor "reset:"
.org OVF1addr
rjmp zeitum ;Interruptvektor für Timer1 Überlauf
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 PIND, Taster ;D.2 Pullups aktivieren
cbi PIND, Taster ;D.2 als Eingang
ldi statusLED, 0b00000100
out PORTB, statusLED ;Am Anfang soll erste LED leuchten
ldi zaehler, 0b00000000 ;Zähler auf 0 stellen
;Timer Register für 100ms 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)
out TIMSK, tmp
sei ;Interrupts zulassen
main:
cpi zaehler, 0b00000101 ;Ist zaehler = 5?
breq lauflicht ;JA -> springe zu lauflich
rjmp main ;NEIN -> springe zu main
lauflicht:
clr zaehler ;zaehler auf 0 setzen
sbrs statusTaster, laufrichtung ;Ist Bit0 = 1?
rjmp pruefRechts ;NEIN -> laufe rechtsrum
;JA -> lauf linksrum
pruefLinks:
cpi statusLED, 0b00000100 ;Leuchtet 3. LED?
breq wiederholenLinks ;Wenn JA, spring zu "wiederholen"
lsl statusLED ;Wenn NEIN´, Bit nach links verschieben -> nächste LED
rjmp ende ;spring zu ende
pruefRechts:
cpi statusLED, 0b00000001 ;Leuchtet 1. LED?
breq wiederholenRechts ;Wenn JA, spring zu "wiederholen"
lsr statusLED ;Wenn NEIN, Bit nach rechts verschieben -> vorherige LED
rjmp ende ;spring zu ende
wiederholenLinks:
ldi statusLED, 0b00000001
rjmp ende
wiederholenRechts:
ldi statusLED, 0b00000100
ende:
out PORTB, statusLED ;nächste LED leuchtet
rjmp main ;springe wieder zur main
;*****************INTERRUPTROUTINE FÜR TIMER1***************************
zeitum:
push tmp ;Rette Universallregister
out SREG, tmp ;Rette Statusregister
push tmp
inc zaehler ;Zähler erhöhen
sbis PIND, Taster ;Ist Taste gedrückt?
rjmp zeitum1 ;NEIN -> springe zu zeitum1
zeitum0: ;JA -> hier weiter machen
sbrs statusTaster, sperre ;Ist Sperre gesetzte?
rjmp zeitum2 ;NEIN -> springe zu zeitum1
rjmp zeitum3 ;JA -> springe zu zeitum2
zeitum1:
cbr statusTaster, (1<<sperre) ;Sperre löschen
rjmp zeitum3
zeitum2:
sbr statusTaster, (1<<sperre) ;Sperre setzen
;Aktion durchführen die beim Drücken des Tasters passieren soll
sbrs statusTaster, laufrichtung ;Ist Bit0 = 1?
rjmp setzeBitLauf ;NEIN -> auf 1 setzen
cbr statusTaster, (1<<laufrichtung);JA -> auf 0 setzen
rjmp zeitum3 ;Ende der Routine
setzeBitLauf:
sbr statusTaster, (1<<laufrichtung)
zeitum3:
;Timer1 neu laden
ldi tmp, HIGH(time1)
out TCNT1H, tmp
ldi tmp, LOW(time1)
out TCNT1L, tmp
pop tmp ;stelle SREG wieder her
out SREG, tmp
pop tmp ;stelle Universalregister wieder her
reti ;die Interrupt-Routine wird verlassen
;und es wird weiter im Hauptprogramm gearbeitet
An was kann das denn noch alles liegen?
Sagt mir nun bitte nicht, dass ich mal PonyProg oder yaap benutzen soll, diese beiden Programme gingen von Anfang an nicht, auch nicht mit dem alten Chip.
Ich hoffe ihr könnt mir weiterhelfen, denn ich bin kurz vor der Verzweiflung :(
Gruß
Thomas