mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Unerwünshcter Reset im Programm Mega 16


Autor: Heinz (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
ich habe einen Ausschnitt aus meinem Programm:
;***************************************
.include "m16def.inc"
;***************************************
.cseg
.def zaehlen = r21
.def temp = r16
.def schieb = r17
.def schieb2 = r20
.def aus = r18
.def an = r19
.org 0x0000
        rjmp    init                  ; Reset Handler

init:  ldi     temp, LOW (RAMEND)    ; Stackpointer initialisieren
        out     SPL, temp
        ldi     temp, HIGH (RAMEND)
        out     SPH, temp
    LDI    R22, 0b11111111     ;initialisieren
    OUT    DDRA, r22
    OUT    DDRB, r22
    OUT    DDRC, r22
    OUT    DDRD, r22
    LDI    aus, 0b00000000
    LDI    an, 0b11111111
main:  LDI    schieb, 0b00000000  ;aufbau in rot
main1:  SEC
    ROL    schieb
    out    PORTA, schieb
    nop
    call warten
    CPI    schieb, 0b11111111
    BRNE  main1
main2:  LDI    schieb, 0b00000000
main3:  SEC
    rol    schieb
    out    PORTB, schieb
    nop
    call warten
    CPI    schieb, 0b11111111
    BRNE  main3
    call warten2
    out    PORTA, aus    ;alles aus
    out    PORTB, aus

Dann geht es im Programm mit Laden einer Konstante in ein Register 
weiter, also ähnlich wie es hier shcon alles war, nur auf andere Ports. 
Jedoch geht das Programm immer nur bis hier hin, was ich reinkopiert 
hab. Dann geht es wieder von vorne Los. Ich nehme an, das der µc ein 
Reset durchführt, aber woher kommt der?

Kann jemand helfen?

mfg

Autor: Martin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hast du eine endlosschleife am ende? Wenn nicht, läuft der MC sonstwohin 
und kann neustarten.

Autor: Kai G. (runtimeterror)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also
stop:
    rjmp stop

(Label und Befehl in einer Zeile ist unhübsch)

Autor: Martin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hast du irgentwo ein push ohne pop? dann funktioniert der call nichtmehr 
und die rücksprungadresse kann futsch sein.

Autor: Heinz (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ja, Endlosschleife habe ich, aber bis dort kommt er ja gar nicht. Er 
kommt ja vermutlich nur bis hier hin, wo ich das Programm hier 
hereinkopeirt habe, weil dann fangen die LEDs wieder von ovrn an zu 
leuchten.
Das mit dem Label und Befehl stimmt eigentlich, ändert aj aber auch 
nichts an der Funktion, würde ich jedenfalls meinen.

Autor: Heinz (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Push habe ich eigentlich auch nirgendwo verwendet.
Kann das sein, das das irgendwie mit der Watchdog oder so zusammenhängt, 
ich wüsste da aber auch nicht weiter.

Autor: Timmey (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Moin..

Initialisierst du denn den Rest der Hardware ?

Stellst du sicher, das kein Interrupt ausgelöst wird,
der dir dann irgendwo ins Hauptprogramm springt, das ja
mitten in der "Zeropage" liegt ?

(@init dürfte ja 0x0001 sein, wenn ich das richtig sehe)

Gruss,
Timmey

Autor: Knut Ballhause (Firma: TravelRec.) (travelrec) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wie sieht denn das ganze Programm aus? So stochert man im Dunkeln.

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> ich habe einen Ausschnitt aus meinem Programm:

In dem Ausschnitt ist kein Fehler, der zu einem Reset führt. Wenn es 
einen Reset gibt, kommt der aus einem anderen Programmteil.

Autor: Heinz (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also ok, hier dfas ganze Proggramm:
;***************************************
.include "m16def.inc"
;***************************************
.cseg
.def zaehlen = r21
.def temp = r16
.def schieb = r17
.def schieb2 = r20
.def aus = r18
.def an = r19
.org 0x0000

    rjmp  init

init:  ldi     temp, LOW (RAMEND)    ; Stackpointer initialisieren
        out     SPL, temp
        ldi     temp, HIGH (RAMEND)
        out     SPH, temp
    LDI    R22, 0b11111111     ;initialisieren
    OUT    DDRA, r22
    OUT    DDRB, r22
    OUT    DDRC, r22
    OUT    DDRD, r22
    LDI    aus, 0b00000000
    LDI    an, 0b11111111
main:  LDI    schieb, 0b00000000  ;aufbau in rot
main1:  SEC
    ROL    schieb
    out    PORTA, schieb
    nop
    call warten
    CPI    schieb, 0b11111111
    BRNE  main1
main2:  LDI    schieb, 0b00000000
main3:  SEC
    rol    schieb
    out    PORTB, schieb
    nop
    call warten
    CPI    schieb, 0b11111111
    BRNE  main3
    call warten2
    out    PORTA, aus    ;alles aus
    out    PORTB, aus
main4:  LDI    schieb, 0b00000000  ;aufbau in grün
main5:  SEC
    ROR    schieb
    out    PORTC, schieb
    nop
    call warten
    CPI    schieb, 0b11111111
    BRNE  main5
main6:  LDI    schieb, 0b00000000
main7:  ROL    schieb
    out    PORTD, schieb
    nop
    call warten
    CPI    schieb, 0b11111111
    BRNE  main7
    call warten2
    out    PORTC, aus    ;alles aus
    out    PORTD, aus
main8:  LDI    schieb, 0b00000000
    LDI    schieb, 0b00000000  ;aufbau in orange
main9:  SEC
    ROL    schieb
    ROR    schieb2
    out    PORTA, schieb
    out    PORTC, schieb2
    call warten
    CPI    schieb, 0b11111111
    BRNE  main9
main10:  LDI    schieb, 0b00000000
main11:  SEC
    ROL    schieb
    out    PORTB, schieb
    out    PORTD, schieb
    call warten
    CPI    schieb, 0b11111111
    BRNE  main11
    call warten2
    out    PORTA, aus    ;alles aus
    out    PORTB, aus
    out    PORTC, aus
    out    PORTD, aus
    nop
    call warten
    out    PORTA, an    ;schrift rot  
    out    PORTB, an
    nop
    call warten2
    out    PORTA, aus    ;alles aus
    out    PORTB, aus
    out    PORTC, an    ;alles grün
    out    PORTD, an
    nop
    call warten2
    out    PORTC, aus    ;alles aus
    out    PORTD, aus
    out    PORTA, an    ;alles orange
    out    PORTB, an
    out    PORTC, an
    out    PORTD, an
    nop
    call warten2
    out    PORTA, aus    ;alles aus
    out    PORTB, aus
    out    PORTC, aus
    out    PORTD, aus
    ldi    zaehlen, 0b00000000
main12:  clz
    out    PORTA, an    ;schrift rot  
    out    PORTB, an
    nop
    call warten3
    out    PORTA, aus    ;alles aus
    out    PORTB, aus
    call warten3
    inc    zaehlen
    cpi    zaehlen, 0b01011111
    brne  main12
    ldi    zaehlen, 0b00000000
main13:  clz
    out    PORTC, an    ;alles grün
    out    PORTD, an
    nop
    call warten3
    out    PORTC, aus    ;alles aus
    out    PORTD, aus
    call warten3
    inc    zaehlen
    cpi    zaehlen, 0b01011111
    brne  main13
    ldi    zaehlen, 0b00000000
main14:  clz
    out    PORTA, an    ;alles orange
    out    PORTB, an
    out    PORTC, an
    out    PORTD, an
    nop
    call warten3
    out    PORTA, aus    ;alles aus
    out    PORTB, aus
    out    PORTC, aus
    out    PORTD, aus
    call warten3
    inc    zaehlen
    cpi    zaehlen, 0b01011111
    brne  main14
    rjmp  main


; warte 1999998 Zyklen:
warten:    ldi  R23, $04
WGLOOP0:   ldi  R24, $C5
WGLOOP1:   ldi  R25, $EA
WGLOOP2:   dec  R25
           brne WGLOOP2
           dec  R24
           brne WGLOOP1
           dec  R23
           brne WGLOOP0
           ldi  R23, $01
WGLOOP:    dec  R23
           brne WGLOOP
      ret

; lange warten
warten2:  ldi  R27, $48
WGLOOP3:  ldi  R28, $BC
WGLOOP4:  ldi  R29, $C4
WGLOOP5:  dec  R29
          brne WGLOOP5
          dec  R28
          brne WGLOOP4
          dec  R27
          brne WGLOOP3
      ret
; kurz warten    
warten3:  ldi  R27, $0A
WGLOOP6:  ldi  R28, $C6
WGLOOP7:  ldi  R29, $C9
WGLOOP8:  dec  R29
          brne WGLOOP2
          dec  R28
          brne WGLOOP8
          dec  R27
          brne WGLOOP6

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

Sieh dir mal 'Warten3' an. Provoziert zwar keinen Reset. Aber Trotzdem.

MfG Spess

Autor: Timmey (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Naja, das RET von Warten3 wird hoffentlich nur verloren gegangen sein..

Und der jmp in die andere Warte-Routine .. naja ... ;)

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

Das auch. Ich meinte das 'brne WGLOOP2'.

MfG Spess

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Zwischen main8 und main9 ist auch noch ein Fehler (Initialiserung von 
schieb2). Ist aber unerheblich bzgl. der vermuteten Reset-Problematik.

Wie stabil ist die Spannungsversorgung? Kann es bei so vielen Ausgaben 
sein, dass du in einen Brownout Zustand kommst?

Autor: Franz (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
probier mal ein
.org 0x0100
vor dem label init damit du sicher aus den interruptvektoren raus bist.

.org 0x0000
rjmp init

.org 0x0100
init:

Autor: Kai G. (runtimeterror)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>.org 0x0100
>vor dem label init damit du sicher aus den interruptvektoren raus bist.

Ist kein SEI drin - sollte keinen Unterschied machen.

Er kann in seinem Falle sogar problemlos das
rjmp  init
weglassen, wenn er explizit auf das Aktivieren der Interrupts verzichten 
will.

Der Watchdog kann eigentlich kein Problem sein, da er nicht 
eingeschaltet wird ;)

Ist das Problem im Simulator nachvollziehbar?

Kannst du den Code so weit reduzieren, dass das Problem nicht mehr 
auftritt?


Noch ein paar Tipps/Anregungen unabhängig vom Problem:

Deine Dokumentation ist nicht wirklich hifreich beim Lesen des 
Programms. Ein Kommentar wie "initialisieren" sagt irgendwie nichts aus.

Gönn dir ruhig ein paar Leerzeilen, wenn ein neuer Abschnitt mit einer 
neuen Aufgabe anfängt und spendier einen Kommentar, der die Aufgabe des 
Blocks beschreibt.

Wenn du Schleifen erstellst empfehle ich diese wie in einer Hochsprache 
einzurücken:
; warte 1999998 Zyklen:
warten:
    ldi  R23, $04
    WGLOOP0:
        ldi  R24, $C5
        WGLOOP1:
            ldi  R25, $EA
            WGLOOP2:
                dec  R25
            brne WGLOOP2
            dec  R24
        brne WGLOOP1
        dec  R23
     brne WGLOOP0

     ldi  R23, $01
     WGLOOP:
         dec  R23
     brne WGLOOP
ret

Noch ein paar Kleinigkeiten:
LDI    R22, 0b11111111     ;initialisieren
; besser:
SER R22

LDI    aus, 0b00000000
; besser:
CLR aus

Wenn du schon Aliase für die Register verwendest (was gut ist!), 
solltest du das konsequenter Weise auch für alle anderen Register 
machen. Das vermeidet, dass du reservierte Register versehentlich mit 
anderen Aufgaben belegst und erhöht die Lesbarkeit deutlich.

Gruß

Kai

Autor: Heinz (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ok, Vielen rießen Dank für eure super guten Hilfen. Ich muss mich aber 
bei euch entschuldigen, es lag am µc, der war irgendwie hin. Ich habe 
einen neuen verwendet, da ging es, ich weis zwar nicht warum der andere 
µc immer von vorn angefangen hat, das ist schon komisch. Also mit dem 
neuen funktioniert es, also noch einmal vielen Dank für die vielen Tips, 
denn die nützen mir auf jeden Fall von der Übersicht her zumindest auch 
was für die nächsten Programme was.

mfg

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Bleibt die Frage, warum der AVR verreckt ist.

Stefan "stefb" B. wrote:
> Wie stabil ist die Spannungsversorgung? Kann es bei so vielen Ausgaben
> sein, dass du in einen Brownout Zustand kommst?

Welchen Strom zieht dein AVR bei den vielen OUTPUT-Aktionen insgesamt 
(zeitweise arbeiten 4 PORTs als Treiber) und an den einzelnen Ports?

Vielleicht überschreitest du die max. elektrischen Daten des AVRs und 
himmelst so nach einiger Zeit jeden AVR. Wird der AVR bei längerem 
Betrieb in dem Gerät warm?

Autor: Knut Ballhause (Firma: TravelRec.) (travelrec) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Untersuche mal die Fuses auf dem vermeintlich verreckten Controller, ob 
die sich von denen des neuen in irgendeiner Weise unterscheiden. 
Vielleicht liegt da der Hund begraben.

Autor: Heinz (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also Fuses ist kein Unterschied. Warm wird der AVR (der neue) eigentlich 
auch nicht wo wirklich.
Insgesamt ziehen die LEDs maximal 2A, aber zwischen µc und den LEDs ist 
ja noch eine Darlingotn-Scghaltung, also dürfte da auch nicht unbedingt 
was passieren.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.