Hallo, Ich arbeite mit AVR-Studio 4.11, einem STK500 und einem Mega32 Nun trten beim debuggen fehler auf: nach einem Externen-Interrupt springt der Controller zunächst an die richtige Adresse um den Interrupt-Handler aufzurufen. Nach soweit ich im einzelschritt debuggen kann stimmt auch alles. Wenn ich jedoch mit F5 in den "Run"-Modus schalte springt er jedoch nachdem der InterruptHandler durchgeführt wurde auf die Einsprungadresse =0x0000 , dieja eigentlich die Resetfunktion Handelt. Mehrer Versuch lieferten schon unnachvollziehbare Sprünge im Programm. Ich wollte nun mittels des Stack-Monitors im "Workspace I/O " des AVR-Studios nachvollziehen wo die ganzen Sprungadressen hinterlegt sind. Es erscheint jedoch Programm-Stack "Disabled". ALLE Einträge im Stack-Monitor sind DISABLED. Wie kann ich diese Enablen ? Hat das was mit dem Fehler zu tun? Können die Adressen überhaupt mit dem Stackmonitor betrachtet werden ? Vielen Dank Alex
Kann sein,
aber wie initialisiere ich ihn sonst noch ausser:
ldi temp,LOW(RAMEND)
out SPL, temp
ldi temp,HIGH(RAMEND)
out SPH, temp
Muss ich sonst noch etwas initialisieren um den Stack Angezeigt zu
bekommen ???
Hi also für mich hört sich das so an also ob da im INT-Handler eine unsymetrische Push-Pop Verteilung vorliegt. Matthias
Hallo, was bedeutet eine "unsymeretrische Push-Pop Verteilung"? Bis zu dem Zeitpunkt an dem der Interrupt auftritt habe ich noch gar kein Push oder Pop verwendet, dies würde erst danach kommen, was ja aber nicht geschieht denn der Interrupt Handler den ich möchte wird ja nicht ausgeführt.
Hi ach deine ISR wird schon garnicht angesprungen. Merkwürdig. Zeig mal deinen Quellcode. In C könnte es auch ein falsch benamter Interrupt im SIGNAL() Makro sein. Matthias
Hier isser:
Er springt schon beim ersten Interupt auf org0x0 !!!????
.include "m32def.inc"
.def temp = r16
.def anz = r17
.def SollSchritte= r18
.def lowByte = r19
.def highByte = r20
;.def ADK = r27
.def AusgabeByte = r21
.def GrOben = r22
.def GrUnten = r23
;**********Verzug************
.def Delay =r24
.def Delay2 =r25
.cseg
.org 0
rjmp reset
rcall CountStart ;IRQ0 Handler
reti ; IRQ1 Handler
reti ; IRQ2 Handler
reti ;TIMER2 COMPARE
reti ;TIMER2 OVERFLOW
reti ;TIMER1 CAPTURE
rcall incre ;TIMER1 COMPARE A
.org $010
rcall incre ;TIMER1 COMPARE B
reti ;TIMER1 OVERFLOW
reti ;TIMER0 COMPARE
.org $016
reti ;TIMER0 OVERFLOW
reti ;SPI Transfer beendet
.org $01a
reti ;UART byte empfangen
.org $01c
reti ;UART datenreg
.org $01e
reti ;UART transfer beendet
reti ;ADC conversion
reti ;EEPROM ready
reti ;anacomp
reti ;Two Wire Serial
reti ;store program
.cseg
.org $02a
;**********************************************************
DLY:
dec Delay
brne DLY
dec Delay2
brne DLY
;dec Delay3
;brne DLY
ret
reset:
ldi temp,LOW(RAMEND) ;LOW-Byte der obersten RAM-
out SPL, temp
ldi temp,HIGH(RAMEND) ;HIGH-Byte der obersten RAM-
out SPH, temp
; ldi Delay3,35 ;Verzögerungs-ZEIT
ldi anz,0
ldi SollSchritte, 20 ;Schritte für 1/100
rcall DLY
ldi GrOben, 133 ; Mittelstellung des Knüppels
ldi GrUnten,127 ;
ldi r16, 0x1 ;PA1 als Ausgang ins Arbeitsregister r16 laden
out DDRA, r16
sei ; interrupts generell aktivieren
ldi temp, 0b00100000
out DDRD, temp ; PORTD configured for Ausgang
;ldi temp, 0xFF
;out DDRC, temp ; PORTC configured for output
;ldi temp, 0xFF
;out PORTC, temp ; LEDs ausschalten
ldi temp,0b00000000 ; steigende Flanke
out MCUCR, temp
ldi temp,0b01000000 ; INT0 und INT1 aktivieren
out GICR,temp
ldi temp,0b11000001 ; steigende Flanke und Bit-Einstellung
out TCCR1A, temp
ldi temp,0b01111111 ; Vergleich LOW (Compare)
out OCR1AL, temp
ldi temp,0b0000000 ; Vergleich HIGH (Compare)
out OCR1AH, temp
ldi temp,0b00010000 ; Interrupts ein
out TIMSK, temp
rcall main
main:
;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;***********************************************************************
Start:
;***********ADC initialisieren mit "Free Run" und Vorteiler 128:
ldi temp,7
;ldi temp, ADK ;Spannungsmessung an PA7
out ADMUX, temp
ldi temp, ((1<<ADEN)|(1<<ADSC)|(1<<ADFR)) + 7 ;
out ADCSRA, temp
;*********** Wir messen Analog-Pegel an PA7 **************
measurement:
sbi ADCSRA, ADIF ;logisch "1" löscht ADIF flag !
;ADC einlesen:
in lowByte, ADCL ;immer zuerst low byte lesen
in highByte, ADCH ;danach das mittlerweile gesperrte high byte
;rcall Konv
;********* aus 10 Bit mach 8 Bit **************************
Konv:
lsr lowByte ; Rechtsschieben
lsr lowByte ; Rechtsschieben
ldi temp,64
MUL highByte,temp ;High *64
mov highByte,r0 ; errechneten Wert highByte zuweisen
Add lowByte,highByte ; High + Low
rcall Nullstellung
;************ Knüppelstellung bestimmen **********************
Nullstellung:
;;************ unter 127 ---> nach unten
cp LowByte,GrUnten
brlo NachUnten
;;************* über 135 ---> nach oben
cp LowByte,GrOben
brsh NachOben
;;************* wenn dazwischen dann NIX
rjmp nix
;**************** Analog-Werte und Richtung an PC0-7 ausgeben
NachUnten:
ldi r16, 0b00000000 ;Drehrichtung rücksetzten(PA6)
out PORTA, r16
ldi temp, 2
mul LowByte,temp ;Low *2
mov AusgabeByte,r0 ; errechneten Wert Ausgabe zuweisen
com AusgabeByte
rjmp DACAus
nix:
;ldi r16, 0b00000000 ;Drehrichtung rücksetzten (PA6)
;out PORTA, r16
ldi AusgabeByte,0
;com AusgabeByte
rjmp DACAus
NachOben:
ldi r16, 0b00000001 ;Drehrichtung 1 DIR PA6
out PORTA, r16
subi LowByte,128
ldi temp, 2
mul LowByte,temp ;Low *2
mov AusgabeByte,r0 ; errechneten Wert Ausgabe zuweisen
ldi temp,1
add AusgabeByte,temp ; noch eins dazuzählen auf 255 !!!!
;neg AusgabeByte
rjmp DACAus
;************* Werte zu PC0-7
schreiben*************************************
DACAus:
ldi r16, 0xFF ;0xFF ins Arbeitsregister r16 laden
out DDRC, r16
out PORTC, AusgabeByte
rjmp loop
;***********************************************************************
******
; ldi ADK,6
; rcall ADmess
; ldi ADK,5
; rcall ADmess
; ldi ADK,4
; rcall ADmess
; ldi ADK,3
; rcall ADmess
; ldi ADK,2
; rcall ADmess
;ADmess:
; rcall Start
; rcall measurement
Ausgabe1:
ldi r16, 0xFF ;0xFF ins Arbeitsregister r16 laden
out DDRB, r16 ;Inhalt von r16 ins IO-Register DDRB
ausgeben
ldi r16, 0b00000001 ;0b11111100 in r16 laden
com r16
out PORTB, r16 ;r16 ins IO-Register PORTB ausgeben
rjmp loop ;Sprung zur Marke "ende" -> Endlosschleife
loop:
ldi temp,7
rcall Start
;--------------------------------------------------
incre:
inc anz
rcall verg
verg:
cp anz,SollSchritte
brsh Ruck
reti
Ruck:
push temp
ldi anz,0
ldi temp,0b00000000 ; Prescaler aus (0b00000001 )
out TCCR1B, temp
pop temp
ret
CountStart:
push temp
ldi temp,0b00000001 ; Prescaler ein !!!!!!!!!!!
out TCCR1B, temp
pop temp
ret
Hi ich hab jetzt nicht deinen ganzen Code analysiert aber du solltest dir dringend über den Unterschied von rcall und rjmp klar werden. Matthias
Ja das stimmt wohl. Ich kann mir den unterschied zwischen rcall und rjmp nicht erklären. hnlich geht es mir auch mit dem reti und ret, huerbei ist auch das Problem an welcher Stelle ich éinen dieser beiden Befehle einzetzten soll. Ich hab zwar schon in einem Buch daüber gelesen, dort ist es aber nicht Richtig erklärt. Kann mir das mal jemand erklären ?
rcall ist ein Unterprogrammsprung, d.h. es wird nicht nur gesprungen sonder die Adresse nach dem Sprungbefehl wird auf den Stack gelegt und mit einem ret kann an diesen zurückgekehrt werden. Der reti Befehl macht das ganze für eine Interruptunterbrechung.. Gruß Thomas
OK, vielen Dank Wie kann ich nun vervolgen welche Adressen wie der Reihe nach auf dem Stack abgelegt werden und bei ret wieder abgerufen, bzw mit Push-Pop. Es wird doch im AVR-Studio 4.11 möglich sein dies beim debuggen zu beobachten ?
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.