PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Programm spingt immer zum Anfang zurueck



Ozzy
05.07.2006, 07:07
Hi,

ich hatte ein Programm für den ATMega16 geschrieben, dass auf dem auch gut funktioniert hat. Weil ich nun aber mehr Ports brauche, wollte ich das Programm auf dem ATMega128 simulieren, doch da passiert etwas merkwürdiges: statt im Hauptprogramm weiterzulaufen, springt er immer nach vorne zurück:



.cseg
.org 0x0000
rjmp init

init: inititalisierung (Stack, Ports,...)
main: hauptprogramm


Wenn er bei der Zeile "main" angekommen ist, springt er gleich wieder zu "rjmp init" zurück. Habt Ihr eine Idee dazu?

MfG, Ozzy

Madgyver
05.07.2006, 07:58
Ne idee nicht, aber kannste nicht den kompletten Quelltext angeben? Der FEhler liegt bestimmt nicht in den 5 Zeilen...

Ozzy
05.07.2006, 15:28
Kein Problem:



.include "m128def.inc"

.dseg
.org 0x0100

; benutzerdefinierte Variablen

clock_hour: .byte 1
clock_min: .byte 1
clock_sec: .byte 1

; Ende benutzerdefinierte Variablen

.cseg
.org 0x0000
rjmp init

; Systeminitialisierung
init: .org 0x0030
; Stackpointer initialisieren
ldi R16, high(RAMEND)
out SPH, R16
ldi R16, low(RAMEND)
out SPL, R16

ldi R16, 0xFF ; PORTA (Ausgabe)
out DDRA, R16
ldi R16, 0x00
out PORTA, R16

ldi R16, 0x00 ; PORTB (Eingabe)
out DDRB, R16
ldi R16, 0xFF
out PORTB, R16

ldi R16, 0x42 ; PORTD (Bidirektional)
out DDRD, R16
ldi R16, 0x00
out PORTD, R16

call lcd_init ; LCD initialisieren
call init_extint ; externe Interrups initialisieren
call init_timer ; timer inistialiseren
clr R16 ; loeschen der Uhrzeit
sts clock_sec, R16
sts clock_min, R16
sts clock_hour, R16
sei ; globale Interrupts aktivieren
ldi R16, (1<<INT1)|(1<<INT0)|(1<<INT2)
out GICR, R16 ; General Interrupt Control Register setzen

main: ldi R16, FF ; loesche das Display ;
call write_chr
ldi R16, LF ; Zeilenumbruch
call write_chr
ldi ZL, LOW(zeichenkette<<1) ; lade Zeichenkette für 2.Zeile
ldi ZH, HIGH(zeichenkette<<1)
call write_str ; Ausgabe 2te Zeile
haupt: ldi R16, VT ; Zurueck zum Anfang 1.Zeile
call write_chr
ldi ZL, LOW(leerzeichen<<1) ; Leerzeichen laden
ldi ZH, HIGH(leerzeichen<<1)
call write_str ; und ausgeben
lds R16, clock_hour ; Stunden laden
call write_bcd ; und ausgeben
ldi R16, ':' ; Doppelpunkt
call write_chr ; und schreiben
lds R16, clock_min ; min laden
call write_bcd
ldi R16, ':'
call write_chr
lds R16, clock_sec ; sec laden
call write_bcd
jmp haupt


So, das sollte es gewesen sein... Jetzt vielleicht eine Idee?

MfG, Ozzy

linux_80
05.07.2006, 16:51
Hallo,
das globale Interrupt-flag wird gesetzt (sei) , aber es ist keine einzige ISR definiert, wenn dann so ein IRQ auftritt, gehts immer wieder von vorne los.

Ozzy
05.07.2006, 17:07
Hi, danke für Deine Antwort. Ich hatte die Interrupts kurz rausgenommen, da er immer dachte, er hätte eins bekommen. Muss mich da noch mal etwas drum kümmern, die scheinen eben auch nicht gleich zu sein mit dem 32...
Eigentlich standen noch diese Interrupts da:


.org OC1Aaddr
jmp t1comp_isr
.org INT0addr
jmp int0_isr
.org INT1addr
jmp int1_isr
.org INT2addr
jmp int2_isr


Dann werde ich mal schauen, dass ich den Rest auch noch in den Griff bekomme.

Aber eine Frage habe ich noch: bei der Zeile:
"ldi R16, high(RAMEND)"
meldet der Compiler mir immer:
"AVR Simulator: Invalid opcode 0xffff at address 0x000001"

Hast Du noch eine Idee, was das sein könnte? Baut man beim 128 den STACK anders auf?

MfG, Ozzy

linux_80
05.07.2006, 20:07
Die Adresse 0x0001 bezieht sich nicht auf diesen Befehl, der steht nicht an Adresse 1,
an Adresse 1 steht nix, weil dein Programm erst bei 0x0030 beginnt.
Bzw. ist da ein Loch von 0x01 - 0x30 !