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