Forum: Mikrocontroller und Digitale Elektronik [pic] "echten" Reset im Programm durchführen


von Thomas M. (xt-fahrer)


Lesenswert?

Hallo,

ich habe im meinem Prog auf dem 16F88 folgende Struktur:

   org 0
Start:
   ;Variablen init, TRISA/B usw.

Mainloop:
   ; Unterprogrammaufrufe, Variablenabfrage


   btfsc STATUS,Z
   goto Mainloop
   goto Start


Wenn das Zeroflag gelöscht ist, soll wieder ganz an den Anfang 
gesprungen werden. Das macht das Programm wohl auch, allerdings werden 
die Variablen nicht resettet. Ich bekomme nicht dasselbe Ergebnis, wie 
wenn ich den Stromzufuhr unterbreche. Muß evtl. noch ein Bit in einem 
Register gesetzt/gelöscht werden, damit ich erreiche, daß sich das 
Programm bei goto Start genauso wie frisch nach dem Einschalten verhält?

Th.

von Sven P. (Gast)


Lesenswert?

Thomas M. schrieb:
> Wenn das Zeroflag gelöscht ist, soll wieder ganz an den Anfang
> gesprungen werden. Das macht das Programm wohl auch, allerdings werden
> die Variablen nicht resettet. Ich bekomme nicht dasselbe Ergebnis, wie
> wenn ich den Stromzufuhr unterbreche.
Dann programmiere halt anständige und vollständige 
Initialisierungsroutinen. Reset ist wohl in diesem Fall Murks.

von H.Joachim S. (crazyhorse)


Lesenswert?

die brutale Methode: einen Pin mit dem Reset-Eingang verbinden...

Im Normalfall sich solche Sachen aber nicht nötig.

von Thomas M. (xt-fahrer)


Lesenswert?

Sven P. schrieb:
> Thomas M. schrieb:
>> Wenn das Zeroflag gelöscht ist, soll wieder ganz an den Anfang
>> gesprungen werden. Das macht das Programm wohl auch, allerdings werden
>> die Variablen nicht resettet. Ich bekomme nicht dasselbe Ergebnis, wie
>> wenn ich den Stromzufuhr unterbreche.
> Dann programmiere halt anständige und vollständige
> Initialisierungsroutinen. Reset ist wohl in diesem Fall Murks.

Es geht um TRISA und B sowie Timer-Register. Die behalten ihre Werte, 
wenn ich im Programm zurück auf Start springe. Oder hast du was an "clrf 
TMR1H" auszusetzen? Da er es nicht macht, muß wohl noch irgendein Bit 
fehlen

von holger (Gast)


Lesenswert?

>Oder hast du was an "clrf
>TMR1H" auszusetzen?

Nichts, nur das in deinem Programm davon auch nichts
zu sehen ist.

von cdk59 (Gast)


Lesenswert?

Thomas M. schrieb:

> Es geht um TRISA und B sowie Timer-Register. Die behalten ihre Werte,
> wenn ich im Programm zurück auf Start springe. Oder hast du was an "clrf
> TMR1H" auszusetzen? Da er es nicht macht, muß wohl noch irgendein Bit
> fehlen

Ich kenne den F88 nicht, aber wahrscheinlich hast die falsche 
Speicherbank gewählt
Probier doch mal:

movlw   <wert für TRISA>
BANKSEL TRISA
movwf   TRISA
movlw   <wert für TRISB>
movwf   TRISB
BANKSEL TMR1H
clrf    TMR1H

von Thomas M. (xt-fahrer)


Lesenswert?

cdk59 schrieb:
> Thomas M. schrieb:
>
>> Es geht um TRISA und B sowie Timer-Register. Die behalten ihre Werte,
>> wenn ich im Programm zurück auf Start springe. Oder hast du was an "clrf
>> TMR1H" auszusetzen? Da er es nicht macht, muß wohl noch irgendein Bit
>> fehlen
>
> Ich kenne den F88 nicht, aber wahrscheinlich hast die falsche
> Speicherbank gewählt
> Probier doch mal:
>
> movlw   <wert für TRISA>
> BANKSEL TRISA
> movwf   TRISA
> movlw   <wert für TRISB>
> movwf   TRISB
> BANKSEL TMR1H
> clrf    TMR1H

Ok, ich hätte dazuschreiben sollen, daß im Debugger (MPLAB SIM) alles so 
läuft, wie es soll.
BANKSEL benutze ich korrekt.

Th.

von (prx) A. K. (prx)


Lesenswert?

Der Klassiker: Watchdog einrichten und "vergessen" ihn zu bedienen.

von holger (Gast)


Lesenswert?

>Ok, ich hätte dazuschreiben sollen, daß im Debugger (MPLAB SIM) alles so
>läuft, wie es soll.

Da läuft der Hardwaretimer ja auch nicht einfach weiter;)

von John B. (johnbauer)


Lesenswert?

Bei einem Reset über /MCLR oder den WDT bleiben einige Register 
unverändert, die bei einem Power-on Reset (POR) auf einen bestimmten 
Wert gesetzt werden. Um den Zustand nach dem Einschalten wieder 
herzustellen, musst Du auch wirklich die Spannungsversorgung trennen und 
wieder verbinden.

Wenn bestimmte Register, zu einem bestimmten Zeitpunkt, bestimmte Werte 
enthalten sollen, dann ist es auf jeden Fall die bessere Lösung wenn in 
Deinem Programm diese Werte dann auch gesetzt werden.

Thomas M. schrieb:
> Ich bekomme nicht dasselbe Ergebnis, wie
> wenn ich den Stromzufuhr unterbreche.

Was ist genau das Problem?

von Thomas M. (xt-fahrer)


Lesenswert?

John Bauer schrieb:
> Bei einem Reset über /MCLR oder den WDT bleiben einige Register
> unverändert, die bei einem Power-on Reset (POR) auf einen bestimmten
> Wert gesetzt werden. Um den Zustand nach dem Einschalten wieder
> herzustellen, musst Du auch wirklich die Spannungsversorgung trennen und
> wieder verbinden.
>
> Wenn bestimmte Register, zu einem bestimmten Zeitpunkt, bestimmte Werte
> enthalten sollen, dann ist es auf jeden Fall die bessere Lösung wenn in
> Deinem Programm diese Werte dann auch gesetzt werden.
>
> Thomas M. schrieb:
>> Ich bekomme nicht dasselbe Ergebnis, wie
>> wenn ich den Stromzufuhr unterbreche.
>
> Was ist genau das Problem?

Hier der vollständige Code bis zur Mainloop:
[code]
    org 0
Start   bsf    STATUS,RP0
        movlw  B'00000001'
        movwf  TRISA
        movlw  B'10010001'
        movwf  TRISB
    ;
        movlw b'11000001'
        movwf OPTION_REG


    clrf ANSEL
    bcf  STATUS,RP0


    clrf PORTA
    clrf PORTB
    clrf TMR1L
    clrf TMR1H

    movlw b'01111001'
    movwf T2CON      ;

              ;
    movlw b'00110000'
    movwf T1CON

    movlw 0x20
    movwf FSR
    clrf INDF
    incf FSR,F
    btfss FSR,6
    goto $-3
    ;
    ;
Mainloop
    btfss T1CON,TMR1ON
    bsf sswled

                usw.

                btfsc STATUS,Z
                goto Mainloop
                goto Start
[\code]

Das Hauptproblem ist, daß TMR1 nach einem goto Start-Befehl nicht 
aufhört zu zählen, was er nach Init-Wert von T1CON sollte, er startet 
nämlich erst innerhalb der Mainloop. Bei einem Sprung zur Start-Marke 
sollte er ausgeschaltet werden (movlw b'00110000' und movwf T1CON). 
Woher ich weiß, daß er weiterläuft? Weil am Pin sswled eine Leuchtdiode 
hängt, die nicht ausgeht, was sie nach einem clrf PORTB aber müßte.

Th.

von Ottmar K. (wil1)


Lesenswert?

Hallo Thomas,
Der korrekte und sichere Weg ist ganz einfach der, dass Du alle 
Variablen explicit löscht oder mit dem konkreten Wert belegst, den diese 
beim Programmstart auch haben sollen.
Sich darauf zu verlassen, dass beim Reset die Variablen "leer" sind ist 
fehlerhaft.

z.B.

INIT
  movlw  b'11111111'; Ausgangszustand Ausgänge = H = alle Segmente aus
  movwf  PORTB
  movlw  b'11110'   ; Digits 1-3 aus 4 (Einer) ein, Taster offen Bit0=L
  movwf  PORTA
  ;
  movlw d'110'      ; 1 ms kurze Verzögerungszeit
  movwf delay1
  ;
  clrf  Einer       ; Alle Zähler auf 0 Stellen
  clrf  Zehner
  clrf  Hunderter
  clrf  Tausender
MAIN

Jetzt sind die Daten gelöscht oder aber mit Wert belegt.

Gruss Ottmar

von Kein Name (Gast)


Lesenswert?

> Weil am Pin sswled eine Leuchtdiode hängt, die nicht ausgeht

Soweit ich die Sache überblicke, darf die LED ger nicht ausgehen.

Ein paar Microsekunden nach dem "clrf PORTB" kommt sofort das "bsf 
sswled". Das flackern geht so schnell, das kann man doch ger nicht 
sehen.

Nach dem "clrf PORTB"  eine Sekunde delay einbauen, damit man was sieht?

von Thomas M. (xt-fahrer)


Lesenswert?

Ottmar K. schrieb:
> Hallo Thomas,
> Der korrekte und sichere Weg ist ganz einfach der, dass Du alle
> Variablen explicit löscht oder mit dem konkreten Wert belegst, den diese
> beim Programmstart auch haben sollen.
> Sich darauf zu verlassen, dass beim Reset die Variablen "leer" sind ist
> fehlerhaft.

Aber tue ich nicht genau das? Ich lösche PORTA und B mit clrf und setze 
T1CON und T2CON mit konkreten Werten. Das, was du hier schreibst

> INIT
>   movlw  b'11111111'; Ausgangszustand Ausgänge = H = alle Segmente aus
>   movwf  PORTB
>   movlw  b'11110'   ; Digits 1-3 aus 4 (Einer) ein, Taster offen Bit0=L
>   movwf  PORTA
>   ;
>   movlw d'110'      ; 1 ms kurze Verzögerungszeit
>   movwf delay1
>   ;
>   clrf  Einer       ; Alle Zähler auf 0 Stellen
>   clrf  Zehner
>   clrf  Hunderter
>   clrf  Tausender
> MAIN

unterscheidet sich doch prizipiell nicht von meinem Code. Trotzdem macht 
der PIC im Realbetrieb nicht dasselbe wie im MPLAB.
Ich bin verwirrt... :-(

Th.

von Thomas M. (xt-fahrer)


Lesenswert?

Kein Name schrieb:
>> Weil am Pin sswled eine Leuchtdiode hängt, die nicht ausgeht
>
> Soweit ich die Sache überblicke, darf die LED ger nicht ausgehen.
>
> Ein paar Microsekunden nach dem "clrf PORTB" kommt sofort das "bsf
> sswled". Das flackern geht so schnell, das kann man doch ger nicht
> sehen.
>
> Nach dem "clrf PORTB"  eine Sekunde delay einbauen, damit man was sieht?

Nicht ganz richtig. TMR1 wird nur innerhalb der Mainloop gestartet, und 
zwar erst nach einem bestimmten Ereignis (wenn ein bestimmter Pin auf 
hight geht, der erst auf high geht, wenn ich eine Taste drücke). Wenn 
ich also an den goto Start komme und ich diese Taste nicht drücke, wird 
TMR1 auch nicht neu gestartet - so sollte es jedenfalls sein.

Th.

von Kein Name (Gast)


Lesenswert?

Die zwei Semikolon unter dem $-3 sind in Wirklichkeit die Tastenabfrage? 
Richtig so?

Würde da noch ein paar Pins für Debug-Leds missbrauchen. Eine nach dem 
"clrf PORTB" setzen, eine nach der Tastenabfrage setzen.

Einfach mal alle unmöglichsten Stellen kontrollieren - nicht auf den 
Timer versteifen.

von W.S. (Gast)


Lesenswert?

Thomas M. schrieb:
> Das macht das Programm wohl auch, allerdings werden
> die Variablen nicht resettet. Ich bekomme nicht dasselbe Ergebnis, wie
> wenn ich den Stromzufuhr unterbreche.

Deine Herangehensweise ist grundfalsch. Man kann zwar davon ausgehen, 
daß nach einem echten Reset die Register so gesetzt sind wie im Manual 
beschrieben, aber das ist ja nun nicht der Sinn eines Setups.

Also gehe ab Adresse 0 einfach davon aus, daß nichts was dich 
interessiert, so gesetzt ist, wie du es brauchst.

Bei mir steht am blutigen Anfang zumeist
 BCF   GIE
 CLRF  STATUS    ; löscht alle Flags und die RP0,1
 CLRF  PCLATH
 GOTO  setup

..
und zum Setup richtest du dir alles so ein, wie du es haben willst. 
Vergiß auch nicht, den eventuellen ADC einzurichten, sonst liest du an 
PortA nicht das, was du erwartest..


W.S.

von John B. (johnbauer)


Lesenswert?

Thomas M. schrieb:
> Weil am Pin sswled eine Leuchtdiode
> hängt, die nicht ausgeht, was sie nach einem clrf PORTB aber müßte.

Wenn ein clrf PORTB die LED ausschaltet, dann schaltet ein bsf sswled 
die LED ein (sie ist also vom Pin nach Masse geschaltet).

Mit den Befehlen
1
    btfss T1CON,TMR1ON
2
    bsf   sswled
wird die LED eingeschaltet, wenn TMR1ON=0 ist (Timer 1 aus). Wenn Timer 
1 läuft (TMR1ON=1) ändert sich der Zustand der LED nicht.

Wenn die LED erst angehen soll wenn Timer 1 an ist, dann brauchst Du 
diese Befehlsfolge:
1
    btfsc T1CON,TMR1ON
2
    bsf   sswled

Mir ist allerdings nicht klar, warum sich die LED nach einem Power-on 
anders verhalten soll.

Gruß
John

von Ottmar K. (wil1)


Lesenswert?

Hallo Thomas,

könnte es sein, dass PORTA von Anfang an nicht richtig initialisiert 
wurde und die "Analog-Falle" zuschnappt? Erst NACH dem 
Initalisierungscode 5.1 kannst du Digitale Eingänge in TRISA zuweisen. 
Du intialisierst aber bereits zuvor die Ein- und Ausgänge.

Start   bsf    STATUS,RP0      *bank select
        ----Aanmerkung-------------------
        *hier Code einfügen um PORTA
        *Analoge Inputs in Digitale Inputs
        *zu konfigurieren (siehe weiter unten)
        ----Anmerkung Ende---------------

        movlw  B'00000001'     ;*BinCode zur configuration In/Out
        movwf  TRISA           ;*Datenrichtungsregister PORTA


        movlw  B'10010001'
        movwf  TRISB

Im Abschnitt 5 des Datenblattes zum 16F88 sehe ich:
------------
Note:
On a Power-on Reset, the pins PORTA<4:0> are configured as analog
inputs and read as ‘0’.
------------

Dort wird auch gleich vorgeschlagen wie korrekt vorzugehen ist um 
DIGITALE Eingänge zu konfigurieren:

EXAMPLE 5-1, INITIALIZING PORTA
TABLE 5-1:  PORTA FUNCTIONS

BANKSEL PORTA ; select bank of PORTA
CLRF    PORTA ; Initialize PORTA by clearing output data latches
BANKSEL ANSEL ; Select Bank of ANSEL
MOVLW   0x00  ; Configure all pins
MOVWF   ANSEL ; as digital inputs
MOVLW   0xFF  ; Value used to initialize data direction
MOVWF   TRISA ; Set RA<7:0> as inputs

ich drück Dir die Daumen, dass Du Dein Problem bald lösen kannst!

Gruss Ottmar

von Meister E. (edson)


Lesenswert?

W.S. schrieb:
> CLRF  STATUS    ; löscht alle Flags und die RP0,1

Falsch. CLRF setzt definitiv das Z-Flag.

W.S. schrieb:
> CLRF  PCLATH
>  GOTO  setup

Das macht auch nur dann Sinn, wenn setup nicht ausserhalb von Page0 
liegt.

Gruß,
Edson

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.