Hallo PIC-Freunde,
also, wie in der Überschrift steht: Da bemerkte ich seltsame Dinge, die
ich mir nicht erklären kann.
Und zwar experimentiere ich gerade mit ultraniedrigen Taktfrequenzen,
dem externen RC-Oszillator, wobei ich diesem mit ca. 1 Hz Taktfrequenz
zuschauen kann, wie die Maschinenbefehle gaaaaanz langsam nacheinander
in einer kurzen Main-Schleife abgearbeitet werden. Fast so gut wie
Single-Step, nur automatisch.
Ich schalte nur 2 LEDs um.
Laut Datenblatt ist der PIC ja statisch, und arbeitet ab DC
Taktfrequenz.
In der Main-Schleife zähle ich bei jedem Lauf eine Variable hoch, und
verwende diese mit Bit-Test-Befehlen, um zwei LEDs wechselweise ein- und
auszuschalten. Das niedrigste Bit reicht ja, es toggelt mit jeder
Zählung.
Also, es werden da je nach dem niedrigsten Counterbit jeweils die LEDs
umgeschaltet.
Einmal wechseln die LEDs so, daß beide sichtbar Takt für Takt
nacheinander umschalten. Im zweiten Fall schalten beide LEDs
gleichzeitig, obwohl die Schaltbefehle genau wie im ersten Fall
nacheinander folgen. Genau das ist der Punkt, den ich nicht verstehe.
Jeweils mit den Bitsetzbefehlen bsf und bcf für beide Fälle vertauscht.
Bei einem hochfrequenten Programm z.B. mit Megaherzen wäre mir das gar
nicht aufgefallen.
Hat mal jemand eine Idee, was das sein könnte?
Natürlich glaube ich schon, den PIC-Assembler etwas zu können. Wenn
jemand anderer Meinung ist, poste ich gerne auch den kleinen
Programmschnipsel. Vielleicht habe ich ja heute Tomaten auf den Augen,
manchmal sieht man simpelste Dinge nicht. ;-)
Den Simulator habe ich allerdings noch nicht bemüht, sollte aber
grundsätzlich gehen.
Aktiviere mal Clockout und monitoriere diesen.
Du wirst feststellen, daß wenn du eine Led einschaltest, die Spannung
einbricht und dadurch der intern Komparator einen weiteren Clock Impuls
generiert. Passiert eigentlich nur bei sehr geringem Clock.
Chris schrieb:> Aktiviere mal Clockout und monitoriere diesen.> Du wirst feststellen, daß wenn du eine Led einschaltest, die Spannung> einbricht und dadurch der intern Komparator einen weiteren Clock Impuls> generiert. Passiert eigentlich nur bei sehr geringem Clock.
Dabei habe ich die I/O doch schon als rein digitale I/O initialisiert,
wobei ADC und Komparator abgeschaltet werden.
Aber da kennt sich jemand offenbar damit aus.
Ja, es gibt noch mehr: Die Blinkfrequenz ist im Tastverhältnis auch
nicht gut. Der eine Zustand dauert 15 Sekunden, der andere 9 Sekunden.
Wobei beide nach Programm gleich sein müßten. Wirklich rätselhaft.
Also muß ich mal Clockout frei schalten, und wirklich das Oszi anhängen.
Notfalls an einem weiteren I/O noch den zweiten Oszi-Kanal anhängen.
Die Stromversorgung des PIC sehe ich jetzt nicht als kritisch, der soll
bis 2V herunter spielen, also mit fast leeren Batterien. Aktuell sind da
halb volle 4 Mignonzellen mit 4,9V dran, und ein paar Elkos.
Langer Rede, kurzer Sinn: Ich poste auch mal das kleine Programm:
> Ja, es gibt noch mehr: Die Blinkfrequenz ist im Tastverhältnis auch> nicht gut. Der eine Zustand dauert 15 Sekunden, der andere 9 Sekunden.> Wobei beide nach Programm gleich sein müßten. Wirklich rätselhaft.
Hä?
Da sind doch 1. Sprungbefehle, die dauern 2 Takte und Du hast 2. noch
incf COUNTER,f und btfss COUNTER,0 drin
hä? schrieb:> Da sind doch 1. Sprungbefehle, die dauern 2 Takte und Du hast 2. noch> incf COUNTER,f und btfss COUNTER,0 drin
Das tut sich in der Zahl der Taktzyklen nichts. Der incf Counter sowieso
gar nicht.
hä? schrieb:> Da sind doch 1. Sprungbefehle, die dauern 2 Takte und Du hast 2. noch> incf COUNTER,f und btfss COUNTER,0 drin
goto benötigt 2 Taktzyklen
incf benötigt 1 Taktyklus
btfss benötigt 1 Taktzyklus wenn das Bit nicht gesetzt ist und 2 wenn es
gesetzt ist.
Ich erhalte für einen Durchlauf durch Loop2 10 Taktzyken und andersrum
11 Taktzyklen.
Naja, wenn LED2 eingeschalten wird, sind es 10 clk, hingegen wenn
LED1 eingeschalten wird, verbraucht der loop 11 clk.
Ich sprach vom Komparator des RC-OSC. Bei ungünstiger Beschaltung
passiert
sowas, wobei dein Code nicht zu deiner Aussage passt.
Peter Dannegger schrieb:> 2 Bitbefehle hintereinander geht nicht, da muß ein NOP dazwischen.> Auf Sprut wird das erklärt, warum.
Danke, ich werde das so einfach mal testen.
Findet man das denn nicht in PIC-Manuals? Wenn nein, warum nicht? Oder
war ich zu blöd, die Stelle zu finden?
Aber wie schon gesagt, wenn das nicht gerade mit 1 Hz passiert, sondern
1 MHz, stört es sicherlich meistens gar nicht.
Peter Dannegger schrieb:> 2 Bitbefehle hintereinander geht nicht, da muß ein NOP dazwischen.> Auf Sprut wird das erklärt, warum.
Stimmt nicht.
Weiss nicht auf WAS sich Sprut dabei genau bezieht, aber ich habe noch
nie zwischen Bitbefehlen ein NOP geschrieben.
Chris B. schrieb:> aber ich habe noch> nie zwischen Bitbefehlen ein NOP geschrieben
Ich bisher auch nicht. Bis Peter kam, und behauptet, irgendwo auf der
Welt wäre es erklärt. Ohne konkrete Quellenangaben und Links natürlich.
;-)
Meint der eigentlich, ich würde jetzt Sprut komplett absuchen? ;-)
Sprut selbst zeigt ja selbst genug Codeschnipsel mit "bsf", "bcf" in ein
und dem selben Register OHNE "nop" dazwischen.
Vermutlich sind in irgend welchen Listings zwischen 2 Bitbefehlen ein
NOP eingefügt wenn eine Leitung getaktet wird etc.
Also Jungs, herzlichen Dank noch mal an alle.
Der Fehler lag natürlich bei mir. Und das auch noch bei einem Winzling
8-Pinner, der was um nen Euro herum kostet!
Das Register CMCON war falsch initialisiert. Es ist nach Reset auf 0x00,
muß aber nach nochmaligem genauem Hinschauen ins Datenblatt auf 0x07
initialisiert sein, damit der Komparator aus ist, und die zugehörigen
drei GPIO-Pins digitale I/O werden. Auch das Register ANSEL muß nach
Reset gelöscht werden, damit die I/O digital sind. Es steht nach Reset
auf 0x0F. Also anders herum als bei CMCON.
CMCON und ANSEL müssen also nach Reset initialisiert werden. Wenn man es
nicht tut, wie auch in einigen Beispielcodes, dann funktionieren die I/O
trotzdem auch digital. Mir fiel da über die Jahre wirklich nichts auf.
In Beispielen wurde das CMCON oft auch gar nicht beachtet, und bei
höheren Taktfrequenzen fällt die von mir beobachtete Funktionsweise ja
auch gar nicht auf.
Die Sache mit den NOPs versuchte ich noch mal, das spielt aber überhaupt
gar keine Rolle. Jetzt nach der richtigen Initialisierung wird jeder
Befehl an I/O genau so ausgeführt, wie es sein soll.
Die Hauptschleife vereinfachte ich noch mal wie folgt:
1
loop:
2
bsf LED1
3
bcf LED2
4
nop
5
nop
6
nop
7
nop
8
bsf LED2
9
bcf LED1
10
nop
11
nop
12
goto loop
Sie läuft in etwas mehr als 10 Sekunden einmal durch, ich verlängerte
noch mal die Zeitkonstante des RC-Gliedes auf 320ms. Damit hat ein
Taktzyklus ungefähr 0,8 Hz bzw. ca. 1,25 Sekunden Dauer. Man kann bei
jeder Befehlsausführung bequem auf den Sekundenzeiger der Uhr schauen,
und es so mit verfolgen.
Wie schon gesagt, es war nicht ausgesprochen lebenswichtig. Niemand
betreibt in der Regel einen µC mit 1 Hz Taktzyklus. Auf meine Art habe
ich aber jetzt was gelernt, was anderen erst gar nicht auffällt.
Fast gleichzeitig umschalten lassen sich beide Pins bei dieser
Geschwindigkeit natürlich nicht. Ich werde es auch noch mal mit einem
Bytebefehl zum Portzugriff versuchen, ob sich die Sache da genau so
bemerkbar macht, oder nicht.
Kürzlich betrieb ich ja auch noch einen Parallelportbaustein mit 5 Pins
Interface an den I/O, aber mit Normalspeed 1 MHz. Das ging ganz gut.
Hier wurden die Ports wieder mit Bytebefehlen gesetzt.