Aus RN-Wissen.de
Wechseln zu: Navigation, Suche
Rasenmaehroboter Test

(Bascom Tabellen)
(Siehe auch)
 
(11 dazwischenliegende Versionen von 2 Benutzern werden nicht angezeigt)
Zeile 1: Zeile 1:
 
== Bascom Tabellen ==
 
== Bascom Tabellen ==
{{Baustelle|PicNick}}
+
An sich sind Tabellen in Bascom recht einfach anzuwenden.
  
 +
===Tabellen im SRAM / ERAM / XRAM===
 +
Man schreibt einfach bei einer Feld-dimensionierung eine Zahl dazu, und schon gibt es dieses Feld mehrfach
 +
DIM tabelle(24) as byte
 +
DIM strings(8) as string * 18
 +
Um ein Element zu adressieren, wird einfach nur zusätzlich zum Feldnamen der Index angegeben
 +
strings(4) = "viertes Element"
 +
strings(7) = "siebtes Element"
 +
Damit lassen sich auch sehr effiziente Schleifen bauen
 +
dim indexwert as byte
 +
for indexwert = 1 to 8
 +
  print strings(indexwert)
 +
next
 +
Dabei ist zu beachten, daß Basic allgemein und daher auch Bascom die Elemente mit "1" beginnend adressiert und nicht mit "0", wie z.B C. Die Angabe "BASE", um das zu ändern, gibt's bei Bascom nicht, also soll es halt so sein. Man darf das halt bei irgendwelchen Rechnungen nie vergessen.
 +
 +
===mehrdimensionale Tabellen===
 +
So direkt hat das der Bascom nicht drauf. Aber man kann sich natürlich helfen.
 +
 +
'''Beispiel'''
 +
 +
Es wird eine 2 dimensionale Tabelle von Words benötigt, sagen wir 6 x 14. Man definiert also
 
<pre>
 
<pre>
$regfile = "m32def.dat"
+
const Max_x = 6
$crystal = 8000000
+
const Max_y = 14
$baud = 9600
+
const Max_z = Max_x * Max_y    ' 6 * 14 = 84
$hwstack = 32
+
$hwstack = 64
+
$framesize = 32
+
' ---------------------------------------------
+
' Pixel Timer                ' 1 mS each pixel
+
' ---------------------------------------------
+
Config Timer0 = Timer , Prescale = 64
+
Const Tim_preload = 131
+
Dim Timerload As Byte
+
  Timerload = Tim_preload
+
  
  On Timer0 Isr_tim0
+
DIM Tabelle(Max_z) as word     
  Timer0 = Timerload
+
DIM tab_index as byte          ' der berechnete eindimensionale Index
' ---------------------------------------------
+
DIM tab_x as byte
' Sync Interrupt
+
DIM tab_y as byte
' ---------------------------------------------
+
DIM help as byte              ' Ein Hilfsfeld zum Rechnen
Config Int0 = Falling
+
  On Int0 Isr_int0
+
  
' ---------------------------------------------
+
' wir wollen das element 4 , 7 adressieren  (cave: 1 - max_x und 1 - max_y, s.o)
' Patterm dimension
+
tab_x = 4
' ---------------------------------------------
+
tab_y = 7
Const Pat_rows = 7
+
Const Pat_cols = 5
+
'----------------------------------------------
+
Const Buf_chars = 16
+
Const Col_chars = Pat_cols * Buf_chars
+
' ---------------------------------------------
+
'    0      Left          Top  255
+
'    |.......|characters|...>.....
+
' ---------------------------------------------
+
Const Col_left = 12
+
Const Col_top = 120
+
' ---------------------------------------------
+
'
+
' ---------------------------------------------
+
Dim Char_buffer As String * Buf_chars
+
  
Dim Charpntr As Word
+
  help = tab_x - 1
Dim Charcount As Byte
+
  help = help * Max_y
Dim Pataddr As Word
+
  tab_index = help + 1
Dim Pattern As Word
+
  tab_index = tab_index + tab_y
Dim Patcol As Byte
+
  tab_index = tab_index - 1
  
Dim Tim_flag As Byte
+
  Tabelle(tab_index) = wert
Dim Show_flag As Byte
+
Dim Work_flag As Byte
+
  
 +
</pre>
 +
Wenn man einmal eine Funktion tab_index = f (x, y) definiert und schreibt, ist das nicht mehr so schlimm.
  
Dim Charval As Byte
+
===Tabellen im Programmspeicher===
Dim Charidx As Byte
+
Auch die gibt es, nur funktioniert die Sache da etwas anders. Der Zugriff mittels "RESTORE" und "READ" ist natürlich wie gewohnt möglich, nur ist so kein direkter Zugriff in vernünftiger Zeit zu machen
Dim Line_ctl As Byte
+
Dim Charout As Byte
+
    Enable Int0
+
    Enable Timer0
+
    Start Timer0
+
    Enable Interrupts
+
  
     Pattern = Loadlabel(char_pattern)
+
Beim Anlegen der Tabelle müssen natürlich die Werte gleich reingeschrieben werden, zur Laufzeit geht da nix mehr. 
 +
<pre>
 +
Byte_Tabelle:
 +
  DATA     $00, $01, 23, ...........
 +
Integer_Tabelle:
 +
  DATA    0%, 1%, 23%, -23%, ...........  ' da gehen dann auch negative Zahlen
 +
Long_Tabelle:
 +
  DATA    0&, 3840&, 23&, -23&, ........... 
 +
Single_Tabelle:
 +
  DATA    0.44!, 3840!, 23.67!, -23!, ........... 
 +
</pre>
 +
Klarerweise geht nur lesen, dabei ist auf die richtige Definition von "Wert" zu achten, und die muß zu der Tabelle passen, z.B.:
 +
DIM Wert as Byte
 +
Wert = LOOKUP (12, Byte_tabelle)
  
' ---------------------------------------------
+
DIM Wert as Integer 
'              Set Input
+
  Wert = LOOKUP (12, Integer_tabelle)
' ---------------------------------------------
+
  Char_buffer = "0123456789ABCDEF"
+
  
' ---------------------------------------------
+
''' Vorsicht: das erste Byte wird hier mit der Nummer = 0 angesprochen'''
'             Initial conditions
+
Bitte keine Anfragen, ich kann das auch nicht erklären !
' ---------------------------------------------
+
  Patcol = 0
+
  Line_ctl = 0
+
  Work_flag = 0
+
  
  Do
+
Natürlich lassen sich auch mehrdimensionale Tabellen simulieren, genau wie bei den SRAM /EPROM Tabellen
      If Tim_flag = 1 Then
+
        Tim_flag = 0
+
        If Show_flag = 1 Then
+
            Print Bin(charout)
+
        End If
+
        Incr Line_ctl
+
        If Line_ctl = Col_left Then
+
            Work_flag = 1
+
            Charpntr = Varptr(char_buffer)
+
            Charcount = Buf_chars
+
        End If
+
        If Work_flag = 1 Then
+
            If Patcol = 0 Then
+
' read character & find pattern
+
              Patcol = 1
+
              Charval = Inp(charpntr)
+
              Charidx = Lookdown(charval , Char_table , 16)
+
              If Charidx < 255 Then
+
                  Decr Charidx
+
                  Pataddr = Charidx * Pat_cols
+
                  Pataddr = Pataddr + Pattern
+
                  Show_flag = 1
+
              Else
+
                  Show_flag = 0
+
              End If
+
            End If
+
' prepare character pattern------------------------------------------
+
            If Show_flag = 1 Then
+
              Charout = Cpeek(pataddr)                    ' writout pattern
+
              Incr Pataddr
+
            Else
+
              Charout = 0
+
            End If
+
' set next pattern column------------------------------------------
+
            Incr Patcol
+
            If Patcol > 5 Then
+
              Patcol = 0
+
              Print
+
' step next character --------------------------------------------
+
              Incr Charpntr
+
              Decr Charcount
+
              If Charcount = 0 Then
+
' all done
+
                  Work_flag = 0
+
              End If
+
            End If
+
  
      End If
+
Eine interessante Umkehrung: mit dem Befehl "LOOKDOWN" kann ein Wert in einer solchen Tabelle auch gesucht werden, mit dem Index als Ergebnis.  
  End If
+
  Loop
+
  
End
+
DIM Indexnr as byte
'------------------------------------------------
+
DIM Wert as Integer 
Isr_tim0:
+
Wert = 23
  Timer0 = Timerload
+
indexnr = LOOKDOWN (Wert, Integer_tabelle, 5)
  Tim_flag = 1
+
  Return
+
'------------------------------------------------
+
  
Isr_int0:
+
Hier muß die Anzahl der Elemente angegeben werden, im Beispiel ist das 5
  Select Case Line_ctl
+
  Case Is < Col_top:
+
      Incr Timerload
+
  Case Is > Col_top:
+
      Decr Timerload
+
  End Select
+
  Line_ctl = 0
+
  Return
+
'------------------------------------------------
+
  
Char_table:
+
''' Vorsicht: das erste Element wird hier als Indexnr = 1 bezeichnet'''
'-------"0"-"1"-"2"-"3"-"4"-"5"-"6"-"7"-"8"-"9"
+
Bitte keine Anfragen, ich kann das auch nicht erklären !
  Data 48 , 49 , 50 , 51 , 52 , 53 , 54 , 55 , 56 , 57
+
'-------"A"--"B"--"C"--"D"--"E"--"F"
+
  Data 65 , 66 , 67 , 68 , 69 , 70
+
  
 +
Ist der gesuchte Wert nicht enthalten, wird 255 bzw (-1) zurückgegeben.
  
Char_pattern:
+
 
' "0" -------------------------------------------
+
===Anwendungen von Programmspeichertabellen===
Data &B01111100
+
 
Data &B10000010
+
[[Sourcevergleich#Suchen_und_Finden|Einige Überlegungen über Tabellenzugriffe]] wurden ja schon dargestellt.
Data &B10000010
+
====Beispiel 7-Segment-Anzeige====
Data &B01111100
+
Hier brauchen wir für jedes Zeichen nur ein Byte. 7 Bits davon sind für die Display-Segmente a-g. Solange nur die Zahlen 0-9 und A-F dargestellt werden sollen, wird ein einfacher indizierter Zugriff wohl genügen, da ja alle Zeichen vorhanden sind.
Data &B00000000
+
<pre>
' "1" -------------------------------------------
+
Segmente:
Data &B00000000
+
'---------abcdefg.
Data &B00000100
+
  DATA &B11111100    ' 0
Data &B00000010
+
  DATA &B01100000    ' 1
Data &B11111110
+
'... usw. .....
Data &B00000000
+
  DATA &B10011110    ' F
' "2" -------------------------------------------
+
</pre>
Data &B11000100
+
In dieser Tabelle von 16 Bytes kann das darzustellende Zeichen direkt als Zugriffsindex verwendet werden. Wenn z.B. die Segment auf das PORTB auszugeben sind, geht das also sehr einfach:
Data &B10100010
+
<pre>
Data &B10010010
+
DIM Zeichen as Byte
Data &B10001100
+
    Zeichen = 3    ' zum Beispiel
Data &B00000000
+
    PORTB = LOOKUP(Zeichen, Segmente)
' "3" -------------------------------------------
+
</pre>
  Data &B01000100
+
Wenn ein Byte hexadezimal, also beide Nibbles, dargestellt werden soll, sind natürlich zwei Anzeigen erforderlich
Data &B10000010
+
<pre>
Data &B10010010
+
DIM Zeichen as Byte
Data &B01101100
+
DIM Temp as Byte
Data &B00000000
+
    Zeichen = &H85    ' zum Beispiel 0x85
' "4" -------------------------------------------
+
' hier muß auf die linke Anzeige geschaltet werden
  Data &B00011100
+
    Temp = Zeichen
Data &B00010010
+
    Shift temp, right, 4 ' das obere Nibble muß nach unten, also 0x85 --> 0x08
Data &B11111111
+
    PORTB = LOOKUP(temp, Segmente)
Data &B00010000
+
' jetzt auf die rechte Anzeige schalten
Data &B00000000
+
    Temp = Zeichen AND &H0F    ' das obere Nibble wird gelöscht, also 0x85 --> 0x05
' "5" -------------------------------------------
+
    PORTB = LOOKUP(temp, Segmente)
Data &B10111110
+
Data &B10010010
+
Data &B10010010
+
Data &B01100010
+
Data &B00000000
+
' "6" -------------------------------------------
+
  Data &B01111100
+
Data &B10010010
+
Data &B10010010
+
Data &B01100100
+
Data &B00000000
+
' "7" -------------------------------------------
+
Data &B00000100
+
Data &B00010010
+
Data &B00010010
+
Data &B11111110
+
Data &B00000000
+
' "8" -------------------------------------------
+
Data &B01101100
+
Data &B10010010
+
Data &B10010010
+
Data &B01101100
+
Data &B00000000
+
' "9" -------------------------------------------
+
Data &B00001100
+
Data &B00110010
+
Data &B01010010
+
Data &B10001100
+
Data &B00000000
+
' "A" -------------------------------------------
+
Data &B11111100
+
Data &B00010010
+
Data &B00010010
+
Data &B11111000
+
Data &B00000000
+
' "B" -------------------------------------------
+
Data &B11111110
+
  Data &B10010010
+
Data &B10010010
+
Data &B01101100
+
Data &B00000000
+
' "C" -------------------------------------------
+
Data &B01111100
+
Data &B10000010
+
Data &B10000010
+
Data &B01000100
+
Data &B00000000
+
' "D" -------------------------------------------
+
Data &B10000010
+
Data &B11111110
+
Data &B10000010
+
Data &B01111100
+
Data &B00000000
+
' "E" -------------------------------------------
+
Data &B11111110
+
Data &B10010010
+
Data &B10010010
+
Data &B10000010
+
Data &B00000000
+
' "F" -------------------------------------------
+
Data &B11111110
+
Data &B00010010
+
Data &B00010010
+
Data &B00000010
+
Data &B00000000
+
 
</pre>
 
</pre>
 +
 +
====Beispiel Dot-Matrix-Anzeige====
 +
Hier sind erstmal einige Überlegungen notwendig.
 +
*Für eine 7x5 Anzeige braucht man offensichtlich für jedes Zeichen bei platzsparender Anordnung 5 Byte. Bei um 90<sup>o</sup> gedrehter Speicherung wären sogar 7 Byte erforderlich, und nur 5 Bits wären jeweils in Verwendung. Das wäre doch recht ungünstig. Wenn aber die Zeit für eine Drehung bei der Ausgabe nicht zur Verfügung steht, bleibt wohl nichts anderes übrig.
 +
 +
Ein beliebiges Zeichen könnte als etwa so aussehen:
 +
<pre>
 +
Patterntab:
 +
.....
 +
  DATA  &B01111100    ' column 0 für "0"
 +
  DATA  &B10000010    ' column 1 für "0"
 +
  DATA  &B10010010    ' column 2 für "0"
 +
  DATA  &B10000010    ' column 3 für "0"
 +
  DATA  &B01111100    ' column 4 für "0"
 +
.....
 +
</pre>
 +
Vor dem Zugriff muß ein Index mit 5 multipliziert werden, um den Beginn des richtigen Zeichens zu treffen.
 +
*Wenn wir vom ASCII-Zeichensatz alle druckbaren Zeichen in der Tabelle führen wollen (und können), ist die Tabelle ja immerhin geschlossen, nur für die ersten 32 Steuerzeichen muß uns was einfallen. Dazu können wir vom aktuellen Zeichen-Wert einfach diese Zahl 32 abziehen.
 +
<pre>
 +
DIM Zeichen as Byte
 +
DIM Temp as word
 +
    Zeichen = 48      ' zum Beispiel  Ascii-"0" = 0x30 = d'48'
 +
 +
    Temp = Zeichen - 32
 +
    Temp = Temp * 5                        ' das geht auch flotter, das ist aber nicht das Thema
 +
    PORTB = LOOKUP(Temp, Patterntab)      ' die erste Spalte
 +
    incr Temp
 +
    PORTB = LOOKUP(Temp, Patterntab)      ' die zweite Spalte
 +
  .......usw. bis zur fünften Spalte
 +
</pre>
 +
Noch eine Anmerkung: ob man das Display der 5 Pattern als Schleife ausführen kann und wie, hängt von den sonstigen technischen Erfordernissen ab, daher soll hier nicht weiter darauf eingegangen werden. Es gibt auch unterschiedliche Lösungen für Leerstellen zwischen den einzelnen Zeichen, wenn sie notwendig sind (z.B. bei Graphikdisplays, wo ja alle Pixel dicht aneinander liegen). 
 +
 +
*Haben wir aber nicht vor, tatsächlich alle Zeichen darzustellen, wäre diese Methode recht platzfressend, denn wir müßten ja trotzdem die ganzen 95 (druckbare Zeichen) * 5 = 475 Byte definieren. Besonders schlimm wird es, wenn auch einige Sonderzeichen (Umlaute) dazukommen sollen, die ja irgendwo zwischen 128 und 255 liegen.
 +
 +
Hier kann es zweckmäßig sein, eine Art Mapping-Tabelle dazwischenzuschalten. Sie soll helfen, vom Input-Zeichen zum tatsächlichen Pattern-Index zu finden.
 +
 +
Nehmen wir an, wir wollten wiederum nur die Zahlen 0 - 9 und A - F darstellen. Wir legen dies Zeichen nun einfach geschlossen hintereinander an
 +
<pre>
 +
Patterntab:
 +
  DATA  &B01111100, &B10000010, &B10010010, &B10000010, &B01111100    ' column 0-4 für "0"
 +
.....
 +
  DATA  &B11111110, &B00010010, &B00010010, &B00000010, &B00000010    ' column 0-4 für "F"
 +
</pre>
 +
Und nun ein zweite Tabelle, wo wir die gewünschten Zeichen in dieser Reihenfolge haben, mit ihrem normalen Ascii-Code
 +
<pre>
 +
Mapping:
 +
'-------"0"--"1"--"2"--"3"--"4"--"5"--"6"--"7"--"8"--"9"--"A"--"B"--"C"--"D"--"E"--"F"
 +
  DATA  $30, $31, $32, $33, $34, $35, $36, $37, $38, $39, $41, $42, $43, $44, $45, $46
 +
</pre>
 +
Eine weiter Anmerkung:
 +
  DATA  "0", ...
 +
können wir nicht schreiben, denn das interpretiert Bascom als String und legt in Wirklichkeit 2 Byte an, nämlich $30 und $0 als Stringterminator.
 +
 +
Jetzt können wir es uns ersparen, irgendwas abzuziehen
 +
<pre>
 +
DIM Zeichen as Byte
 +
DIM Temp as word
 +
DIM Index as byte
 +
 +
    Zeichen = 65      ' zum Beispiel  Ascii-"A" = 0x41 = d'65'
 +
 +
    Index = LOOKDOWN(Zeichen, Mapping, 16)    ' 16 Zeichen sind definiert
 +
                                              ' die position in der Mapping-Tabelle gibt den
 +
                                              ' tatsächlichen Index in der Patterntabelle an
 +
 +
    Temp = Index - 1                      ' das ergebnis 1-16 ---> 0 - 15 (s.o.)
 +
    Temp = Temp * 5                        ' wie gehabt
 +
    PORTB = LOOKUP(Temp, Patterntab)      ' die erste Spalte
 +
    incr Temp
 +
.......... usw. fünf Spalten
 +
</pre>
 +
Dabei sollte nach LOOKDOWN der Index auf 255 (-1) abgefragt werden, denn dann ist das Zeichen nicht in der Tabelle enthalten.
  
 
==Autor==
 
==Autor==
Zeile 259: Zeile 198:
  
 
==Siehe auch==
 
==Siehe auch==
 +
 +
* [[Sourcevergleich#Bascom_.28State_Machine.29|Tabellenbeispiel für State-Machine]]
 
* [[Avr]]
 
* [[Avr]]
 
* [[Bascom]]
 
* [[Bascom]]
* [[Interrupt]]
+
 
  
 
[[Kategorie:Robotikeinstieg]]
 
[[Kategorie:Robotikeinstieg]]
 
[[Kategorie:Microcontroller]]
 
[[Kategorie:Microcontroller]]
 
[[Kategorie:Software]]
 
[[Kategorie:Software]]
 +
[[Kategorie:Praxis]]
 
[[Kategorie:Quellcode Bascom]]
 
[[Kategorie:Quellcode Bascom]]

Aktuelle Version vom 22. Januar 2006, 16:55 Uhr

Bascom Tabellen

An sich sind Tabellen in Bascom recht einfach anzuwenden.

Tabellen im SRAM / ERAM / XRAM

Man schreibt einfach bei einer Feld-dimensionierung eine Zahl dazu, und schon gibt es dieses Feld mehrfach

DIM tabelle(24) as byte
DIM strings(8) as string * 18

Um ein Element zu adressieren, wird einfach nur zusätzlich zum Feldnamen der Index angegeben

strings(4) = "viertes Element"
strings(7) = "siebtes Element"

Damit lassen sich auch sehr effiziente Schleifen bauen

dim indexwert as byte
for indexwert = 1 to 8 
  print strings(indexwert)
next

Dabei ist zu beachten, daß Basic allgemein und daher auch Bascom die Elemente mit "1" beginnend adressiert und nicht mit "0", wie z.B C. Die Angabe "BASE", um das zu ändern, gibt's bei Bascom nicht, also soll es halt so sein. Man darf das halt bei irgendwelchen Rechnungen nie vergessen.

mehrdimensionale Tabellen

So direkt hat das der Bascom nicht drauf. Aber man kann sich natürlich helfen.

Beispiel

Es wird eine 2 dimensionale Tabelle von Words benötigt, sagen wir 6 x 14. Man definiert also

const Max_x = 6
const Max_y = 14
const Max_z = Max_x * Max_y    ' 6 * 14 = 84

 DIM Tabelle(Max_z) as word      
 DIM tab_index as byte          ' der berechnete eindimensionale Index
 DIM tab_x as byte
 DIM tab_y as byte
 DIM help as byte              ' Ein Hilfsfeld zum Rechnen 

' wir wollen das element 4 , 7 adressieren   (cave: 1 - max_x und 1 - max_y, s.o)
 tab_x = 4
 tab_y = 7

   help = tab_x - 1
   help = help * Max_y 
   tab_index = help + 1
   tab_index = tab_index + tab_y
   tab_index = tab_index - 1

   Tabelle(tab_index) = wert

Wenn man einmal eine Funktion tab_index = f (x, y) definiert und schreibt, ist das nicht mehr so schlimm.

Tabellen im Programmspeicher

Auch die gibt es, nur funktioniert die Sache da etwas anders. Der Zugriff mittels "RESTORE" und "READ" ist natürlich wie gewohnt möglich, nur ist so kein direkter Zugriff in vernünftiger Zeit zu machen

Beim Anlegen der Tabelle müssen natürlich die Werte gleich reingeschrieben werden, zur Laufzeit geht da nix mehr.

Byte_Tabelle:
  DATA     $00, $01, 23, ...........
Integer_Tabelle:
  DATA     0%, 1%, 23%, -23%, ...........  ' da gehen dann auch negative Zahlen
Long_Tabelle:
  DATA     0&, 3840&, 23&, -23&, ...........  
Single_Tabelle:
  DATA     0.44!, 3840!, 23.67!, -23!, ...........  

Klarerweise geht nur lesen, dabei ist auf die richtige Definition von "Wert" zu achten, und die muß zu der Tabelle passen, z.B.:

DIM Wert as Byte 
Wert = LOOKUP (12, Byte_tabelle)
DIM Wert as Integer  
Wert = LOOKUP (12, Integer_tabelle)

Vorsicht: das erste Byte wird hier mit der Nummer = 0 angesprochen Bitte keine Anfragen, ich kann das auch nicht erklären !

Natürlich lassen sich auch mehrdimensionale Tabellen simulieren, genau wie bei den SRAM /EPROM Tabellen

Eine interessante Umkehrung: mit dem Befehl "LOOKDOWN" kann ein Wert in einer solchen Tabelle auch gesucht werden, mit dem Index als Ergebnis.

DIM Indexnr as byte
DIM Wert as Integer  
Wert = 23
indexnr = LOOKDOWN (Wert, Integer_tabelle, 5)

Hier muß die Anzahl der Elemente angegeben werden, im Beispiel ist das 5

Vorsicht: das erste Element wird hier als Indexnr = 1 bezeichnet Bitte keine Anfragen, ich kann das auch nicht erklären !

Ist der gesuchte Wert nicht enthalten, wird 255 bzw (-1) zurückgegeben.


Anwendungen von Programmspeichertabellen

Einige Überlegungen über Tabellenzugriffe wurden ja schon dargestellt.

Beispiel 7-Segment-Anzeige

Hier brauchen wir für jedes Zeichen nur ein Byte. 7 Bits davon sind für die Display-Segmente a-g. Solange nur die Zahlen 0-9 und A-F dargestellt werden sollen, wird ein einfacher indizierter Zugriff wohl genügen, da ja alle Zeichen vorhanden sind.

Segmente:
'---------abcdefg.
  DATA  &B11111100    ' 0 
  DATA  &B01100000    ' 1 
'... usw. .....
  DATA  &B10011110    ' F

In dieser Tabelle von 16 Bytes kann das darzustellende Zeichen direkt als Zugriffsindex verwendet werden. Wenn z.B. die Segment auf das PORTB auszugeben sind, geht das also sehr einfach:

DIM Zeichen as Byte
    Zeichen = 3     ' zum Beispiel 
    PORTB = LOOKUP(Zeichen, Segmente)

Wenn ein Byte hexadezimal, also beide Nibbles, dargestellt werden soll, sind natürlich zwei Anzeigen erforderlich

DIM Zeichen as Byte
DIM Temp as Byte
    Zeichen = &H85     ' zum Beispiel 0x85
' hier muß auf die linke Anzeige geschaltet werden
    Temp = Zeichen
    Shift temp, right, 4  ' das obere Nibble muß nach unten, also 0x85 --> 0x08
    PORTB = LOOKUP(temp, Segmente)
' jetzt auf die rechte Anzeige schalten
    Temp = Zeichen AND &H0F    ' das obere Nibble wird gelöscht, also 0x85 --> 0x05
    PORTB = LOOKUP(temp, Segmente)

Beispiel Dot-Matrix-Anzeige

Hier sind erstmal einige Überlegungen notwendig.

  • Für eine 7x5 Anzeige braucht man offensichtlich für jedes Zeichen bei platzsparender Anordnung 5 Byte. Bei um 90o gedrehter Speicherung wären sogar 7 Byte erforderlich, und nur 5 Bits wären jeweils in Verwendung. Das wäre doch recht ungünstig. Wenn aber die Zeit für eine Drehung bei der Ausgabe nicht zur Verfügung steht, bleibt wohl nichts anderes übrig.

Ein beliebiges Zeichen könnte als etwa so aussehen:

Patterntab:
.....
  DATA  &B01111100    ' column 0 für "0" 
  DATA  &B10000010    ' column 1 für "0" 
  DATA  &B10010010    ' column 2 für "0" 
  DATA  &B10000010    ' column 3 für "0" 
  DATA  &B01111100    ' column 4 für "0" 
.....

Vor dem Zugriff muß ein Index mit 5 multipliziert werden, um den Beginn des richtigen Zeichens zu treffen.

  • Wenn wir vom ASCII-Zeichensatz alle druckbaren Zeichen in der Tabelle führen wollen (und können), ist die Tabelle ja immerhin geschlossen, nur für die ersten 32 Steuerzeichen muß uns was einfallen. Dazu können wir vom aktuellen Zeichen-Wert einfach diese Zahl 32 abziehen.
DIM Zeichen as Byte
DIM Temp as word
    Zeichen = 48      ' zum Beispiel  Ascii-"0" = 0x30 = d'48'

    Temp = Zeichen - 32
    Temp = Temp * 5                        ' das geht auch flotter, das ist aber nicht das Thema
    PORTB = LOOKUP(Temp, Patterntab)       ' die erste Spalte
    incr Temp
    PORTB = LOOKUP(Temp, Patterntab)       ' die zweite Spalte
  .......usw. bis zur fünften Spalte

Noch eine Anmerkung: ob man das Display der 5 Pattern als Schleife ausführen kann und wie, hängt von den sonstigen technischen Erfordernissen ab, daher soll hier nicht weiter darauf eingegangen werden. Es gibt auch unterschiedliche Lösungen für Leerstellen zwischen den einzelnen Zeichen, wenn sie notwendig sind (z.B. bei Graphikdisplays, wo ja alle Pixel dicht aneinander liegen).

  • Haben wir aber nicht vor, tatsächlich alle Zeichen darzustellen, wäre diese Methode recht platzfressend, denn wir müßten ja trotzdem die ganzen 95 (druckbare Zeichen) * 5 = 475 Byte definieren. Besonders schlimm wird es, wenn auch einige Sonderzeichen (Umlaute) dazukommen sollen, die ja irgendwo zwischen 128 und 255 liegen.

Hier kann es zweckmäßig sein, eine Art Mapping-Tabelle dazwischenzuschalten. Sie soll helfen, vom Input-Zeichen zum tatsächlichen Pattern-Index zu finden.

Nehmen wir an, wir wollten wiederum nur die Zahlen 0 - 9 und A - F darstellen. Wir legen dies Zeichen nun einfach geschlossen hintereinander an

Patterntab:
  DATA  &B01111100, &B10000010, &B10010010, &B10000010, &B01111100     ' column 0-4 für "0" 
.....
  DATA  &B11111110, &B00010010, &B00010010, &B00000010, &B00000010     ' column 0-4 für "F" 

Und nun ein zweite Tabelle, wo wir die gewünschten Zeichen in dieser Reihenfolge haben, mit ihrem normalen Ascii-Code

Mapping:
'-------"0"--"1"--"2"--"3"--"4"--"5"--"6"--"7"--"8"--"9"--"A"--"B"--"C"--"D"--"E"--"F"
  DATA  $30, $31, $32, $33, $34, $35, $36, $37, $38, $39, $41, $42, $43, $44, $45, $46 

Eine weiter Anmerkung:

 DATA  "0", ...

können wir nicht schreiben, denn das interpretiert Bascom als String und legt in Wirklichkeit 2 Byte an, nämlich $30 und $0 als Stringterminator.

Jetzt können wir es uns ersparen, irgendwas abzuziehen

DIM Zeichen as Byte
DIM Temp as word
DIM Index as byte

    Zeichen = 65      ' zum Beispiel  Ascii-"A" = 0x41 = d'65'

    Index = LOOKDOWN(Zeichen, Mapping, 16)    ' 16 Zeichen sind definiert
                                              ' die position in der Mapping-Tabelle gibt den 
                                              ' tatsächlichen Index in der Patterntabelle an

    Temp = Index - 1                       ' das ergebnis 1-16 ---> 0 - 15 (s.o.) 
    Temp = Temp * 5                        ' wie gehabt
    PORTB = LOOKUP(Temp, Patterntab)       ' die erste Spalte
    incr Temp
.......... usw. fünf Spalten

Dabei sollte nach LOOKDOWN der Index auf 255 (-1) abgefragt werden, denn dann ist das Zeichen nicht in der Tabelle enthalten.

Autor

Siehe auch


LiFePO4 Speicher Test