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.