Forum: Mikrocontroller und Digitale Elektronik PIC 16F628 Fehler im Lauflicht


von Bruckschi (Gast)


Lesenswert?

Hallo,

ich beschäftige mich noch nicht seit langen mit Pics und bin noch bei 
den Übungsaufgaben (Blinker/Lauflicht), beim Blinklicht habe ich ein 
Problem.

Nach anlegen der Betriebsspannung fängt das Lauflicht an zu laufen. Es 
passiert aber das manchmal 2 Lichter laufen. Nach Ausschalten des 
Netzteils, läuft meistens wieder nur eine LED.

In der Simulation funktioniert alles einwandfrei, nur in der 
Wirklichkeit gibts Probleme.

Die Schaltung ist auf einer Steckplatine aufgebaut, sie besteht aus 
einem 16Mhz-Quarz, 2x33pF-Kondensatoren, 7 LEDs und 1 Widerstand.

Kann mir jemand meinen Fehler verraten?

mfg
Bruckschi

Das Assemblerfile:

  list p=16f826
;********************************
;*
;* Pinbelegung
;
;  PortA:     0
;             1
;             2
;             3
;             4
;  PortB:     0 LED
;             1 LED
;             2 LED
;             3 LED
;             4 LED
;             5 LED
;             6 LED
;             7 LED
;
;  Lauflicht am Port B
;
;***************************************
;
  #include <P16f826.INC>

;Configuration bits
    CONFIG      OSC = HS             ; HS 20 MHz
    CONFIG      PWRT = ON            ; power up timer on
    CONFIG      BOR = OFF            ; brown out detect off
    CONFIG      WDT = OFF            ; watchdog off
    CONFIG      LVP = OFF            ; lvp off
;
; Variablen
;
loops          Equ     0x22      ;Zähler für Warteschleife
loops2         Equ     0x23      ;Zähler für Warteschleife
;
;
;
;Port B auf Ausgänge stellen

init
  bsf               Status, RP0             ; Bank 1 umschalten
  movlw             B'00000000'             ; PortB alle Ausgänge
  movwf             TrisB
  bcf               Status, RP0             ; auf Bank 0 umschalten
  clrf              PortB                   ; alle LED ausschalten

; 1. LED einschalten


  clrf              PortB, 0
  bsf               PortB, 0                 ; LED an RB0 einschalten


; Lauflicht

Loop
  call              Wait    ;Wartezeit
  rlf               PortB, f  ;nächste LED einschalten
  goto              Loop


; Warteschleife für 250 ms

Wait
  movlw              D'250'               ;250ms Pause
  movwf              Loops                 ;250 in den Zähler schreiben

Wai
  Movlw              .110                 ;Zeitkonstante für 1ms
  movwf               Loops2
Wai2
  nop
  nop
  nop
  nop
  nop
  nop
  decfsz             loops2, F             ; 1ms vorbei
  goto               Wai2                  ; nein, noch nicht
  decfsz             Loops, F              ; 250 ms vorbei
  goto               Wai                   ; Nein, noch nicht
  retlw              0                     ; das warten hat ein Ende

  end

von Sergey (Gast)


Lesenswert?

MCLR mit 10K gegen VCC vergessen?

von dummy (Gast)


Lesenswert?

list p=16f826
  #include <P16f826.INC>

16F628?

von sales (Gast)


Lesenswert?

clrf              PortB, 0
das ist falsch, kann W auf 0 setzen.
clrf              PortB
ist richtig.

anstatt
 bcf               Status, RP0             ; auf Bank 0 umschalten
machst du
 clrf              Status

damit setzt du Carry auch auf null.

  rlf               PortB, f  ;nächste LED einschalten
da wird das Carry auch eingeschoben, also Achtung.
Weiters was ist, wenn du den 1.er rausschiebst, das hast du nicht drinn.
Nochwas, rlf PortB ist nicht gut, da dabei PortB eingelesen wird,
und da kann es passieren, daß ein bit eine eins ist, wo eine null sein 
sollte, lieber eine Variable nehmen, und diese dann auf PortB 
raussenden.

von pic (Gast)


Lesenswert?

clrf              PortB, 0
das ist falsch, kann W auf 0 setzen.
clrf              PortB
ist richtig.

anstatt
 bcf               Status, RP0             ; auf Bank 0 umschalten
machst du
 clrf              Status

damit setzt du Carry auch auf null.

  rlf               PortB, f  ;nächste LED einschalten
da wird das Carry auch eingeschoben, also Achtung.
Weiters was ist, wenn du den 1.er rausschiebst, das hast du nicht drinn.
Nochwas, rlf PortB ist nicht gut, da dabei PortB eingelesen wird,
und da kann es passieren, daß ein bit eine eins ist, wo eine null sein 
sollte, lieber eine Variable nehmen, und diese dann auf PortB 
raussenden.

von Michael M. (bruckschi)


Lesenswert?

MCLR habe ich wirklich nicht mit 10Kohm verbunden, benötige ich das 
wirklich, außer als Schutzfunktion für den PIC?

Pic 16F626 ist verkehrt, habe nur einen zu alten Stand vom Lauflicht 
hochgeladen, weil es nicht ging hab ich es mit noch ein paar 
rücksetztbedingungen von PortB versucht. Daher stammt auch das doppelte 
auf 0 setzten des PortB (clrf              PortB, 0).


clrf              PortB, 0
das ist falsch, kann W auf 0 setzen.
clrf              PortB
ist richtig.

Was ist daran falsch, dass W auf 0 gesetzt wird?

rlf               PortB, f  ;nächste LED einschalten
da wird das Carry auch eingeschoben, also Achtung.
Weiters was ist, wenn du den 1.er rausschiebst, das hast du nicht drinn.

Durch den rlf schieb ich doch Alle Bits in der Speicherzelle um eine 
Position nach links. Das Lauflicht läuft von Bit0 nach Bit7, dann kurz 
Pause und es fängt wieder von vorne an.

Nochwas, rlf PortB ist nicht gut, da dabei PortB eingelesen wird,
und da kann es passieren, daß ein bit eine eins ist, wo eine null sein
sollte, lieber eine Variable nehmen, und diese dann auf PortB
raussenden.

Könntest du bitte das Programm mit Variablen schreiben.

Mfg
Michael

von Sergey (Gast)


Lesenswert?

Wenn du MCLR nicht als I/O Pin verwendest (siehe CONFIG Fuses -> 
_MCLRE_ON / _MCLRE_OFF), dann sollte er mit 10K gegen VCC (+) verbunden 
sein.

Ansonsten resettet der PIC sporadisch bzw es passiert anderes 
undefiniertes Verhalten.

von dummy (Gast)


Lesenswert?

>MCLR habe ich wirklich nicht mit 10Kohm verbunden, benötige ich das
>wirklich, außer als Schutzfunktion für den PIC?

Jo, klasse, super Idee. Den Reset Pin floaten lassen.
Hast du noch alle Tassen im Schrank?

von Sven S. (stepp64) Benutzerseite


Lesenswert?

Michael Brucksch wrote:
>
> clrf              PortB, 0
> das ist falsch, kann W auf 0 setzen.
> clrf              PortB
> ist richtig.
>
> Was ist daran falsch, dass W auf 0 gesetzt wird?

Die Syntax von clrf lautet: clrf f
Also gibt es keinen zweiten Parameter. Demzufolge solltest du auch nur 
clrf PORTB schreiben ohne Komma und zweiten Parameter.

>
> rlf               PortB, f  ;nächste LED einschalten
> da wird das Carry auch eingeschoben, also Achtung.
> Weiters was ist, wenn du den 1.er rausschiebst, das hast du nicht drinn.
>
> Durch den rlf schieb ich doch Alle Bits in der Speicherzelle um eine
> Position nach links. Das Lauflicht läuft von Bit0 nach Bit7, dann kurz
> Pause und es fängt wieder von vorne an.
>
Die Bitschiebebefehle (rlf und rrf) schieben zwar alle Bits nach links 
oder rechts, sie schieben aber auch immer das aktuelle Carry-Flag mit 
rein (bei rlf wird das Carryflag auf Bit0 geschoben, bei rrf auf Bit7). 
Gleichzeitig wird das Bit welches rausgeschoben wird in das Carryflag 
geschoben. Wenn du also sicher sein willst, dass du nur Nullen bei 
deinem Lauflicht reinschieben willst, solltest du vor dem rlf ein bcf 
STATUS,C einfügen. Damit wird das Carryflag gelöscht und du kannst 
sicher sein, dass nur Nullen in dein Byte eingeschoben werden.

> Mfg
> Michael

von Michael M. (bruckschi)


Lesenswert?

dummy wrote:
>>MCLR habe ich wirklich nicht mit 10Kohm verbunden, benötige ich das
>>wirklich, außer als Schutzfunktion für den PIC?
>
> Jo, klasse, super Idee. Den Reset Pin floaten lassen.
> Hast du noch alle Tassen im Schrank?

Den Resetpin habe ich direkt mit VCC verbunden.

von Michael M. (bruckschi)


Lesenswert?

Habe das Programm nach den oberen Empfelungen abgeändert, der Fehler ist 
aber immer noch da. Kann es sein, dass es am Netzteil liegt, da der 
Fehler nicht passiert, wenn ich den Pic über MCLR resete.

von holger (Gast)


Lesenswert?

>Kann es sein, dass es am Netzteil liegt, da der
>Fehler nicht passiert, wenn ich den Pic über MCLR resete.

Ja, das kann sein.
Setzt im Configurationword mal BOR auf ON.
Das könnte helfen.

PS: Sorry für das Ding mit den Tassen :(

von chris (Gast)


Lesenswert?

Nein, Netzteil dürfte es nicht sein, obwohl der Resetpin sollte über 
einen Wiederstand gehen, da im Reset der Pin einen zu hohen Strohm 
zieht, und in Latch-up gehen könnte.

von chris (Gast)


Lesenswert?

Poste mal den Sourcecode, sowie das Hex-File.

von Michael M. (bruckschi)


Angehängte Dateien:

Lesenswert?

---------------------------------------------
PIC ASSEMBLER LISTING
Line    Address Opcode  Instruction
---------------------------------------------
0001    0000            ;Line removed by MPASMWIN preprocessor:   list 
p=16f828
0002    0000            ;********************************
0003    0000            ;*
0004    0000            ;* Pinbelegung
0005    0000            ;
0006    0000            ;  PortA:  0
0007    0000            ;    1
0008    0000            ;    2
0009    0000            ;    3
0010    0000            ;    4
0011    0000            ;  PortB:   0 LED
0012    0000            ;    1 LED
0013    0000            ;     2 LED
0014    0000            ;    3 LED
0015    0000            ;    4 LED
0016    0000            ;    5 LED
0017    0000            ;    6 LED
0018    0000            ;    7 LED
0019    0000            ;
0020    0000            ;
0021    0000            ;
0022    0000            ;  Lauflicht am Port B
0023    0000            ;
0024    0000            ;***************************************
0025    0000            ;
0026    0000            ;Line removed by MPASMWIN preprocessor: 
#include <P16f828.INC>
0027    0000
0028    0000            ;Configuration bits
0029    0000            ;Line removed by MPASMWIN preprocessor: 
CONFIG      OSC = HS             ; HS 20 MHz
0030    0000            ;Line removed by MPASMWIN preprocessor: 
CONFIG      PWRT = ON            ; power up timer on
0031    0000            ;Line removed by MPASMWIN preprocessor: 
CONFIG      BOR = OFF            ; brown out detect off
0032    0000            ;Line removed by MPASMWIN preprocessor: 
CONFIG      WDT = OFF            ; watchdog off
0033    0000            ;Line removed by MPASMWIN preprocessor: 
CONFIG      LVP = OFF            ; lvp off
0034    0000            ;
0035    0000            ; Variablen
0036    0000            ;
0037    0000            loops   Equ  0x22  ;Zähler für Warteschleife
0038    0000            loops2  Equ  0x23  ;Zähler für Warteschleife
0039    0000            ;
0040    0000            ;
0041    0000            ;
0042    0000            ;Port B auf Ausgänge stellen
0043    0000
0044    0000            init
0045    0000    1683      bsf  Status, RP0  ; Bank 1 umschalten
0046    0001    3000      movlw  B'00000000'  ; PortB alle Ausgänge
0047    0002    0086      movwf   TrisB
0048    0003    0183      clrf  Status    ; auf Bank 0 umschalten
0049    0004    0186      clrf   PortB    ; alle LED ausschalten
0050    0005
0051    0005            ; 1. LED einschalten
0052    0005
0053    0005
0054    0005    1406      bsf  PortB, 0  ; LED an RB0 einschalten
0055    0006
0056    0006
0057    0006            ; Lauflicht
0058    0006
0059    0006            Loop
0060    0006    2009      call   Wait    ;Wartezeit
0061    0007    0D86      rlf  PortB, f  ;nächste LED einschalten
0062    0008    2806      goto  Loop
0063    0009
0064    0009
0065    0009            ; Warteschleife für 250 ms
0066    0009
0067    0009            Wait
0068    0009    30FA      movlw   D'250'    ;250ms Pause
0069    000A    00A2      movwf  Loops    ;250 in den Zähler schreiben
0070    000B
0071    000B            Wai
0072    000B    306E      Movlw   .110    ;Zeitkonstante für 1ms
0073    000C    00A3      movwf  Loops2
0074    000D            Wai2
0075    000D    0000      nop
0076    000E    0000      nop
0077    000F    0000      nop
0078    0010    0000      nop
0079    0011    0000      nop
0080    0012    0000      nop
0081    0013    0BA3      decfsz  loops2, F  ; 1ms vorbei
0082    0014    280D      goto  Wai2    ; nein, noch nicht
0083    0015    0BA2      decfsz  Loops, F  ; 250 ms vorbei
0084    0016    280B      goto   Wai    ; Nein, noch nicht
0085    0017    3400      retlw  0    ; das warten hat ein Ende
0086    0018
0087    0018              end
---------------------------------------------
Number of errors = 0

Ich hoffe das war das richtige file. Ich habe das Programm auch auf 
einen 2. Pic vom selben Typ gebrannt, funktioniert aber leider auch 
nicht.

An Holger
Schon verziehen, bei digitalen Schaltungen verbinde ich immer alle nicht 
benötigten Pins mit Masse oder mit +. Nur bei testaufbauten bin ich zu 
faul Widerstände zu nehmen.

von holger (Gast)


Lesenswert?

@ Michael

Hast du das mit dem BOR auf ON versucht?
Wenn die Spannung deines Netzteils nur langsam
hochgeht dann kann das ohne aktivierten Brown Out Reset
zu deinem Fehler führen.

von Marabel (Gast)


Lesenswert?

Da wird das Carry-Flag ja immer noch nicht gelöscht...
Ich denke, das ist schon genau der richtige Tipp. Mach das mal, dann 
wirst du sehen, wie schön das funktioniert...

So, habe ich meinen Senf auch dazugegeben!

MfG - Marabel

von PicPic (Gast)


Lesenswert?

#include <P16f828.INC>

Pic16F628   ist das richtig?

von Michael M. (bruckschi)


Lesenswert?

Jetzt, kommt eine Anfängerfrage. Ich Entschuldige mich gleichmal im 
vorraus.

Setze ich nicht mit

clrf  Status    ; auf Bank 0 umschalten

auch das Carry mit auf 0.

Falls das nicht damit zurückgesetzt wird, mit welchen Befehl setzt ich 
es dann zurück.

Das mit Bor habe ich versucht, klappt aber nicht. Das selbe gilt für das 
abändern der include-datei in 16F628.

von PicPic (Gast)


Lesenswert?

bsf STATUS,C      Carry 1
bcf STATUS,C      Carry 0
clrf  Status    setzt Carry 0

von PicPic (Gast)


Lesenswert?

BCF  STATUS,RP0  ;register bank 0     #########
BsF  STATUS,RP0  ;register bank 1    #########

von Marabel (Gast)


Lesenswert?

Für Fragen brauchst du dich nicht zu entschuldigen: es gibt keine dummen 
Fragen - nur dumme Antworten...

Du hast eigentlich Recht: In deinem Programm wird nirgendwo das 
Carry-Flag beeinflusst.
ABER: Noch ist dein Programm kurz und überschaubar - das wird sich aber 
im Laufe der Zeit ändern...

Daher setzt man das Carry-Flag vor einem Rotationsbefehl grundsätzlich 
auf den Wert, dan man benötigt - schwupps, ist diese Fehlerquelle 
todsicher eliminiert und man kann weiter suchen...

An dieser Stelle besteht kein diskussionsbedarf: Man macht das so, 
fertig aus.

Aber genausowenig führt man Rotationsbefehle direkt am Port aus.
Wie schon oben beschrieben, macht man das mit einer Variablen und gibt 
diese dann auf dem Port aus.
Ebenfalls kein diskussionsbedarf...

Versteh mich nicht falsch, aber das sind nunmal die do's und dont's beim 
PIC-Programmieren.

Also, benutze zum Rotieren eine Variable und vor dem Rotationsbefehl 
löschst du das Carry-Flag.
Das kannst du doch mal eben schnell testen - dauert doch nur 2 Minuten 
zum Programmieren...

Es gibt da noch einige Stolperfallen, die du bei www.sprut.de nachlesen 
kannst.

MfG - Marabel

von Michael M. (bruckschi)


Lesenswert?

Jetzt gibts nur noch das Problem, dass ich das mit den Variablen noch 
nicht versucht habe. Es wird leider länger dauern. Könnte mir jemand, 
das Programm schreiben?

von Marabel (Gast)


Lesenswert?

Das darf doch nicht wahr sein...

Im Variablenteil:
LED equ 0x24;

Zeile 54 (bsf  PortB, 0) ersetzen und erweitern:
movlw 0x01;
movwf LED;

Zeile 61 (rlf  PortB, f) ersetzen und erweitern:
bcf STATUS,C;
rlf LED,f;
movf LED,w;
movwf PORTB;

Jetzt aber los!

Marabel

von holger (Gast)


Lesenswert?

Im Titel 16F628

Im obersten Post 16.09.2008
 list p=16f826

Und mitten drin #include <P16f828.INC>

Ja was denn nun?

>Könnte mir jemand, das Programm schreiben?

Was zahlst du?

von PicPic (Gast)


Lesenswert?

holger (Gast)

alles schon gesagt.

Solche wie du sind eine große Hilfe!

von holger (Gast)


Lesenswert?

>Solche wie du sind eine große Hilfe!

Ich tue mein bestes ;)

>Habe das Programm nach den oberen Empfelungen abgeändert, der Fehler ist
>aber immer noch da. Kann es sein, dass es am Netzteil liegt, da der
>Fehler nicht passiert, wenn ich den Pic über MCLR resete.

Es liegt wahrscheinlich nicht am Code.
Er hat es immer noch nicht geschafft den Brown Out Reset
zu aktivieren.

von juppi (Gast)


Lesenswert?

holger (Gast)

War auch nicht bös gemeint.

von chris (Gast)


Lesenswert?

init  clrf  Status
  bsf  Status,RP0
  clrf  TrisB
  nop
start  clrf  Status  ; interrupt vector
  clrf  Led
  clrf  PortB  ; all led off
  call  Wait
  movlw  0xff  ; led on
  movwf  PortB  ; output it
  call  Wait_1s
  clrf   PortB    ; alle LED ausschalten

Loop
  call  Wait
  bcf  Satus,0
  rlf  Led,W
  skpnz
  movlw  1
  movwf  PortB
  movwf  Led
  goto  Loop

Wait_1s  call    Wait2
Wait2  call    Wait
Wait  movlw   D'250'    ;250ms Pause
  movwf  Loops    ;250 in den Zähler schreiben
Wai
  Movlw   .110    ;Zeitkonstante für 1ms
  movwf  Loops2
Wai2
  goto $+1
  goto $+1
  gotp $+1
  decfsz  loops2, F  ; 1ms vorbei
  goto  Wai2    ; nein, noch nicht
  decfsz  Loops, F  ; 250 ms vorbei
  goto   Wai    ; Nein, noch nicht
  retlw  0    ; das warten hat ein Ende

  end

von gast (Gast)


Lesenswert?

Hallo  chris

Hast du das im Editor geschrieben?

Sehr interessant
>skpnz

Diesen Befehl kenne ich nicht

Ist auch nicht im dat. vom P16F628 (finde ihn nicht)

MPLAB zeigt aber kein Fehler an.

von chris (Gast)


Lesenswert?

skpnz  ist ein alias zu
btfsc 3,3
Es ist halt übersichtlicher.

es gibt auch

ADDCF <f>,<dst> Add carry to <f>, result in <dst>
B <addr> Branch
BC <addr> Branch on carry
BZ <addr> Branch on zero
BNC <addr> Branch on no carry
BNZ <addr> Branch on not zero
CLRC Clear carry
CLRZ Clear zero
SETC Set carry
SETZ Set zero
MOVFW <f> Move file to W
NEGF <f> Negate <f>
SKPC Skip on carry
SKPZ Skip on zero
SKPNC Skip on no carry
SKPNZ Skip on not zero
SUBCF <f>,<dst> Subtract carry from <f>, result in <dst>
TSTF <f> Test <f>

von gast (Gast)


Lesenswert?

Hallo chris

Werde mal alle testen, kannte ich nicht.
Wo steht das ausführlich?


>rlf  Led,W
>skpnz
Laut meiner Befehlstab.  wird doch nur C verändert nicht z,

oder wird auch gleichzeitig  "Led" auf Null getestet und Z gesetzt


Gruß

von gast (Gast)


Lesenswert?

>oder wird auch gleichzeitig  "Led" auf Null getestet und Z gesetzt

meinte  W

von chris (Gast)


Lesenswert?

stimmt, wollte eigentlich skpnc nehmen, aber da macht es nach dem
init keine pause, und wenn du das NOP von org 3 auf org 0 setzt, kannst 
du es auch debuggen.

So, beim Einschalten, eine Sekunde alle Leds an, als Funktionskontrolle,
danach 1/4 sek alle Leds aus, und dann beginnt das Lauflicht.

Loop
  call  Wait
  bcf  Satus,0
  rlf  Led,f
  movf LED,W
  skpnz
  movlw  1
  movwf  PortB
  movwf  Led
  goto  Loop

von chris (Gast)


Lesenswert?

stimmt, wollte eigentlich skpnc nehmen, aber da macht es nach dem
init keine pause, und wenn du das NOP von org 3 auf org 0 setzt, kannst 
du es auch debuggen.

So, beim Einschalten, eine Sekunde alle Leds an, als Funktionskontrolle,
danach 1/4 sek alle Leds aus, und dann beginnt das Lauflicht.
Sollte zufällig mal ein Interrupt kommen, macht das auch nicht, dann
startet das Ding halt von neuem, und du siehst es auch, aber dann kann 
kein Interrupt mehr zustandekommen.

Loop
  call  Wait
  bcf  Satus,0
  rlf  Led,f
  movf LED,W
  skpnz
  movlw  1
  movwf  PortB
  movwf  Led
  goto  Loop

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.