Forum: Mikrocontroller und Digitale Elektronik PIC12F509 I/O Konfiguration GPIO1 geht nicht.


von Sebastian R. (pingu84)


Angehängte Dateien:

Lesenswert?

Hallo zusammen,

erst mal möchte ich mich für Antworten oder Hinweise jeglicher Art 
bedanken.
Doch nun zu meinem Problem. Ich habe eine kleine Platine mit einem 
PIC12F509. Mein Problem ist, dass die Ausgänge nicht das machen was sie 
sollen. Wenn man sich den Stromlaufplan anschaut, dann sieht man, dass 
GPIO 5 und 4 Eingänge sein müssen, während GPIO 0 bis 2 Ausgänge sein 
sollen. Ich muss dazu sagen, dass der Programmcode, der in der Schleife 
"HP" steht, nicht abgearbeitet wird. Dort blinkt die LED an GPIO 1. Das 
habe ich zu Testzwecken eingefügt. Mein Problem ist, wenn ich die I/Os 
so konfiguriere wie ich es brauche, dann leuchtet sie nicht mehr, wenn 
das "goto HP1" löscht wird. Warum ist das so? Ich schaue nun schon seit 
Stunden über mein Programm und sehe den Fehler nicht.

Zur weiteren Erklärung: Die Schaltung soll eine Weiche schützen. Da die 
Spulen der Weiche nicht für Dauerkontakt ausgelegt sind, können diese zu 
warm werden und die Spule brennt durch. Das ist teuer und ärgerlich zu 
gleich, da man auch noch an seiner Anlage schrauben darf. Daher die 
Idee, dass die Schaltung je nach Wahl die linke Spule bzw. die rechte 
Spule bestromt für ca. 2s. Danach soll nichts passieren. Wenn also ein 
Taster klemmt, dann kann ein überhitzen nicht mehr passieren. 
Gleichzeitig soll an GPIO 5 ein Überstrom gemessen werden können, wenn 
denn der Strom zu groß wird und über die LED angezeigt werden. So ist 
sicher gestellt, dass die Transistoren nicht beschädigt werden. Die 
Spule selbst wird einer pulsierenden Gleichspannung bestromt, statt mit 
den üblichen 14V AC. Anbei mein bisheriger Programmcode:

INIT
    Org 0
BEGIN
    movwf  OSCCAL

    movlw  B'11000000'    ;  ;Damit alle PORT-PINS benutzbar sind
    option          ;
    clrf   GPIO

    movlw   B'00011000'
    ;movlw   D'48'

    TRIS   GPIO
    clrf   GPIO
    goto  HP1


;----------------------------------------------------------------------- 
-----------------------------------------------------------
HP    ;Gelb gedrückt
    movlw  D'255'
    movwf  zaehl
    movwf  dauer


    bsf    LED
    call  pause

    bcf    LED
    call  pause

    movlw  D'128'
    movwf  zaehl
    movwf  dauer


    bsf    LED
    call  pause

    bcf    LED
    call  pause

    movlw  D'255'
    movwf  zaehl
    movwf  dauer


    bsf    LED
    call  pause

    bcf    LED
    call  pause



    goto  HP

;----------------------------------------------------------------------- 
-----------------------------------------------------------
HP1




    btfss  Gelbin
    bsf    Gruen

    btfss  Gelbin
    bcf    Gelb


    btfsc  Gelbin
    bsf    Gruen

    btfsc  Gelbin
    bcf    Gruen

    call  pause2

HP1
    bcf    LED

    bcf    Gruen
    bcf    Gelb
    goto  HP1

;----------------------------------------------------------------------- 
------------------------------------------------------------
pause                ;Pause erzeugen
    movfw  zaehl        ;die sehr klein ist
    movwf  zaehl1        ;empirisch ermittelt
    movfw  dauer
    movwf  zaehl2
wdh2
    btfsc  Strom
    goto  U_Strom



    decfsz   zaehl2,f
    goto   wdh2
    movfw  dauer
    movwf  zaehl2
    decfsz  zaehl1,f
    goto   wdh2
    return
;----------------------------------------------------------------------- 
------------------------------------------------------------
pause2                ;lange Pause erzeugen
    movlw  D'6'
    movwf  hilfe
pause2b
    movlw  D'255'
    movwf  zaehl
    movlw  D'255'
    movwf  dauer

    movfw  zaehl        ;die sehr klein ist
    movwf  zaehl1        ;empirisch ermittelt
    movfw  dauer
    movwf  zaehl2

    btfsc  Strom
    goto  U_Strom


wdh2b
    decfsz   zaehl2,f
    goto   wdh2b
    movfw  dauer
    movwf  zaehl2
    decfsz  zaehl1,f
    goto   wdh2b

    decfsz  hilfe
    goto  pause2b

    return
;----------------------------------------------------------------------- 
------------------------------------------------------------
U_Strom
    clrf  GPIO        ;Schalte alle Funktionen aus
    bsf    LED          ;Setze nur die LED
    movlw  D'128'        ;
    movwf  zaehl        ;
    movlw  D'128'        ;
    movwf  dauer        ;
    call  pause        ;
    bcf    LED          ;
    call  pause


    goto  U_Strom
;----------------------------------------------------------------------- 
------------------------------------------------------------
ende1
    btfss  Gelbin        ;wenn 0 Signal dann soll ge-
    ;goto  HP1          ;wechselt werden
    nop
    nop
    nop
    nop
    goto  ende1

ende2
    btfsc  Gelbin        ;wenn 0 Signal dann soll ge-
    ;goto  HP          ;wechselt werden 0= vereist
    nop
    nop
    nop
    nop
    goto  ende2

    end
;----------------------------------------------------------------------- 
------------------------------------------------------------

von Andreas H. (ahz)


Lesenswert?

Sebastian R. schrieb:
> Ich schaue nun schon seit
> Stunden über mein Programm und sehe den Fehler nicht.

Glaube ich sofort ;-)

Es wäre hilfreich, wenn Du die KOMPLETTE Asm Src posten würdest.

Was hast Du denn da gepostet ? Ist das der Code, der läuft ? Oder der 
Code der nicht läuft ? Oder irgend ein Zwischending ?

Grüße
Andreas

von Sebastian R. (pingu84)


Lesenswert?

Hallo Andreas!

Hier ist der komplette Code. Ich bastel aber an ihm ständig herum um den 
Fehler auszumerzen bzw. die Platine ans Leben zu erwecken. Den Code 
erstelle ich somit erst gerade. Eigentlich eine banale Sache. Ich muss 
sagen, dass ich mich eher mit den Mid-Range Typen auskenne. Diese 
kleinen PICs bereiten mir immer wieder Probleme, da es doch signifikante 
Unterschiede gibt, die ich nicht kenne. Das ist der komplette Code den 
ich zurzeit vorliegen habe. Vielen Dank für deine Mühe!



; Prozessor=12F509 interner Oszillator, Kein Watchdog, kein Reset,
        LIST    P=PIC12F509 ;, R=HEX
    #include "p12F509.inc"

  __CONFIG   _MCLRE_OFF & _CP_OFF & _WDT_OFF & _IntRC_OSC

;MCLRE_OFF


;Variablen und Register


zaehl      equ    9
zaehl1       equ   0A
zaehl2       equ   0B
dauer      equ    0C    ;Pause
hilfe      equ    11    ;Hilfsregister
often      equ    12    ;Schleifenzähler
ZPause      equ    13    ;Zusatzpausenzähler


#define  Gruen  GPIO,0    ;Ausgang grün
#define  LED    GPIO,1    ;LED Zustandsanzeige
#define  Gelb  GPIO,2    ;Ausgang gelb
#define  Gelbin  GPIO,4    ;Eingang gelb
#define  Strom  GPIO,5    ;Eingang Strombegrenzung




INIT
    Org 0
BEGIN
    movwf  OSCCAL

    movlw  B'11000000'    ;  ;Damit alle PORT-PINS benutzbar sind
    option          ;
    clrf   GPIO

    movlw   B'111000'
    ;movlw   D'48'

    TRIS   GPIO
    clrf   GPIO
    goto  TestP


;----------------------------------------------------------------------- 
-----------------------------------------------------------
TestP    ;Gelb gedrückt
    movlw  D'255'
    movwf  zaehl
    movwf  dauer


    bsf    LED
    call  pause

    bcf    LED
    call  pause

    movlw  D'128'
    movwf  zaehl
    movwf  dauer


    bsf    LED
    call  pause

    bcf    LED
    call  pause

    movlw  D'255'
    movwf  zaehl
    movwf  dauer


    bsf    LED
    call  pause

    bcf    LED
    call  pause



    goto  HP

;----------------------------------------------------------------------- 
-----------------------------------------------------------
HP




    btfss  Gelbin
    bsf    Gruen

    btfss  Gelbin
    bcf    Gelb


    btfsc  Gelbin
    bsf    Gruen

    btfsc  Gelbin
    bcf    Gruen

    call  pause2

HP1
    bcf    LED

    bcf    Gruen
    bcf    Gelb
    goto  HP1

;----------------------------------------------------------------------- 
------------------------------------------------------------
pause                ;Pause erzeugen
    movfw  zaehl        ;die sehr klein ist
    movwf  zaehl1        ;empirisch ermittelt
    movfw  dauer
    movwf  zaehl2
wdh2
    btfsc  Strom
    goto  U_Strom



    decfsz   zaehl2,f
    goto   wdh2
    movfw  dauer
    movwf  zaehl2
    decfsz  zaehl1,f
    goto   wdh2
    return
;----------------------------------------------------------------------- 
------------------------------------------------------------
pause2                ;lange Pause erzeugen
    movlw  D'6'
    movwf  hilfe
pause2b
    movlw  D'255'
    movwf  zaehl
    movlw  D'255'
    movwf  dauer

    movfw  zaehl        ;die sehr klein ist
    movwf  zaehl1        ;empirisch ermittelt
    movfw  dauer
    movwf  zaehl2

    btfsc  Strom
    goto  U_Strom


wdh2b
    decfsz   zaehl2,f
    goto   wdh2b
    movfw  dauer
    movwf  zaehl2
    decfsz  zaehl1,f
    goto   wdh2b

    decfsz  hilfe
    goto  pause2b

    return
;----------------------------------------------------------------------- 
------------------------------------------------------------
U_Strom
    clrf  GPIO        ;Schalte alle Funktionen aus
    bsf    LED          ;Setze nur die LED
    movlw  D'128'        ;
    movwf  zaehl        ;
    movlw  D'128'        ;
    movwf  dauer        ;
    call  pause        ;
    bcf    LED          ;
    call  pause


    goto  U_Strom
;----------------------------------------------------------------------- 
------------------------------------------------------------
ende1
    btfss  Gelbin        ;wenn 0 Signal dann soll ge-
    ;goto  HP1          ;wechselt werden
    nop
    nop
    nop
    nop
    goto  ende1

ende2
    btfsc  Gelbin        ;wenn 0 Signal dann soll ge-
    ;goto  HP          ;wechselt werden 0= vereist
    nop
    nop
    nop
    nop
    goto  ende2

    end
;----------------------------------------------------------------------- 
------------------------------------------------------------

von Sebastian R. (pingu84)


Lesenswert?

Der gepostete Code läuft nicht. Das Problem ist die INIT. Die 
Fehlerbeschreibung findest du in den eckigen Klammern.


INIT
    Org 0
BEGIN
    movwf  OSCCAL

    movlw  B'11000000'    ;  ;Damit alle PORT-PINS benutzbar sind
    option          ;
    clrf   GPIO

    movlw   B'111000'    [Sobald hier die letzten Bits auf 1 gestellt 
werden leuchtet die LED permanent. Der Controller reagiert nicht auf den 
BCF -Befehl! Wenn ich eine 0 wähle für Ausgang blinkt die LED. So soll 
es für die Testzwecke erst mal sein, später natürlich nicht. Aber GPIO 4 
und 5 müssen Eingänge sein. Wenn ich die LED ansteuern möchte, benötige 
ich aber die Eingänge.]
    ;movlw   D'48'

    TRIS   GPIO
    clrf   GPIO
    goto  TestP

Ich bin mir auch schon nicht sicher ob ich das Option-Register richtig 
setze. Hier kann ich aber rein packen was ich will. Der Fehler bleibt.

von Stephan (Gast)


Lesenswert?

Ich denke mal, der Fehler liegt in der SUB "pause".
Da steht:

wdh2
    btfsc  Strom
    goto  U_Strom

GPIO wird aber erst 0, wenn ein (hoher) Strom durch den Shunt 
tatsächlich fließt - Du landest also ohne Stromfluss permanent in 
"U_Strom" und kommst dann aus der Schleife auch nicht mehr raus, da von 
dort wieder pause aufgerufen wird - nach ein paar Runden hast Du einen 
Stack overflow.
Wahrscheinlich (ohne die ganze Logik jetzt zu checken, brauchst Du da 
ein

btfss Strom

In Init würde ich zusätzlich  das hier

    movlw   B'111000'

auf     movlw   B'00111000' ändern, um sicher zu gehen, dass hier keine 
Interpretationsspielräume (right/left justified) aufkommen.

von Sebastian R. (pingu84)


Lesenswert?

Vielen Dank Stephan!

Der Fehler ist gefunden. Ich habe mich so fixiert auf die I/O 
Konfiguration, dass ich nicht beachtet habe, dass ich die 
Kurzschlussabfrage schon drin habe. Nun klappt erst mal alles so wie es 
soll. Wunderbar!

Gruß

Sebastian

von Stephan (Gast)


Lesenswert?

prima, freut mich.

Gruß, Stephan

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.