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:
1 | ;==================================================================== |
2 | ; File name: extrctest.asm |
3 | ;==================================================================== |
4 | list p=12F675, F=INHX8M ; List Direktive |
5 | #include <p12f675.inc> ; Include-File |
6 | errorlevel -302 ; Unterdrückung Message 302 vom List-File |
7 | |
8 | __CONFIG _CP_OFF & _CPD_OFF & _BODEN_OFF & _MCLRE_ON & _WDT_OFF & _PWRTE_ON & _EXTRC_OSC_NOCLKOUT |
9 | |
10 | ; Test externer RC-Oszillator mit 1µF und 100kOhm. |
11 | ; Die Zeitkonstante ergibt 100ms. |
12 | |
13 | ; Es geht um eine Energieverbrauchsminimierung. |
14 | |
15 | #define BANK1 banksel 0x80 ; Select BANK1 |
16 | #define BANK0 banksel 0x00 ; Select BANK0 |
17 | |
18 | ; Definitionen |
19 | #define LED1 GPIO,GP0 ; Blink-LED |
20 | #define LED2 GPIO,GP1 ; Blink-LED |
21 | |
22 | ; RAM |
23 | udata_shr |
24 | COUNTER res 1 ; Universalzaehler |
25 | ;==================================================================== |
26 | org 00 |
27 | goto start |
28 | ; |
29 | ;==================================================================== |
30 | org 04 |
31 | isr: |
32 | retfie |
33 | ;==================================================================== |
34 | |
35 | ; Achtung! |
36 | ; Die Taktfrequenz ist sehr gering, durch die externe RC-Kombination |
37 | ; vielleicht um die 10 Hz. |
38 | |
39 | start: |
40 | ; |
41 | bcf STATUS,RP0 ; Bank 0 |
42 | clrf GPIO |
43 | movlw 03h ; GP<1:0> sind |
44 | movwf CMCON ; digitale IO |
45 | bsf STATUS,RP0 ; Bank 1 |
46 | movlw b'11111100' ; GP0 und GP1 Output LED-Signalisierung |
47 | movwf TRISIO ; sonst alle Input |
48 | ; |
49 | clrf ANSEL ; Nur PIC12F675 |
50 | ; |
51 | bcf STATUS,RP0 ; Bank 0 |
52 | clrf COUNTER |
53 | ; |
54 | loop: |
55 | ; |
56 | incf COUNTER,f |
57 | btfss COUNTER,0 |
58 | goto loop_2 |
59 | bsf LED1 |
60 | bcf LED2 |
61 | goto loop_done |
62 | loop_2: |
63 | bcf LED1 |
64 | bsf LED2 |
65 | ; |
66 | loop_done: |
67 | goto $+1 ; Hier kann noch mal der Watchdog mit |
68 | goto loop ; hinein, und sonst was |
69 | ; |
70 | ;==================================================================== |
71 | END |
> 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.
2 Bitbefehle hintereinander geht nicht, da muß ein NOP dazwischen. Auf Sprut wird das erklärt, warum.
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? ;-)
Wilhelm Ferkes schrieb: > Meint der eigentlich, ich würde jetzt Sprut komplett absuchen? ;-) Klar. Irgendeiner muss es ja machen. ;-)
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.
Habe es gefunden: es geht um die "I/O speed Falle" - dürfte aber bei 10 Hz nicht ausschlaggebend sein http://www.sprut.de/electronic/pic/fallen/fallen.html
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.
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.