Forum: PC-Programmierung GOTO-Befehl geht nicht (PIC 16F84A)


von Tobias Möhring (Gast)


Lesenswert?

Hallo!

Ich benutze einen PIC 16F84A mit dem PIC 16F84 ELV Emulator Programmer.
Dazu die Testplatiene mit den 8 LEDs, die aufleuchten sollen, wenn das
zugehörige Bit von PORTB auf 0 liegt.
Das Programm soll erst jede 2. LED ansteuern, dann warten und dann die
anderen ansteuern. Da das Umschalten nicht geklappt hat habe ich 2
Befehlszeilen eingefügt, die die beiden äußeren LEDs ansteuern und
diese Zeilen durch das Programm geschoben. damit habe ich die Zeile mit
dem Fehler identifiziert. Das Problem liegt offenbar darin, das der
goto-Befehl nicht ausgeführt wird.

Da ich den Quellcode leider nicht von meinem Programmierrechner
runterbekomme muß ich ihn abtippen und hier reinschreiben. Tut mir
leid, aber anders geht nicht........



    LIST    p=16F84A

#include <p16f84a.inc>

UNI1    equ    0Ch
UNI2    equ    0Dh
UNI3    equ    0Eh   ;nicht mehr benötigt, aber noch nicht gelöscht
        org    000h

        clrw
        bsf   03h,5    ;Bank1
        movwf 01h      ;Option reg löschen
        bsf   01h,5  ;Takt extern
        movwf  06h     ;PORTB als Ausgänge
        bcf    03h,5   ; Bank0
        movwf  06h     ;PORTB = 0

loop    movlw  0AAh
        movwf  06h     ;PORTB = 10101010
        movlw  0EFh
        movwf  0Eh     ;UNI3
        movwf  0Ch     ;UNI1

wart    movwf  0Dh     ;UNI2
        bsf    06h,0    ;Laufkontrolle (rechts 2 Lichter aus)

warte   decfsz  0Dh,1
        goto   warte ;Hier liegt das Problem(goto wird nicht gemacht)
        bcf    06h,7     ;Laufkontrolle (links 2 Lichter an)
        decfsz  0Ch,1
        goto   wart

        movlw  055h
        movwf  06h   ; PORTB = 01010101
        movlw  0FFh
        movwf  0Eh    ; UNI3
        movwf  0Ch    ; UNI1

warte3  movwf  0Dh    ; UNI2

warte4  decfsz  0Dh,1
        goto    warte4
        decfsz  0Ch,1
        goto    warte3

        goto loop

        END

von Andreas Jäger (Gast)


Lesenswert?

1) Der Programmanfang sollte so aussehen:
        :
        org    0x00
        goto   start
        org    0x04
        goto   PerInt

start:  org    0x10
        clrw
        bsf   03h,5    ;Bank1
        movwf 01h      ;Option reg
        :

2) Wenn du schon Variablen deklarierst, dann solltest du die auch
benutzen:

UNI1    equ    0Ch
UNI2    equ    0Dh
:
:
warte   decfsz  UNI2,1
        goto    warte

3) Ebenso solltest du die Registernamen verwenden, das erhöht die
Lesbarkeit und damit die Fehlersuche ungemein!

nicht
        movwf  06h     ;PORTB als Ausgänge
sondern
        movwf  PORTB   ;PORTB als Ausgänge


4) Wie hast du denn festgestellt, dass dein "goto" nicht ausgeführt
wird? Die Zeilen

warte   decfsz  0Dh,1
        goto   warte ;Hier liegt das Problem(goto wird nicht gemacht)

dürften wie die anderen Zeitschleifen im Echtbetrieb keine
bemerkenswerte Verzögerung verursachen - oder läuft dein PIC mit 1 Hz?

Andreas

von Tobias Möhring (Gast)


Lesenswert?

Sorry, das mit den Variablen hab ich wieder rausgenommen, weil ich
ausschließen wollte, das es daran lag.

Ich benutze den Interruot ja nicht, also dachte ich mir das macht nix,
wenn ich die Speicherstelle einfach mitbenutze.

Das es an dieser Zeile liegt habe ich wie folgt rausgefunden:

Zu Anfang hatte ich 2 Schleifen ineinander verschachtelt (also eine
Watreschleife, die FFh mal durchlaufen wird und eine Schleife enthält,
die bei jedem Durchlauf der äuseren FFh mal durchlaufen wird) Da meine
Oszillatorfrequenz bei 160 kHz liegen soll habe ich ausgerechnet, das
die Verzögerung FFh*FFh/160kHz also irgendwo zwischen 0,4 und 5
Sekunden betragen sollte (ja nachdem, wieviele Takte die ausführung des
Sprungs dauert). Dieses Programm verursachte aber nicht das gewünschte
blinken. Also habe ich es einmal als Simulation (in MPLAB) durchlaufen
lassen (dauerte eine Stunde bis ich bei der Stelle war, wo die Lampen
ihre Zustände ändern) Dabei hab ich mir PORTB angeschaut und
festgestellt, das alles wie gewünscht funktioniert.
Da ich aber auf der Testplatine nichts sehen konnte habe ich dann noch
eine 3. Schleife drübergebaut, um die Wartezeit zu erhöhen (auf
FFh*FFh*FFh Takte)
Da sich immer noch nix tat (die LEDs also zwar an gingen, aber dann
nicht wieder aus und die anderen an) habe ich die 2 Kontrollzeilen
eingefügt und durch den Quellcode geschoben, bis eine nicht mehr
ausgeführt wurde (konnte ich ja sehen, weil die entsprechende Lampe
nicht den gewünschten Zustand annahm). Nun habe ich die 2. Zeile
nachgezogen, um den Fehler einzugrenzen.

Dabei kam folgendes heraus:
Kontrollzeile vor dcfsz wird ausgeführt.
Kontrollzeile nach dcfsz (also da wo das goto hingehört) wird
ausgeführt.
Schiebe ich eine der Kontrollzeilen aber hinter dieses goto (wie oben)
so wird nur noch die erste ausgeführt, die zweite aber nicht.


Ich hoffe, jetzt kann man etwas besser sehen, was ich meine......

von Steffen (Gast)


Lesenswert?

Ich wüsste jetzt nicht, warum deine Zeitschleifen nicht richtig
durchlaufen werden. Das mit den Kontrollzeilen verstehe ich auch nicht
so ganz.

Lass das Ganze doch mal im Simulator im Einzelschrittbetrieb laufen. da
siehst Du genau was der PIC macht.

Mal ganz blöde gefragt (nimms nicht übel, wäre auch ne Erklärung)
Assembliert hast Du das Programm aber nach jeder Änderung?

Steffen

von Tobias Möhring (Gast)


Lesenswert?

Ich speichere nach jeder Änderung und gehe dann auf Make Project oder
Build All.

Wenn ich das richtig verstanden habe erzeuge ich also immer ein neues
HEX-File, in dem alle Änderungen enthalten sind.

Simulation unter MPLAB hab ich schon gemacht. Da mußte ich eine Stunde
warten (ich hab die Taste für Step irgendwann festgeklemmt) und dann
kam der Teil, wo er die Warteschleife verlassen hat und die LEDs
umgeschaltet wurden. Hat also alles wunderbar geklappt, nur auf der
Platine geht es nicht.

Jetzt habe ich mal einen älteren Programmer ausgepackt und den PIC
damit programmiert (PICSTART PLUS glaub ich(das Ding, das man direkt
aus MPLAB aktivieren kann)) aber da hab ich gar keine Reaktion
bekommen. Das kann nun aber auch daran liegen, das ich sowieso immer
das Problem habe, das das Programm überhaupt nicht anläuft, wenn ich
den PIC kurz vom Strom nehme (ja, ich habe POWER ON RESET bzw. POWER UP
TIMER gesetzt).

Was verstehst du an den Kontrollzeilen nicht?
Ich habe einfach 2 Bits von PORTB verändert. Diese Änderung ist
natürlich nur sichtbar, solange das Programm sich noch vor der
Umstellung von PORTB befindet (also nur bis die doppelte Warteschleife
oben (wart und warte) einmal durchlaufen wurde). Aber das reicht ja,
weil ich gar nicht bis dahin komme.
Die Kontrollzeilen machen also nichts anderes, als das gute alte printf
"test" mit dem man in in c Fehlersuche betreiben kann, indem man
zählt, wie oft test auf dem Bildschirm erscheint, wenn das Programm
läuft.

von Steffen (Gast)


Lesenswert?

Da fällt mir spontan nur noch der Watchdog ein. Ist der deaktiviert?

Bzgl. der Simulation kannst Du auch hinter deine Zeischleife einen
Breakpoint setzen und einfach mit Run starten. Unter Debug gibt es dann
eine Stopwatch, die die Zeit und die Durchlaufzyclen zählt. Ist für so
etwas ein gutes Hilfsmittel.

Kurz vom Strom und dann wieder dran ergibt noch lange kein Power-On
Reset, da der 16F84 kein Brouwn-out Detect (kurzer Spannungseinbruch
--> Reset) hat. Nach einem kurzem Stromausfall haben die Register
undefinierte Werte, dadurch kann es passieren, dass der PIC totalen
Mist macht.

Steffen

PS: Falls Du weiter mit den Prozessoren arbeiten willst, dann rate ich
dir zum 16F628(A). Der kann mehr und ist billiger. Der 16F84 stammt
noch aus der PIC-Uhrzeit.

von Tobias Möhring (Gast)


Lesenswert?

Danke!

Aber ich glaub ich hab das noch nicht ganz verstanden.....

Also ich hab den Watchdog aus. Ist das jetzt richtig oder falsch?


Wie bekomme ich denn dann einen Reset? Also wenn kurz vom Strom nehmen
nicht reicht????????

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.