Forum: Mikrocontroller und Digitale Elektronik Stack Monitor Disabled ????


von Alex (Gast)


Lesenswert?

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

von Läubi (Gast)


Lesenswert?

Ist der Stack vileicht nicht richtig Intialisiert?

von Alex (Gast)


Lesenswert?

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 ???

von Μαtthias W. (matthias) Benutzerseite


Lesenswert?

Hi

also für mich hört sich das so an also ob da im INT-Handler eine
unsymetrische Push-Pop Verteilung vorliegt.

Matthias

von Alex (Gast)


Lesenswert?

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.

von Μαtthias W. (matthias) Benutzerseite


Lesenswert?

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

von Alex (Gast)


Lesenswert?

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

von Μαtthias W. (matthias) Benutzerseite


Lesenswert?

Hi

ich hab jetzt nicht deinen ganzen Code analysiert aber du solltest dir
dringend über den Unterschied von rcall und rjmp klar werden.

Matthias

von Alex (Gast)


Lesenswert?

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 ?

von Thomas (Gast)


Lesenswert?

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

von Alex (Gast)


Lesenswert?

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
Noch kein Account? Hier anmelden.