PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : PIC Fallen



PICture
31.03.2006, 00:49
Hallo!

Ich habe das Thema geöffnet um Fallen vom PICs zu sammeln.

Ich bin sehr dankbar für alle Warnungen im voraus. Solche Sammlung finde ich sehr nutzlich für alle die Programme entwickeln.

MfG

kalledom
31.03.2006, 11:43
Hallo PICture,
hier ist eine weitere 'Falle': https://www.roboternetz.de/phpBB2/viewtopic.php?t=18526, hier sind noch mehr: http://www.domnick-elektronik.de/piccheck.htm bei 'Assembler-Programmier(er)-Fehler'

PICture
31.03.2006, 19:19
Hallo kalledom!

Vielen Dank für Deine Links. Weil es sich auf andere Typen von PICs erweitert hat, werde ich das Titel des Treads ändern.

Schöne Grüsse
Andreas

Goblin
02.04.2006, 10:01
http://www.sprut.de/electronic/pic/fallen/fallen.html

Spruts Fallenseite

PICture
12.06.2006, 04:20
Hallo!

Es Betrift den PIC18F252, aber wahrscheinlich gilt für alle PIC18FXXX.

Ich wollte, eine Sequenz:

nop
nop

durch

goto $+2

ersetzen.

Gemessene Ausführungszeit beträgt aber 3 anstatt 2 Takten. Natürlich ein Befehl $+1 schickt den Prozessor in "Nirvana", weil die Adressen nur gerade seien dürfen. Wen jemand eine Verzögerung um 3 Takte braucht, kann also "goto $+2" anwenden.

Erklärung vom Microchip Forum, wo ich selbstverständlich nachgefragt habe:

The second instruction word of all of the 2-word instructions has '1111' in its upper nibble. This will make it always execute as a 'nop'.

If this weren't the case, a skip instruction followed by a 2-word instruction wouldn't work correctly since the PIC would execute something unintended. Execution would be unpredictable in that it would be determined by whatever happened to be in that second instruction word.

MfG

BiGF00T
12.06.2006, 08:31
Absolut unqualifizierte Antwort aber ich konnte es mir leider nicht verkneifen 8-[
Es ist Montag und mein Kopf ist noch beim booten...

http://xs102.xs.to/xs102/06241/scnr.jpg.xs.jpg (http://xs.to/xs.php?h=xs102&d=06241&f=scnr.jpg)

*Mario*
12.06.2006, 11:59
Hallo PICTure,

irgendwie stehe ich bei Deinem Problem auf dem Schlauch. Um drei Takzyklen zu warten, benutze ich folgende Sequenz:

goto $+1
nop

Die Adresse wird in "words" gezählt, d.h. ein goto $+1 springt an den Beginn der folgenden Befehls. Bei mir jedenfalls funktioniert obige Sequenz tadellos (PIC16). Bei PIC18 hab ich noch nicht probiert, denke aber dass das auch geht.

Grüße
Mario

PICture
13.06.2006, 08:30
Hallo *Mario*!

Das geht sicher nicht.

Der Hauptunterschied zwischen den Famillien 12+16F und 18F liegt in der Organisation des Programmspeichers.

Bei den 12F und 16F PICs ist der Programmspeicher 14 Bit breit und jede Adresse enthält einen vollständigen (gültigen) Befehl.

Bei den 18F PICs ist der Programmspeicher 8 Bit breit und nur jede gerade Adresse enthält einen gültigen Befehl, da jeder 16-Bit Befehl im Speicher 2 Byte lang ist.

Deswegen "goto $+1" schickt den Prozessor vom 18F in die Mitte des nächsten Befehls, was er nicht interpretieren kann, und das Programm hängt.

Das ist, so wie ich es jetzt sehe, auch eine Falle für Umsteiger von 12F und 16F auf 18F PICs.

MfG

*Mario*
15.06.2006, 22:20
Hallo PICture,

danke für die Erklärung, wusste ich nicht! Da ich demnächst mein Programm auf einen PIC18 portieren werde (wegen USB) wäre ich da sicher reingefallen.

Super Tipp, Dank Dir!

Gruß
Mario

PICture
07.07.2006, 16:42
Hallo!

Im Microchip Forum haben ein Problem mit dem PIC16F630 gehabt. Sie wollten RA0 bis RA2 als digital I/O eintellen. Ich habe das Problem auch mal gehabt und herausgefunden, dass es bei der Initialisiereung von PORTA, anstatt fehlerhaft im Datenblatt angegebenem:

movlw 5
movwf CMCON

stehen muss

movlw 7
movwf CMCON

Seit ich mein Beitrag dort gepostet habe, hat sich keiner mehr gemeldet. :)

MfG

orph
09.07.2006, 11:28
moin

Wer den PIC 16F88 mit IO-Pins an PortA und RB6+RB7 sollte in der Assembler-Initialisierung in die Bank 1 folgenden Code schreiben:

movlw B'00000000'
movwf ANSEL

Und nicht etwa was auf der Sprut-Homepage steht:

MOVLW 0x06
MOVWF ADCON1


(hat mich lange aufgehalten ;-))

mfg orph

PICture
09.07.2006, 11:33
Hallo orph!

Vielen Dank! Vielleich sollten wir noch ein Thema "Sprut Fallen" eröffnen ? :)

MfG

kalledom
23.08.2006, 23:19
Ein weiterer Fall von einer Falle oder einfach nur ](*,)
Beim PIC 16F877A (PIC 16F87X) PORTE mit seinen 3 Pins die Richtung auf Ausgänge umschalten (sind nach Reset Eingänge):

movlw 11111000b ; 0=Ausgang / 1=Eingang
movwf TRISE
Diese zwei Befehle kosteten mich 3 Tage Suche, warum eine an PortD angeschlossene 7-Segment-Anzeige mal leuchtet und mal nicht.
Wenn man dann irgendwann im Datenbuch nachschaut, was denn eigentlich die Bits 7...3 im TRISE machen, ..... auweia, durch TRISE, 4 = 1 ist PORTD im PSP-Mode, .... :-k
Die Richtung also nur durch AND auf 0 setzen und die restlichen Bits schön in Ruhe lassen:

movlw 11111000b ; 0=Ausgang / 1=Eingang
andwf TRISE ; AND !!!

PICture
26.08.2006, 09:40
Hallo!

Ich weiss nicht ob es eine Falle ist, aber seit ein paar Monaten ist mir nicht gelungen weder Haupt- noch Time1 Oszillator mit Uhrenquartz 32768 Hz zum oszillieren zu bringen und musste ein externen Oszillator mit zwei CMOS Inverter anwenden. Sogar eine Suche im Microchip Forum hat nichts gebracht. Ist es in realer Hardware (nicht im Simulator) wirklich unmöglich ?

MfG

PICture
02.09.2006, 23:02
Hallo!

Beim PIC18F252 habe ich zwei mir bisher enbekannte Fallen entdeckt.

Ich wollte zwei Taster, die auf Portpins paralell zum Display angeschlossen sind einlesen und auswerten. Dafür muss man die zwei Pins vom I/O Port vom Ausgang auf Eingang durch TRIS Register umschalten. Das habe ich mehrmals ohne Probleme gemacht. Diesmal wollte ich es aber eleganter machen: nur die zwei Pins ohne die andere zu beanflüssen mit OR setzen, Taster auswerten und wieder mit AND löschen. Leider funktioniert es nicht. Ich vermute, das TRIS Register nur beschreibbar und nicht ablesbar ist, da nach dem Einschreiben des Registers mit richtigem Wert funktioniert's. Im Datenblatt habe ich darüber nichts gefunden.

Sofort nach dem Umschalten dieser zwei Pins, konnte ich leider die Taster nicht einlesen, und erst nach Vezögerung von mindestens 3xNOP (3x0,1 us) habe ich es geschafft. Wahrscheinlich im Simulator hätte es keine Probleme gegeben, da dort keine Streukapazitäten die 0,3 us zum Entladen brauchen gibt. Ich bleibe aber trotzdem bei der realer Hardware! :)

MfG

kalledom
03.09.2006, 00:04
Hallo PICture,
es könnte sein, daß Du auf einen Pipeline-Effekt gestoßen bist, der in einigen Fällen auftritt, wenn z.B. der erste Befehl noch nicht abgearbeitet ist, der nächste dieses 'unfertig' beschriebene Register ausliest. Dann kommt ein falsches Ergebnis bei raus. Da muß dann 1 NOP zwischen.
Kannst Du mal die genaue Reihenfolge der Befehle mit dem TRIS-Register posten ?

PICture
03.09.2006, 01:43
Hallo kalledom!

Ich habe es jetzt so:


@RAM movlw 0x9E <- hier wird auf RC2 und RC3 als Eingänge umgeschaltet
movwf TRISC
goto $+2 <- hier wird 3xNOP abgewartet (3x0.1µs bei 40MHz PLL/4)
movf PORTC,0
andlw 0x0C
btfss _Z
goto @Out <- hier wird zurück RC2 und RC3 auf Ausgänge umgeschaltet falls die beiden Taster H sind
movlw 0x92 <- hier wird auf Ausgänge zurückgeschaltet falls die beiden Taster L sind und weiter gelaufen
movwf TRISC
movff DTmp6,STmp6 ; aktives Display sichern
movlw 2 ; Display2
movwf DTmp6 ; aktivieren
lfsr FSR2,0x060
call @2nd
call @Line
call @4th
call @Line
movff STmp6,DTmp6 ; aktives Display wiederherstellen
@Out movlw 0x92 <- bei diesem Wert arbeitet Display mit RC 2 und RC3 als Ausgänge
movwf TRISC
return

und es funktioniert.

Vorher habe ich so erfolglos versucht:


@RAM movf TRISC,0
iorlw 0x0C <- hier wird auf RC2 und RC3 als Eingänge umgeschaltet
movwf TRISC
movf PORTC,0
andlw 0x0C
btfss _Z
goto @Out <- hier wird zurück RC2 und RC3 auf Ausgänge umgeschaltet falls die beiden Taster H sind
call @Out <- hier wird auf Ausgänge zurückgeschaltet falls die beiden Taster L sind und weiter gelaufen
movff DTmp6,STmp6 ; aktives Display sichern
movlw 2 ; Display2
movwf DTmp6 ; aktivieren
lfsr FSR2,0x060
call @2nd
call @Line
call @4th
call @Line
movff STmp6,DTmp6 ; aktives Display wiederherstellen
@Out movf TRISC,0
andlw 0xF3
movwf TRISC
return


Dort, wo jetzt goto $+2 (quasi 3xNOP) ist, habe ich vorher bis zu 10xNOP
probiert und hat´s nicht funktioniert. Für mich geht eindeutich die Änderung des TRIS Registers mit OR und AND nicht.

Vielleicht fällt Dir was ein ?. Ich habe damit kein Problem mehr.

Schöne Grüsse ! :)

kalledom
03.09.2006, 12:25
Das könnte des Rätsels Lösung sein:
movf TRISC,0
iorlw 0x0C
movwf TRISC ; Hier ist der Befehl zum Umschalten ...
movf PORTC,0 ; ... der aber hier noch nicht fertig ausgeführt ist !
andlw 0x0C
btfss _Z
goto @Out ; Hier springst Du zur Routine ...
call @Out ; ... und hier ruft Du sie als Unterprogramm auf ?
; ... Was steht am Ende der Routine: return ?


movwf TRISC ; So sollte es funktionieren: Befehl zum Umschalten
nop ; Hier kann die Richtung umgeschaltet werden
movf PORTC,0 ; Hier ist die Richtung umgeschaltet

3 mal oder 8 mal oder wieviel mal auch immer ein NOP reinzusetzen, kann es ja nicht sein. Es handelt sich um einen µC, der absolut logisch arbeitet und niemals Alzheimer bekommt :-)

PS: Beim 16F87x z.B. sind die TRIS-Register in Bank 1. Da können die beiden Befehle für TRIS und PORT nicht direkt hintereinander stehen, dazwischen muß erst auf die Bank umgeschaltet werden. Bis dahin ist die Richtung umgeschaltet.

PICture
04.09.2006, 00:33
Hallo kalledom!

Der PIC18F252 arbeitet aber mit 10 MHz (40 MHz PLL Oszillator) mit realer Hardware und die 3xNOP (0,3 us) braucht (wahrscheinlich) die Hardware, und nicht der uC selbst. :)

Bei den PIC18FXXX gibt es keine Bankumschaltung.

Es gibt in meinem Program kein Fehler, ich wollte nur auf Probleme, die bei realer Hardware aufereten könnten, aufmerksam machen und zeigen, dass ein fehlerfreies Program (im Simulator) fast immer an die reale Hardware angepasst werden muss.

Deswegen meine Empfehlung:

Beim Schreiben eines Programms für reale Hardware nie ein Symulator benutzen !

MfG

TB1
05.09.2006, 15:45
Hi user
Ich hab ein Problem mit einem PIC 12F629. Ich habe ein Programm für einen anderen PIC geschrieben(16F690). Dieses wollte ich jetzt in den 12F übertagen, weils nur um das Schalten von zwei Ausgängen in einem Abstand von 2 Sekunden geht. Als Start für dieses Schalten dient ein Eingangspegel an einem anderen Pin.
Das Problem: er erkennt das Startsignal nicht, und arbeitet das Programm also auch nicht ab. Kann sowas an der Konfiguration liegen? Beim 16F läuft das Programm nämlich problemlos.
Hat einer ne Idee?

kalledom
05.09.2006, 19:46
Hast Du im Quellcode auch angegeben, daß es sich jetzt um 12F629 handelt ?
Z.B. bei Assembler die Zeile: include "p12f629.inc" ; Registerdefinitionen einbinden

PICture
06.09.2006, 07:23
Hallo TB1!

Der einziger, aber wichtiger unterschied zwischen den PIC12FXXX und PIC16FXXX ist bei Portsnamen. Bei den 16F heissen Sie A, B, C, usw. und bei den 12F gibt's nur ein Port der heisst GPIO. Die zügehörigen TRIS Register heissen entsprechend bei 16F TRISA, TRISB, TRISC, usw. und bei 12F TRISIO. Im Programm muss es geändert werden. Ausserdem GP3 ist nur Input. Um alle I/O Pins nutzen zu können, habe ich folgende Konfiguration verwendet:

__CONFIG _CP_OFF & _WDT_OFF & _PWRTE_ON & _MCLRE_OFF & _INTRC_OSC_NOCLKOUT

Dazu kommt noch folgene Initialiesierung:

movlw 7
movwf CMCON ; comparator off, RA0-2 digital I/O

Wenn Du das mit den Ports und das was der kalledom erwähnt hat bereits gemacht hast, poste am besten Deine .asm Datei, dann können wir Dir besser helfen.

MfG

TB1
06.09.2006, 07:38
Hi Leute,
An den geänderten Namen TRISIO und GPIO kanns nicht liegen. Hab ich berücksichtigt. Ich programmiere in C (jaja ich weis), und die korrekte Headerdatei ist im Projekt verknüpft. Auch der korrekte PIC ist in MPLAB eingestellt.
Wenn ich das Eingangssignal als Startbedingung aus dem Programm rausnehme, dann läuft das Schalten der Ausgänge wie gewünscht. Er erkennt nur das Startsignal, also Highpegel an einem Eingangspin, nicht.

Trotzdem erstmal besten DAnk für Eure Hinweise, auch wenn sie mir leider nicht nützen.
Ich werde mal versuchen, die Pindefinition in Assembler ins Programm zu übernehmen. Vielleicht hilft das ja. Bis dann.
MfG TB1

PICture
06.09.2006, 07:48
Schau, bitte, noch mal meinen letzten Beitrag, da ich ihn editiert habe, wenn Du Deinen letzten gepostet hast. :)

Ich kenne C nicht, aber sehr wichtig ist in den Register CMCON bei der Initialisierung den Wert 7 einzuschreiben, da sonst funktionieren die GPIOs 0,1 und 2 nicht als digitale I/Os.

MfG

TB1
06.09.2006, 07:52
HiUser
Ich werde mal die Initialisierungen von PICture probieren. TRISIO und GPIO habe ich berücksichtigt. Da das Problem nur bei einem Eingang auftritt kanns eigentlich nur am Init liegen. Wenn ich die Startbedingung (hi´pegel) rausnehme, dann läuft das Programm nämlich.

PICture
06.09.2006, 07:58
Und noch mal das gleiche mit dem Editieren. :)

MfG

TB1
06.09.2006, 12:30
Hi PICture,
Das Initiaöisieren mit CMCON=7 funktioniert ohne Fehlermeldung. Ob das Programm richtig läuft, werde ich erst morgen (Do) wissen, weil ich immer auf Arbeit mit PIC zu tun hab, und der Brenner deshalb dort ist. Heute hab ich frei O:)
Ich schreib spätestens morgen Mittag obs funktioniert.

TB1
08.09.2006, 11:59
HI Leute;

CMCON=7 war der richtige Tipp. Jetzt läufts. O:) Besten Dank.
Gruss an alle
TB1

PICture
07.01.2007, 21:21
Hallo!

Ich bin heute in eine Falle reingefallen, die ich gar nicht vermuttet habe.

Bei einem Frequenzmessunsprogramm (das bei mir schon früher am PIC18F252 fehlerfrei gelaufen ist) habe ich zum togglen des Prescalers von Timer0 (beim PIC16F870) das bit T0SE in OPTION_REG benutzt,
nur die Reihenfolge von diesen zwei Zeilen:

bsf OPTION_REG,T0SE
bcf OPTION_REG,TOSE

verwechselt und das Programm war schon fehlerhaft. :)

Ich weiss immernoch nicht genau, warum ?

Ich vermute die innere Hardware vom PIC, da gibt's aber leider kein detaliertes Schaltplan, um das analisieren zu können.

MfG

witkatz
28.09.2013, 19:51
Ich hoffe, dass es nicht total verpönt ist, ein über 6 Jahre altes Thread zu reanimieren?
Ich bin beim Portieren eines Projektchens von 16F84A auf 16F630 in die RA3 Falle getappt, die hier schon beim 12F675 mit GP3 in einem Nebensatz erwähnt wurde. Wenn der RA3/MCLR Pin des 16F630 zum I/O Pin konfiguriert wird (MCLRE_OFF), dann kann er nur als Eingang genutzt werden. Es müsste also I-Pin statt I/O-Pin heißen :wink:.
Das steht zwar irgendwo im Datenblatt, aber da recherchiert man erfahrungsgemäß erst, nachdem man aufwändig Testboard-, LED- und Kabel- und MCU-Defekte ausgeschlossen hat.

Gruß witkatz