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
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.
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.
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
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.
>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?
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
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.
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.
>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 :(
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.
--------------------------------------------- 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.
@ 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.
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
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.
bsf STATUS,C Carry 1 bcf STATUS,C Carry 0 clrf Status setzt Carry 0
BCF STATUS,RP0 ;register bank 0 ######### BsF STATUS,RP0 ;register bank 1 #########
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
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?
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
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?
holger (Gast) alles schon gesagt. Solche wie du sind eine große Hilfe!
>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.
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
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.
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>
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ß
>oder wird auch gleichzeitig "Led" auf Null getestet und Z gesetzt
meinte W
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
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.