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.