Charlieplexing Segmente und Ziffern
Elektronik-Labor
Projekte
Mikrocontroller PicoBasic
Die hier vorgestellten Programme sind sehr lang. Da wird man den
Verdacht nicht los, dass PicoBasic für diese Aufgaben die falsche
Sprache ist. Tatsächlich wurde eine solche Aufgabe mit Arduino-C
wesentlich kompakter gelöst. Ich wollte es aber trotzdem wissen, geht
das überhaupt mit PicoBasic? Nach vielen mühevollen Stunden kann ich
sagen, dass es machbar ist, wenn es auch sicherlich nicht zu den
typischen Aufgabenfeldern dieser Sprache zählt. Immerhin habe ich bei
der Gelegenheit zum ersten Mal längere Programme getestet und dabei
zwei Fehler in der Software entdeckt und korrigieren können. Siehe Update-Download.
Bisher konnte ich nur konstante Ziffern darstellen. Nun geht es darum,
die einzelnen Segmente in beliebiger Folge einzuschalten. Dazu wurde
für jedes Segment ein eigenes Unterprogramm gebildet, das dann mit
Gosub aufgerufen werden kann. Im ersten Versuch werden die Segmente der
linken Ziffer so gesteuert, dass die Segmente a bis f sich im Kreis
bewegen. Das mittlere Segment g (L17) bleibt aus. Auch für die rechte
Ziffer gibt es bereits die Unterprogramme, sie werden allerdings noch
nicht angesteuert.
REM Display4
0x0800 Pout = 0
0x0900 Pdir = 0
0x0A00 Pullup = 0
0x0B00 Pulldown = 0
L1:
0x2111 Gosub L11:
0x1964 Delay ms = 100
0x2114 Gosub L12:
0x1964 Delay ms = 100
0x2117 Gosub L13:
0x1964 Delay ms = 100
0x211A Gosub L14:
0x1964 Delay ms = 100
0x211D Gosub L15:
0x1964 Delay ms = 100
0x2120 Gosub L16:
0x1964 Delay ms = 100
0x2004 Goto L1:
REM Segmente
L11:
0x0960 Pdir = 0x60
0x0820 Pout = 0x20
0x4800 Return
L12:
0x0960 Pdir = 0x60
0x0840 Pout = 0x40
0x4800 Return
L13:
0x0930 Pdir = 0x30
0x0820 Pout = 0x20
0x4800 Return
L14:
0x0950 Pdir = 0x50
0x0840 Pout = 0x40
0x4800 Return
L15:
0x0948 Pdir = 0x48
0x0840 Pout = 0x40
0x4800 Return
L16:
0x0928 Pdir = 0x28
0x0820 Pout = 0x20
0x4800 Return
L17:
0x0918 Pdir = 0x18
0x0810 Pout = 0x10
0x4800 Return
L21:
0x09C0 Pdir = 0xC0
0x0840 Pout = 0x40
0x4800 Return
L22:
0x09C0 Pdir = 0xC0
0x0880 Pout = 0x80
0x4800 Return
L23:
0x09A0 Pdir = 0xA0
0x0820 Pout = 0x20
0x4800 Return
L24:
0x09A0 Pdir = 0xA0
0x0880 Pout = 0x80
0x4800 Return
L25:
0x0990 Pdir = 0x90
0x0810 Pout = 0x10
0x4800 Return
L26:
0x0990 Pdir = 0x90
0x0880 Pout = 0x80
0x4800 Return
L27:
0x0988 Pdir = 0x88
0x0880 Pout = 0x80
0x18C8 Delay µs = 200
0x4800 Return
Als nächstes sollen beliebige Ziffern angesteuert werden. Es hat
sich gezeigt, dass es günstiger ist, die Unterprogramme nach oben zu
setzen und das Hauptprogramm ganz nach unten. Das erleichtert die
Wiederverwendung der Ansteuer-Routinen. In diesem Fall beginnt das
Hauprogramm mit Goto L50: Alle Unterprogramme liegen dazwischen. Es
handelt sich dabei um die Unterprogramme zum Einschalten der einzelnen
Segmente und ein Unterprogramm zur Zuordnung der Segmente zu den
verschiedenen Ziffern. Das letztere verwendet eine Tabelle der
für jede Ziffer nötigen Segmente, die ganz am Anfang als
Daten-Array aufgebaut wird. Das Gesamtprogramm ist zu lang, um es
komplett abzubilden. Es soll deshalb hier in Teilen vorgestellt werden.
REM Display6
0x0800 Pout = 0
0x0900 Pdir = 0
0x0A00 Pullup = 0
0x0B00 Pulldown = 0
REM Ziffern
0x0200 B = 0
0x013F A = 0x3F
0x3B00 [B+] = A
0x0106 A = 0x06
0x3B00 [B+] = A
0x015B A = 0x5B
0x3B00 [B+] = A
0x014F A = 0x4F
0x3B00 [B+] = A
0x0166 A = 0x66
0x3B00 [B+] = A
0x016D A = 0x6D
0x3B00 [B+] = A
0x017D A = 0x7D
0x3B00 [B+] = A
0x0107 A = 0x07
0x3B00 [B+] = A
0x017F A = 0x7F
0x3B00 [B+] = A
0x016F A = 0x6F
0x3B00 [B+] = A
REM Start
0x0101 A = 1
0x206D Goto L50:
Die Segment-Unterprogramme werden diesmal ohne die Wartezeiten geschrieben, damit diese zentral verändert werden können.
REM Segmente
L2:
0x0960 Pdir = 0x60
0x0820 Pout = 0x20
0x4800 Return
L3:
0x0960 Pdir = 0x60
0x0840 Pout = 0x40
0x4800 Return
...
L15:
0x0988 Pdir = 0x88
0x0880 Pout = 0x80
0x18C8 Delay µs = 200
0x4800 Return
Es folgt das Unterprogramm bei L16 zur Ansteuerung der Ziffern,
vorerst nur für die linke Stelle. Die darzustellende Ziffer 0 ...9 wird
in A übergeben. Da zugehörige Bitmuster wird aus der Tabelle gelesen
und um eine Stelle nach links geschoben. Dadurch bestimmt die
höchstwertige Bit, ob das letzte Segment g mit Gosub L8: eingeschaltet
werden soll. Wenn das Bitmuster in A kleiner als 0x80 ist, wird der
Aufruf übersprungen. In diesem Fall aber folgt die Segment-Wartezeit
von 1 ms, damit am Ende alle Ziffernsegmente gleich hell erscheinen.
Danach wird jedes Segment mit Pdir = 2 abgeschaltet. Damit sind alle
sechs zugehörigen Pinne hochohmige Eingänge. Vorgesehen ist, dass Bit 0
später mal ein Eingang sein könnte und Bit 1 ein universeller Ausgang.
Für jedes folgende Bit wird das Bitmuster um eine Stelle weiter nach
links geschoben und das entsprechende Segment eingeschaltet, falls da
eine 1 steht.
REM Ziffern
L16:
0x3400 B = A
0x3A00 A = [B+]
0x3100 A = A Shl 1
0x0280 B = 0x80
0x244C If A<B Goto L21:
0x212D Gosub L8:
L21:
0x1901 Delay ms = 1
0x0902 Pdir = 2
0x3100 A = A Shl 1
0x2451 If A<B Goto L22:
0x212A Gosub L7:
...
L26:
0x1901 Delay ms = 1
0x0902 Pdir = 2
0x3100 A = A Shl 1
0x246A If A<B Goto L27:
0x211B Gosub L2:
L27:
0x1901 Delay ms = 1
0x0902 Pdir = 2
0x4800 Return
Am Ende steht das Hauptprogramm ab L50. In diesem Fall sollen
aufsteigende Ziffern von 0 bis 9 in der linken Stelle angezeigt werden.
Das Programm verwendet die äußere D-Schleife zur Veränderung der
Ziffern und die innere C-Schleife für die Dauer jeder Ziffer. In diesem
Fall wird jede Ziffer 142 Mal angezeigt, wobei jeweils 7 * 1 ms
gebraucht wird. Damit bleibt jede Ziffer für eine Sekunde stehen. Weil
D von 9 bis 0 herunterzählt, muss die Ziffer durch eine Subtraktion
umgerechnet werden.
REM Start
L50:
0x0409 D = 9
L51:
0x03FF C = 141
L52:
0x3900 A = D
0x3400 B = A
0x0109 A = 9
0x2B00 A = A - B
0x2146 Gosub L 16:
0x256F C*Goto L52:
0x266E D*Goto L51:
0x2800 A = A + 1
0x206D Goto L50:
Von hier ist es nicht mehr weit bis zur Ansteuerung von zwei Ziffern.
Allerdings brauche ich jetzt zwei weitere Variablen. Die Lösung bringt
die Verwendung des Daten-Arrays. An der Stelle [10] steht die
Zehnerziffer und an der Stelle [11] die Einerziffer. Das Programm
Display7.pbas stellt eine absteigende Zahlenfolge von 99 bis 00 dar.
REM Ziffern
L16:
0x020A B = 10
0x3A00 A = [B+]
0x3400 B = A
0x3A00 A = [B+]
0x3100 A = A Shl 1
0x0280 B = 0x80
0x244E If A<B Goto L21:
0x212D Gosub L8:
L21:
0x1901 Delay ms = 1
....
0x020B B = 11
0x3A00 A = [B+]
0x3400 B = A
0x3A00 A = [B+]
0x3100 A = A Shl 1
0x0280 B = 0x80
0x2476 If A<B Goto L28:
0x2142 Gosub L15:
L28:
0x1901 Delay ms = 1
...
REM Start
L50:
0x0463 D = 99
L51:
0x0346 C = 70
L52:
0x3900 A = D
0x020A B = 10
0x2D00 A = A / B
0x3B00 [B+] = A
0x020A B = 10
0x2C00 A = A * B
0x3400 B = A
0x3900 A = D
0x2B00 A = A - B
0x020B B = 11
0x3B00 [B+] = A
0x2146 Gosub L 16:
0x2599 C*Goto L52:
0x2698 D*Goto L51:
0x2800 A = A + 1
0x2097 Goto L50:
Download aller Display-Programme: Display.zip
Elektronik-Labor
Projekte
Mikrocontroller
PicoBasic