Tips mit PICs 9: Der OSCCAL und sein Verschwinden

Hier geht es um ein sehr spezielles Problem:
- PICs mit OSCCAL
- OSCCAL wird vom Programmierer genutzt
- der zu beschreibende PIC war code-protected (durch irgendein altes Programm)

Weiter geht es hier speziell um den Selbstbau-Brenner 8p5 von sprut und die dazu empfohlene Brenn-Software USBurn.

Warum OSCCAL und wozu?
Zum Ausgleich von Fertigungstoleranzen gibt der Hersteller für jeden Chip einen Korrektur-Code an, mit dem der interne Oszillator dann innerhalb der im Datenblatt angegebenen Toleranzen schwingt.
Anders gesagt: jeder einzelne PIC (aus der Reihe 12F629, 12F675, 16F630, 16F676) besitzt einen individuellen Korrekturwert, mit dem der interne Oszillator auf eine Genauigkeit von ca. 1% gebracht werden kann. Ohne diese Korrektur kann der Wert durchaus um 20% von der Sollfrequenz abweichen!
Beispiel: nach Berechnungen hätte ein Blinkgeber 30 Impulse pro Minute machen sollen. Es waren aber 36. Nach programmierter Korrektur mit OSCCAL waren es, wie geplant, 30 Impulse. Dies entspricht einer Abweichung von 20%. Der OSCCAL-Wert ist 44.

Wo liegt das Problem?
Der OSCCAL-Wert liegt im normalen Flash-Speicher am oberen Ende und kann beim Löschen verlorengehen. Daher wird bei Programmiergeräten Sorge getragen, daß dieser erhalten bleibt, indem er vor dem Löschen ausgelesen wird und nach dem Programmieren wieder eingetragen wird.
Leider hat das o.g. Programmiersystem einen reproduzierbaren Fehler: Der OSCCAL-Wert wird zwar bei einem vorher programm-geschützten (code-protected) PIC ausgelesen und richtig angezeigt, aber später nicht wieder eingeschrieben. Statt dessen wird eine Null eingetragen, die dann als NOP-Befehl interpretiert wird. Beim Überschreiben nicht-geschützter Programme ist nichts zu beanstanden. Alles läuft so wie es soll.

Nebenbei bemerkt:
Der Autor schätzt sprut sehr und ist ihm außerordentlich zu Dank verpflichtet dafür, daß er sich mit seiner Seite so extrem viel Mühe gemacht hat. Ohne ihn wären seine Programmier-Erfolge nicht so rasch gekommen: Der Einstieg war von Null in wenigen Wochen vollzogen. Daher an dieser Stelle herzlichen Dank dafür!


Programmtechnisch geschieht die OSCCAL-Korrektur dadurch, daß in der Start-Sequenz die Befehlsfolge
CALL 0x3ff
MOVWF OSCCAL
abgesetzt wird, wobei an der Adresse 0x3ff der Befehl
RETLW xx
erwartet wird. Der Hersteller trägt an dieser Stelle den Befehl RETLW xx ein. Das xx ist der eingemessene Korrekturwert (z.B. 44). OSCCAL ist eine 'normale' Variable im Datenbereich (Adresse 0x90), auf die der interne Oszillator zugreift. Über den CALL-Aufruf wird also ein Unterprogramm an der Stelle 0x3ff angesprungen, das nur aus dem einzigen Befehl RETLW (Rückkehr aus einem Unterprogramm mit xx im w-Register) besteht. Und der Anwender überträgt diesen Wert in die Speicherzelle OSCCAL. Irgendwie genial.
Lange Vorrede! Falls dieser RETLW-Befehl gelöscht ist, findet das Programm an dieser Stelle keinen Rücksprung-Befehl und macht bei der nächsten Adresse weiter, und das wäre 0x3ff + 1 = 0! Hier beginnt per Definition immer das Start-Programm, wo, nach einigen anderen Befehlen, wieder der CALL 0x3ff auftaucht; somit 'rennt der PIC im Kreis' und scheint mausetot zu sein.
Falls Ihnen der OSCCAL-Wert bekannt ist (z.B. die hier genannte '44'), ersetzen Sie einfach den CALL 0x3ff in der Start-Routine durch MOVLW d'44'. Damit wird das Gleiche erreicht wie mit dem CALL-Befehl; nur gilt dies, wie ganz oben schon gesagt, nur für einen bestimmten PIC. Sie müßten also für jeden weiteren PIC, den Sie brennen möchten, ein neues Programm schreiben! Das ist natürlich unangenehm.

So weit der Notbehelf.

Wie bekommt man nun den richtigen OSCCAL-Wert wieder einprogrammiert?
'Zu Fuß' haben Sie keine Chance, da jedes Programmiergerät diese Speicherstelle gnadenlos mit dem ihm bekannten OSCCAL-Wert überschreibt, und wenn es eine Null ist.
Zunächst raten wir Ihnen dringend, nach dem Kauf von PICs erst einmal den jeweiligen OSCCAL-Wert auszulesen und ihn dann auf dem PIC zu vermerken.
Der Autor hat ihn auf ein kleines Etikett geschrieben und dieses dann von unten auf den PIC geklebt.

sprut hat auf seiner Internet-Seite eine Methode beschrieben, wie man selber den OSCCAL-Wert ausmessen kann. Diese ist aber recht aufwendig, und am Ende steht der Korrektur-Wert nicht im Flash-Speicher (wo er ja eigentlich hingehört), sondern im EEPROM. Das macht für den entsprechenden PIC wieder eine softwaremäßige Sonderlösung nötig. Nicht gerade ideal, aber man kennt wenigstens den Wert wieder.

Wenn man einmal dieses Problem hatte, wird man automatisch die Etikett-Methode wählen!

Der Fehlerfall und seine Korrektur
Nehmen wir an, Sie wollen einen 16F676 neu programmieren. Das Fenster des USBurn sieht nach dem Anklicken von 'Identify PIC in Programmer' und Auslesen des PICs wie folgt aus:

ausgelesen

Sie sehen, daß der OSCCAL ausgelesen wurde (72) und daß in Rot die Warnung 'codeprotected' erscheint. Laden Sie wie gewohnt das zu speichernde Programm:
- select HEX-file as source
Jetzt dürfen Sie
nicht weitermachen wie gewohnt:
- write HEX-file into PIC.
Denn damit hätten Sie genau den Fehlerfall produziert, wie er hier lang und breit beschrieben wird.
Stattdessen gehen Sie zur manuellen Eingabe des OSCCAL-Wertes:

Handeingabe

Interessanterweise steht auch hier noch der gerade gelesene OSCCAL-Wert (rechts). Schieben Sie den Regler so weit, daß der richtige OSCCAL-Wert angezeigt wird (direkt unter dem Schieber).
Programmieren Sie jetzt wie gewohnt den PIC, und der richtige Wert ist eingetragen.
Lesen Sie zur Vorsicht den gerade gebrannten PIC noch einmal ein (per 'Identify ...'), nur zur Kontrolle. Falls nämlich etwas schief gegangen sein sollte, ist der PIC wertlos, wie weiter oben schon beschrieben. Und - wie der Teufel es will, steht statt des gewollten OSCCAL-Wertes der Standard mit '128' im PIC. Dies ist natürlich immer noch besser als garkein Wert, d.h. eine Null!

falscher Wert

Falls auch Ihnen das passiert, hilft nur noch folgende Methode:
Nehmen Sie sich irgendein nicht-geschütztes Programm und brennen Sie dies mit all den hier beschriebenen Optionen in den PIC, evtl. sogar mehrmals, bis beim Kontroll-Lesen der richtige OSCCAL-Wert erscheint. Nun haben Sie einen nicht-geschützten PIC vor Sich, den Sie 'normal', also ohne alle die hier vorgestellten Kapriolen, brennen können.

Die aktuelle Version von USBurn ist V1.10a2 (Stand: 21.02.2010).
sprut hat für die nächste Version des USBurn die Beseitigung dieses Fehlers angekündigt.

10.03.2010:
sprut hat die neue Version (usburn110a5.zip) ins Netz gestellt. Wir empfehlen, nur noch diese zu benutzen.

Für weitere Fragen stehen gern zur Verfügung:
- der MEC; Besichtigung und Fachsimpelei z.B. an unseren "Club-Abenden"
- der Autor: Hans Peter Kastner

Version vom: 10.03.2010; erstellt am: 22.02.2010
Copyright © 2010 by Modelleisenbahnclub Castrop-Rauxel 1987 e.V.

Valid HTML 4.01!