(→Tabellen im Programmspeicher) |
|||
Zeile 92: | Zeile 92: | ||
[[Sourcevergleich#Suchen_und_Finden|Einige Überlegungen über Tabellenzugriffe]] wurden ja schon dargestellt. | [[Sourcevergleich#Suchen_und_Finden|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. | 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. | ||
<pre> | <pre> | ||
Zeile 122: | Zeile 122: | ||
</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. | ||
+ | |||
+ | 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. | ||
+ | |||
+ | |||
==Autor== | ==Autor== | ||
Zeile 128: | Zeile 147: | ||
==Siehe auch== | ==Siehe auch== | ||
+ | |||
+ | * [[Sourcevergleich#Bascom_.28State_Machine.29|Tabellenbeispiel für State-Machine]] | ||
* [[Avr]] | * [[Avr]] | ||
* [[Bascom]] | * [[Bascom]] |
Version vom 20. Januar 2006, 10:56 Uhr
Inhaltsverzeichnis
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.
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.