Anfängerfallen bei der Programmentwicklung


zurück zu PIC-Prozessoren , Elektronik , Homepage

Was sind Fallen?
Die Taktraten-Falle
Die Interrupt-Falle
Die Interrupt-Falle 2
Die Analog-Falle (Port A)
Die Arbeitsspeicher-Falle
Die Daten-Tabellen-Falle
Die I2C-Falle
Die in/out-Falle
Die RA4-Falle
Die I/O-Speed-Falle
Die INTOSC&MCLR-Falle
Die LVP_ON-Falle
Die Quarz-Falle
Die "ICD/ICSP Port Enable bit"-Falle

zurück


Was sind Fallen?

Gerade der erfahrene Umsteiger nutzt seinen Erfahrungsschatz und setzt deshalb manchmal Dinge voraus, die nicht unbedingt zutreffend sind. Daraus entstehen kleine, tückische Programmierfehler, die von einem betriebsblinden Programmierer schwer zu finden sind. Keine dieser Fallen ist ein Fehler des Prozessors oder eine Böswilligkeit der Entwickler. Es sind nur die kleinen Unterschiede zum Gewohnten, die beim ersten Mal viel Zeit kosten können.
Eigentlich ist das auch alles in den Handbüchern beschrieben, aber wer liest die schon genau durch, besonders wenn es um scheinbar einfache Dinge geht.
Im folgenden liste ich die Fallen auf, in die ich selber schon getappt bin:
nach oben

Die Taktraten-Falle

Microchip preist die Eigenschaft seiner Controller, fast alle Befehle in nur einem Zyklus ausführen zu können. Mit diesem Zyklus ist aber nicht ein Takt sondern 4 Takte gemeint.
Ein NOP-Befehl benötigt auf einem mit 10 MHz getakteten PIC also keineswegs nur 100 ns sondern 400 ns. Wer Zeitschleifen aufbaut sollte das berücksichtigen.

Der Timer lässt sich übrigens auch nur mit maximal 1/4 des externen Prozessortaktes füttern, wenn man den internen Takt verwendet.

Bei den PIC24/dsPIC30/dsPIC33 ist ein Zyklus nur 2 Takte lang.

nach oben

Die Interrupt-Falle

Die meisten Prozessoren retten zum Beginn eines Interrupts selbsttätig den Programmzähler und das Statusregister mit den Flags. PIC-Prozessoren zeigen hier falsche Bescheidenheit und beschränken sich auf den Programmzähler.
Viele Befehle in der Interruptbehandlungsroutine verändern aber die Flags (das sind die einzelnen Bits des STATUS-Registers). Man könnte sich im Hauptprogramm nie mehr auf die Stellung eines Flags verlassen, sobald ein Interrupt benutzt wird, es sei den man rettet zu Beginn der Interruptroutine die Flags (also das STATUS-Register) und schreibt sie am Ende des Interrupts wieder zurück.
Dazu kann man aber nicht einfach den mov-Befehl verwenden, da dieser das Z-Flag verändern kann. Microchip schreibt deshalb eine etwas umständlich aussehende aber absolut notwendige Variante vor, um den Programmstatus über einen Interrupt hinwegzuretten.

Für einen 16F84 sollte die Interruptbehandlungsroutine stets mit dem folgenden Code beginnen:
    movwf   w_temp
    swapf   STATUS,w
    movwf   status_temp

und wie folgt enden:
    swapf   status_temp,w
    movwf   STATUS
    swapf   w_temp,f
    swapf   w_temp,w
    retfie
 

Für einen 16F62x oder einen 12F6xx sollte die Interruptbehandlungsroutine stets mit dem folgenden Code beginnen:
    movwf   w_temp
    swapf   STATUS,w
    bcf     STATUS, RP0       ; status_temp in Bank 0
    movwf   status_temp

und wie folgt enden:
    swapf   status_temp,w
    movwf   STATUS
    swapf   w_temp,f
    swapf   w_temp,w
    retfie
 

Für einen 16F87x sollte die Interruptbehandlungsroutine stets mit dem folgenden Code beginnen:
    MOVWF   W_TEMP
    SWAPF   STATUS,W
    CLRF    STATUS
    MOVWF   STATUS_TEMP
    MOVF    PCLATH, W
    MOVWF   PCLATH_TEMP
    CLRF    PCLATH

und wie folgt enden:
    MOVF    PCLATH_TEMP, W
    MOVWF   PCLATH
    SWAPF   STATUS_TEMP,W
    MOVWF   STATUS
    SWAPF   W_TEMP,F
    SWAPF   W_TEMP,W
    retfie

Das Register 'status_temp'  muss in der Bank 0 definiert sein.
Da man nicht weiß, welche Registerbank gerade ausgewählt ist, während der Interrupt ausgelöst wird, muss das Register 'w_temp'  ein Register sein, das in jeder Bank existiert. Beim 16F84 und beim 12F6xx ist das immer garantiert, beim 16F62x dürfen für  'w_temp' Register mit einer Adresse unter 0x70 nur verwendet werden, wenn im Programm niemals in die Bänke 2 oder 3 geschaltet wird.

Beispiel:
wird 'w_temp' für die Adresse 0x20 definiert (w_temp equ 0x20), und befindet sich der Prozessor im Augenblick des Interrupts in der Bank 3, dann versucht die erste Zeile der Interruptserviceroutine, den Inhalt von w in 0x20 abzuspeichern (movwf w_temp). Da der Prozessor in der Bank 3 ist, wird anstelle der Adresse 0x20 aber die Adresse 0x1A0 verwendet. Der 16F62x besitzt auf dieser Adresse aber keine Register. Der Wert von w verschwindet im Nirwana, und der Absturz ist vorprogrammiert.
 

Natürlich muss sich die Interruptroutine (nach dem Retten von W und STATUS) sich selbst die Bank einstellen, die sie benötigt. Am Ende der Interruptroutine wird mit dem Rück-Retten von STATUS die alte Bank-Einstellung automatisch wieder hergestellt.
 

nach oben

Die Interrupt-Falle 2

Im PIC wird ein Interrupt ausgelöst, wenn (z.B. durch ein externes Ereignis) ein Interrupt-Flag gesetzt wird (und das zugehörige Enable-Bit gesetzt ist).
Am Ende der Interruptroutine muss dieses Interruptflag unbedingt wieder auf 0 zurückgesetzt werden. Ansonsten führt das noch gesetzte Flag nach dem Ende der Interruptroutine sofort wieder zum Auslösen des Interrupts, und man befindet sich in einer Endlosschleife.
 
nach oben

Die Analog-Falle (Port A, Port GP)

Umsteiger vom kleinen 16F84 zum 16F876 freuen sich der weitgehenden Assemblercode-Kompatibilität. Allerdings ist PortA gemeinerweise nach dem Zuschalten der Betriebsspannung oder nach dem Reset als analoge Eingänge für den ADC konfiguriert. Man muss also noch die Pins des PortA auf digital umstellen, und schon läuft der 16F876-Code, es sei denn man ist noch in die Arbeitsspeicherfalle getappt.

; 16F876: alle ADC-Eingänge auf digital I/O umschalten
    BSF STATUS, RP0    ; auf Bank 1 umschalten
    MOVLW 0x06         ; PCFG3..0 = '0110'
    MOVWF ADCON1
    BCF STATUS, RP0    ; auf Bank 0 zurückschalten
 

 Die Analog-Falle betrifft übrigens auch den PIC16F628. Hier liegen die Komparatoreingänge nach Reset an den Pins, die eigentlich dem Port A zugedacht sind.

; 16F628 alle Comparatoreingänge auf Digital umschalten
; alles in der Bank 0
    BSF CMCON, CM0
    BSF CMCON, CM1
    BSF CMCON, CM2
 

Auch die kleinen 12F6xx sind nach dem Reset auf analog eingestellt. Beim 12F629 liegt der Komparator an den Pins GP0 und GP1. Beim 12F675 ist zusätzlich noch der ADC an die Ports GP0, GP1, GP2 und GP4 zugeschaltet.

; 12F629 alle Comparatoreingänge auf Digital umschalten
; alles in der Bank 0
    BSF CMCON, CM0
    BSF CMCON, CM1
    BSF CMCON, CM2
 

; 12F675 alle Comparator-/ADC-Eingänge auf Digital umschalten
; beginnt in der Bank 0
    BSF  CMCON, CM0         ; GP0,1 von Comparator auf digital
    BSF  CMCON, CM1
    BSF  CMCON, CM2
    BSF  STATUS, RP0        ; Bank 1
    CLRF ANSEL              ; GP0,1,2,4 von ADC auf digital
    BCF  STATUS, RP0        ; Bank0

nach oben

Die Arbeitsspeicher-Falle

Noch eine kleine Fußangel für Umsteiger vom 16F84 zum 16F876:
Wird ein bewährtes 16F84 Assembler-Programm einfach für den 16F876 benutzt, so kommt es vor, das es fast funktioniert. Dieses "fast" kann mit den verschobenen Adressen der frei verfügbaren Speicher-Zellen zusammenhängen. Beim 16F84 beginnt der vom Programmierer nutzbare Bereich bei 0x0C. Der große Bruder hat hier aber noch interne Register. Erst ab 0x20 darf der Nutzer sich austoben.
nach oben

Die Daten-Tabellen-Falle

Oft werden Konstanten in einer Tabelle im Programmspeicher abgelegt. Das folgende Beispiel ist ein Ausschnitt aus einem Programm, in dem ein PIC16F84 eine 7-Segment LED-Anzeige ansteuert. Welche Leuchtsegmente zur Darstellung der Ziffern 0 .. 9 eingeschaltet werden müssen, ist in 10 Programmzeilen mit RETLW-Befehlen festgelegt.

Um z.B. die Ziffer 4 darzustellen, wird "w" mit dem Wert  "4" geladen, und dann die Zeile "addwf PCL,f" mit einem Call-Befehl "call Segmente" angesprungen. Der addwf-Befehl erhöht den Programmcounter zusätzlich um den Wert 4 und bewirkt dadurch einen Sprung in die Zeile "retlw B'11010100' ; 4". Hier wird der Wert B'11010100' nach "w" geladen und ein Return ausgelöst, der zur rufenden Routine zurückführt.

     ; 7-Segment-Tabelle
Segmente
      addwf PCL, f
      retlw B'00011000' ; 0
      retlw B'11011110' ; 1
      retlw B'00110010' ; 2
      retlw B'01010010' ; 3
      retlw B'11010100' ; 4
      retlw B'01010001' ; 5
      retlw B'00010001' ; 6
      retlw B'11011010' ; 7
      retlw B'00010000' ; 8
      retlw B'01010000' ; 9

Das ist trickreich und funktioniert meistens.

Bei der Verwendung solcher Tabellen muss man aber darauf achten, dass der addwf-Befehl nur 8-bittig arbeitet, der Programmcounter aber viel länger ist. Innerhalb der Tabelle, darf keine Befehlsadresse der Form xxxFF auftauchen. Der addwf-Befehl kann solche Adressen nicht überspringen, sondern springt stattdessen zu einer Adresse 256 Byte vor dem gewünschten Ziel. Die Adressen muss man deshalb im *.lst-file prüfen und evtl. durch "org"-Befehle und Sprünge manipulieren.

Sobald man die Sprungberechnungs-Routine bei einer Adresse höher 0x00FF hat, darf nicht vergessen werden, PCLATCH anzupassen.

nach oben

Die I2C-Falle

Die 'großen' PICs (z.B. PIC16F87x) verfügen über eine umfangreiche Hardware zur seriellen Kommunikation. Dabei ist auch eine I2C-Schnittstelle.

Da die beiden Pins des PIC, die das I2C-Port darstellen, keine internen Hochziehwiderstände besitzen, muss man diese extern anschließen. Ansonsten interpretiert der PIC den externen Low-Pegel als aktiven I2C-Bus, den gerade ein anderer I2C-Master benutzt. Solange jemand anders auf dem Bus zu senden scheint, übernimmt der PIC aber nicht die Kontrolle über den Bus.

Die externen Hochziehwiderstände präsentieren dem PIC einen sauberen High-Pegel, und der I2C-Master übernimmt dann gern die Buskontrolle

nach oben

Die in/out-Falle

Jedesmal, wenn auf ein Port (PORTA..PORTE, GPIO) schreibend zugegriffen wird, dann wird zunächst das gesamte Port gelesen, das gelesene Byte im Prozessor modifiziert, und dann das veränderte Byte in das Port zurückgeschrieben. Also wird auch dann, wenn nur ein einzelnes Bit verändert werden soll (bsf, bcf),  jedesmal das ganze Port angefasst.

Beim anfänglichen Lesen des Ports liest der Prozessor nicht etwa das Portregister (z.B. PORTA oder PORTB) aus, sondern liest die momentanen Pegel an den Pins des Ports ein. Bei Pins, die auf Output eingestellt sind macht das keinen Unterschied, wohl aber für Port-Pins, die auf Input eingestellt sind. Deren Bits im Port-Register können dadurch unbeabsichtigter Weise verändert werden. Nach dem Umschalten auf Output, haben diese Pins dann einen anderen Pegel als beabsichtigt.

Beispiel:
An einem PIC sei RB0 über einen 10kOhm Widerstand mit Vss (Masse) verbunden, während RB1 mit einem weiteren 10kOhm-Widerstand an Vdd (+5V) liegt.
An allen Pins wird low ausgegeben:

; 16Fxx RB0..7 auf Output einstellen
    BSF  STATUS, RP0    ; auf Bank 1 umschalten
    CLRF TRISB          ; PORTB auf Output
    BCF  STATUS, RP0    ; auf Bank 0 zurückschalten
    CLRF PORTB          ; low an allen PortB-Pins

Nun liegt an allen Pins low Pegel.
Nun werden RB0 und RB1 auf Input geschaltet, und anschließend RB2 auf high gesetzt.

; 16Fxx RB0 und RB1 auf Input einstellen
    BSF  STATUS, RP0    ; auf Bank 1 umschalten
    BSF  TRISB, 0       ; RB0 auf input
    BSF  TRISB, 1       ; RB1 auf input
    BCF  STATUS, RP0    ; auf Bank 0 zurückschalten
; RB2 auf high setzen
    BSF  PORTB, 2       ; RB2 auf  high setzen

Nachdem RB0 und RB1 auf input umgeschaltet wurden, nehmen ihre Pins die Pegel an, die ihnen von außen durch die Widerstände als Eingangssignale aufgezwungen werden. Am Pin RB0 liegt nun low aber am Pin RB1 liegt high. Die zugehörigen Bits im PORTB-Register sind aber nach wie vor beide 0.
Beim Setzen von RB2 auf high liest der PIC zunächst alle Port-Pins ein. Dabei liest er am Pin von RB1 nun den high-Pegel des externen Widerstandes. Der PIC liest also:
00000010
Anschließend setzt er das Bit 2
00000110
und schreibt das Ergebnis in das Register PORTB. Dadurch verändert sich nun nicht nur das Bit 2 sonden auch das Bit 1 von PORTB von low auf high. Da RB1 aber auf input steht, hat das noch keine Konsequenzen.
Nun schalten wir RB0 und RB1 wieder auf output.

; 16Fxx RB0..7 auf Output einstellen
    BSF  STATUS, RP0    ; auf Bank 1 umschalten
    CLRF TRISB          ; PORTB auf Output
    BCF  STATUS, RP0    ; auf Bank 0 zurückschalten

Nun wird der veränderte Wert von RB1 ausgegeben. Während RB0 wieder low ausgibt, und RB2 (wie gewollt) high ausgibt, liegt nun plötzlich auch RB1 auf high, obwohl das im Programm gar nicht explizit so programmiert wurde.
 
 

Bei der Entwicklung der PIC18Fxxxx-Typen hat man dem Problem Rechnung getragen. Wenn man das Port auslesen will, so kann man das jetzt auf zwei verschiedene Weisen machen. Ein Lesen von PORTx (z.B. PORTA oder PORTB) liest den Pegel der Port-Pins, wie es auch bisher üblich war. Man kann aber nun auch von LATx (z.B. LATA oder LATB) lesen. Ein Zugriff auf LATx ist ein Zugriff auf das Portregister, und nicht auf die Pins. Wenn man auf LATx zugreift, dann gibt es keine in/out-Falle. Auf PORTx sollte nur zugegriffen werden, wenn man wirklich den Spannungspegel an input-Pins einlesen will.

nach oben

Die RA4-Falle

RA4 ist an vielen PICs ein open-Drain-Ausgang. Damit scheint es sich anzubieten, ihn mit anderen open-Drain Ausgängen anderer Schaltkreise zusammen an eine Leitung anzuschließen. Das wäre z.B. für eine Emulation eines I2C-Busses sinnvoll.

Für RA4 gilt aber eine gesteigerte Version der oben beschriebenen in/out-Falle. Diese Falle ist deshalb besonders gemein, da RA4 nicht auf input umgeschaltet werden muss, um durch Manipulation anderer PORTA-Pins  versehentlich auf low umgeschaltet zu werden.

Beispiel:
RA4 und RA3 werden für die Emulation eines I2C-Busses benutzt. Dabei treibt RA3 die Taktleitung, und RA4 die Datenleitung. Die Datenleitung kann auch von anderen Chips (I2C-Slaves) mit open-drain-Treibern nach low gezogen werden.
Momentan ist RA4 auf high gesetzt, um anderen Geräten die Komunikation über die Datenleitung zu ermöglichen. Ein anderes Gerät zieht nun die Datenbleitung (und damit Pin RA4) auf low. Ein beliebiger schreibender Zugriff auf PORTA (z.B. das Setzen von RA3 mit 'bsf PORTA, 3' ) löst nun folgendes aus: Der PIC liest alle Port-Pins ein. Dabei liest er am Pin RA4 low, weil ein anderes Gerät die Datenleitung auf low zieht. Danach verändert der PIC das eingelesenen Byte entsprechend dem Befehl (z.B. wird das Bit 3 gesetzt bei 'bsf PORTA, 3' ). Das veränderte Byte wird nun nach PORTA geschrieben. In diesem Moment wird RA4 mit '0' beschrieben, und RA4 beginnt die Datenleitung aktiv nach low zu ziehen. Damit unterbindet RA4 natürlich jegliche Komunikation auf dieser Leitung.

Man beachte, dass in diesem Fall keine Manipulation von TRISA nötig ist, um in diese Falle zu tappen

nach oben

Die I/O-Speed-Falle

Das Schreiben auf ein Port erfolgt immer am Ende des Befehlszyklusses. Das Lesen vom Port erfolgt dagegen immer am Anfang des Befehlszyklusses.

Beispiel:
Ein PIC wird mit 20 MHz getaktet. Port B  ist auf output  eingestellt. In PORTB steht zu Beginn der Wert 0xFF:

    CLRF  PORTB          ; Alle Pins von Port B auf  low setzen
    MOVFW PORTB          ; Port B einlesen

Welcher Wert steht nun in w ??

Man sollte annehmen, dass 00000000 eingelesen wurde. Das wird auch oft der Fall sein, garantieren kann man es aber nicht.

Bei 20 MHz ist ein Befehlszyklus 0,2 µs lang. Zwischen dem Schreiben auf Port B und dem Auslesen desselben liegen höchstens 0,05 µs = 50 ns. Es hängt von der Kapazität der an die Pins angeschlossenen Schaltung ab, ob die Pintreiber in der Lage sind, innerhalb dieser kurzen Zeit die Ausgänge wirklich auf low zu ziehen. Bei einer kapazitiven Last von 1nF sind dazu immerhin schon 80 mA nötig.

Sicherer ist es, zwischen die beiden Befehle ein 'NOP' einzufügen.
 

nach oben

Die INTOSC&MCLR-Falle

Wichtig für Benutzer der Brenner0, AN589-Brenner und Q&D-Brenner:

Wenn ein Brenner auf einen PIC zugreifen will, dann schaltet er normalerweise seine 5V-Betriebsspannung ein, legt  MCLR auf Vss (um einen Reset auszulösen) und legt dann MCLR schlagartig auf Vpp (+12V), so dass der PIC nach dem Reset nicht dazu kommt, auch nur einen einzigen Befehl abzuarbeiten. Damit ist der PIC im Programmiermodus, und durch den Reset steht der interne Programcounter des PIC auf der Adresse 0x00. Dort kann man dann anfangen zu brennen.

Wenn bei einem PIC aber beim vorigen Brennen der interne Oszillator aktiviert wurde und MCLR zu einem I/O-Pin gemacht wurde, dann ignoriert der PIC das Vss-Signal an MCLR und beginnt mit der  Abarbeitung seines Programms, sobald die Betriebsspannung Vdd angelegt wird.. Beim dann folgenden Anlegen von Vpp an MCLR stoppt der PIC seine Arbeit, aber der Programcounter steht nicht mehr auf 0x00, und das anschließende Brennen eines neuen Programms erfolgt auf zufälligen Adressen des Programmspeichers.

Solche PICs lassen sich nur problemlos brennen, wenn zuerst  Vpp (12V) und danach Vdd (5V) angeschaltet wird. Das ist nicht mit  allen Brennern möglich. Die Brenner 1, 2, 3 und 5 können das  mit der Software PBrenner ab V3.4. (Ältere Versionen nur mit einigen Typen)
 

PIC18Fxxx/xxxx

Das gleiche Problem gilt im Prinzip auch für die PIC18F-Typen mit internem Oszillatorblock (nanoWatt). Auch hier lässt sich MCLR per Config zum Input-Port RE3 machen und gleichzeitig INTOSC oder INTOSCIO als Taktquelle einstellen. In den Datenblättern fand ich keine Lösung, insbesondere wird die Einschaltreihenfolge VDD->Vpp explizit verlangt.

Der Hersteller warnt davor, LVP (low voltage programming) zu erlauben, wenn MCLR zum I/O-Pin gemacht wird. Dann wäre es beim nächsten Programmieren nämlich nötig, das PGM-Pin (RB5 o.ä.) auf low zu legen, um den Programmiermode zu erreichen. Die meisten Programmiergeräte tun das aber nicht, da ihre Entwickler (auch ich) LVP für nicht notwendig erachten.

nach oben

Die LVP_ON-Falle

Ist in der Konfiguration des PIC die Option LVP_ON aktiviert (low voltage programming enabled), dann muss dafür gesorgt werden, dass das PGM-Pin (meist RB3) sicher auf Low-Pegel liegt. Dafür ist es über einen externen Widerstand mit Masse (Vss) zu verbinden. Wenn interne pull-ups aktiviert werden, so darf der pull-up des PGM-Pins nicht aktiviert werden.

Falls das nicht beachtet wird, und PGM auf High wandert (das passiert sehr leicht, wenn das Pin frei gelassen wird), dann schaltet der PIC in den Programmiermodus. Die Warscheinlichkeit, das Programm im Flash-Speicher zu beschädigen ist verschwindend gering, aber der PIC unterbricht die Programmabarbeitung. Der PIC bleibt "stehen" oder er arbeitet nur "stotternd".

Die PIC-Typen, die LVP beherrschen, werden vom Hersteller oft mit aktiviertem LVP_ON ausgeliefert. Wer kein LVP benötigt sollte es beim ersten Brennen des PIC deaktivieren.

nach oben

Die Quarz-Falle

Einige PICs (z.B. PIC18F2550)  können mit einem externen Takt von bis zu 48 MHz gespeist werden. Ebendso kann an die Pins OSC1&OSC2 ein Quarz mit einer so hohen Schwingfrequenz angeschlossen werden. Quarze mit Frequenzen von mehr als ca. 22 MHz sind aber oftmals nicht als Grundwellenquarze sondern als Oberwellenquarze ausgelegt. Oberwellenquarze neigen am PIC dazu, mit ihrer Grundfrequenz zu schwingen. Das ist dann oft nur ein Drittel der angegebenen Quarzfrequenz.
Ein 48-MHz-Quarz (Oberwellenquarz für die dritte Oberwelle) schwingt dann z.B. nur mit 16 MHz. Da der PIC ja korrekt arbeitet (nur zu langsam), merkt man das nicht sofort. Im Reichelt-Katalog ist für jeden Quarz angegeben, ob es sich um einen Grundwellenquarz oder einen Oberwellenquarz handelt.

Man sollte darauf verzichten, am PIC-Oszillator Quarze mit mehr als 20 MHz einzusetzen. Die erwünschte hohe interne Taktfrequenz des PIC lässt sich mit der (bei solchen PIC-Typen stets vorhandenen) internen PLL unproblematischer erreichen.
nach oben

Die "ICD/ICSP Port Enable bit"-Falle

Viele PIC18Fxxxx-Typen mit mehr als 40 Pins haben einen alternatives ICSP-Interface. Durch ein spezielles Bit in der Configuration kann auf dieses Interface umgeschaltet werden (CONFIG4L, Bit3). Dummerweise besitzen viele kleineren PICs (18 .. 40 Pins) ebenfalls dieses Configurationsbit, nur ist es in der Dokumentation nur beiläufig erwähnt. Wird bei den "kleinen" PIC18Fxxxx dieses Bit auf "1" gesetzt, dann ist der PIC ab sofort nicht mehr korrekt über das normale Programmierinterface ansprechbar. Er liefert eine falsche PIC-ID an den Brenner, und der Brenner verweigert oft die Arbeit mit so einem PIC.
Nun kommts: Wird die Konfiguration in Assembler oder C mit den normalen Konfigurations-Optionen eingestellt, dann wird Bit3 Config4L standardmäßig auf "1" gesetzt! Das Dilemma ist vorprogrammiert. Wenn ein Programmiergerät nun die Config aus dem HEX-File in gutem Glauben in den PIC brennt, dann ist der PIC nach erfolgreich abgeschlossenem Brennen nicht mehr durch das Programmiergerät ansprechbar.

Obwohl es nicht die Aufgabe eines Brenners ist, die Konfiguration zu korrigieren, können USBurn und P18 das. Dazu ist es erforderlich, dass nach dem Erkennen des PIC und dem Laden des HEX-Files in die Programmiersoftware die Option "Config from HEX-File" manuell deaktiviert wird (ist normalerweise aktiv). Das Brennprogramm übernimmt dann die Config zwar aus dem HEX-File, korrigiert aber offensichtliche Fehler, bevor es den PIC damit beschreibt. Dadurch umgeht man diese Falle.

Ist man bereits in die Falle getappt, dann kann USBurn ab V1.8 dieses Problem wieder beseitigen. Dafür dient das "Reanimation"-Fenster. Hier wird der PIC-Typ manuell ausgewählt, und dann der PIC komplett (also auch die falsche Config) gelöscht.

nach oben

zurück zu PIC-Prozessoren , Elektronik , Homepage
Autor: sprut
erstellt: 2000
letzte Änderung: 04.02.2008