www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Wie Wahrheitstabelle implementieren ?


Autor: UBoot-Stocki (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,

bei meinem aktuellen Projekt habe ich mehrere Schalter, die in
bestimmten Kombinationen verschiedene Bitmuster an einem IO-Port
erzeugen sollen.

Ganz allgemein gesprochen, möchte ich eine Wahrheitstabelle im Programm
abbilden. Bsp:

; 1 2 3 | 4 5 6
; -------------
; 0 0 0 | 0 1 0
; 0 0 1 | 1 0 0
; 0 1 0 | 0 0 0
; 0 1 1 | 0 1 0
; 1 0 0 | 1 0 0
; 1 0 1 | 0 1 1
; 1 1 0 | 1 0 0
; 1 1 1 | 1 0 1

Beim Auftreten der genannten Kombinationen an den BITs 1,2 und 3 sollen
auf den an den BITs 4,5 und 6 die angegebenen Muster (Beispielhaft)
erzeugt werden.

Ideal wäre doch, wenn man die Tabelle z.B. ins Memory schreibt und dann
(abh. von der Kombination am "Eingang") die Ergebnisse auslesen
könnte.

Wie kann man sowas machen ?

Wer hat Ideen ?

Gruß

UBoot-Stocki

Autor: UBoot-Stocki (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi.

erwähnen sollte ich wohl noch, dass ich die Ideen für Assembler suche
.....

Gruß

Uboot-Stocki

Autor: ERDI - Soft (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Erstelle doch ne Tabelle mit 'DB' an einer bestimmten Adresse, lese
den Eingang ein und springe zur Adresse der Tabelle plus dem gelesenen
Wert am Port. Dann hast du automatisch den richtigen Wert.

(Sprung nach 'Adresse der Tabelle' + 'Port' = Ausgabe)

Hoffe, du verstehst, was ich meine.

Autor: crazy horse (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
read_tabelle:
ldi ZH, high (tabelle)
ldi ZL, low (tabelle)
add ZL, r16     ;r16 enthält input
brnc pointer_ok
inc ZH          ;falls übertrag ZL->ZH
lpm             ;liest das entsprechende byte aus der tabelle nach R0
ret


tabelle:
.db 0b010
.db 0b100
usw

Autor: Armin Kniesel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,

muß das nicht
>ldi ZH, high (2*tabelle)
>ldi ZL, low  (2*tabelle)
heißen?

weil der Ram ist doc Word-organisiert.


Armin

Autor: Jens Renner (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

Das gilt meiner Meinung nach nur für Daten im Programmspeicher.
Bei Daten im RAM referenziere ich immer low(label)/high(label).
Ist nicht der Programmspeicher word-weise organisiert und der RAM
byte-weise? So schien es mir in den Specs dargestellt...
Auf jeden Fall ist das der einzige Weg, mit dem es bei mir
funktioniert.

Jens

Autor: Thomas Burkhardt (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

so wie's oben dasteht scheint die Tabelle aber im Programmspeicher
nicht im RAM zu sein. Dann muss der Z-Pointer auch wie von Armin
angegeben initialisiert werden.


Grüße

Autor: Ripper (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
würde ich auch so machen wie erdi, eventuell noch um net gar zu
verschwenderisch zu sein die bytes jeweils in die unteren und oberen 4
bit unterteilen.

Autor: crazy horse (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
klar muss mit 2 multipliziert werde, ich Döskopp :-)
und noch was: jede neue .db-Anweisung beginnt eine neue Wordadresse,
also immer eine gerade Anzahl von Bytes in eine Zeile schreiben.

tabelle:
.db 0b010, 0b100

Autor: UBoot-Stocki (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,

wenn ich das richtig sehe, gibt es im Moment zwei Möglichkeiten:

1.) von "ERDI - Soft"
Es wird eine Tabelle von out-Kommandos mit anschliesendem "return"
erstellt. Abhängig vom Eingangswert wird gesprungen.

2.) von "crazy horse"
Verwendung von lpm

Habe ich das so richtig verstanden ?

Gruß

UBoot-Stocki

Autor: ERDI - Soft (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ne, ich glaube, das Programm stimmt mit meiner Beschreibung ziemlich
überein. (Hab bisher noch keinen AVR programmier. :-) )

Autor: Thomas Burkhardt (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

> Es wird eine Tabelle von out-Kommandos mit anschliesendem "return"
> erstellt. Abhängig vom Eingangswert wird gesprungen.

Geht auch, wird aber mehr Code sein, als eine Tabelle, die mit LPM
ausgelesen wird.

Grüße

Autor: UBoot-Stocki (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,

ich versuch das mal zusammenzufassen ...

             ...
             ldi ZH, high (2*tabelle)
             ldi ZL, low (2*tabelle)
             andi r16, 0b00000111     ; Maskiert Bits 0-2
             add ZL, r16              ;r16 enthält input
             brnc pointer_ok
             inc ZH                   ;falls übertrag ZL->ZH
pointer_ok: lpm                       ;liest das entsprechende byte
                                      ;aus der tabelle nach R0
             out PORTB, r0            ; Gibt Kombination aus
             ...

tabelle:
.db 0b010, 0b100             ; Beispielhafte Kombinationen
.db 0b010, 0b100             ; Beispielhafte Kombinationen
.db 0b010, 0b100             ; Beispielhafte Kombinationen
.db 0b010, 0b100             ; Beispielhafte Kombinationen

Ist es das ?

Gruß

UBoot-Stocki

Autor: Rainer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ähm, wenn die Tabelle statisch ist, sich also nicht ändern kann, wärs
nicht am besten einfach die gute alte boolsche Algebra auszupacken und
mit ein paar unds, nichts, oders usw zu arbeiten?

Autor: UBoot-Stocki (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,

das mit der boolschen Algebra stimmt! Man kann sogar das einmal
erlernte (KV-Diagramme etc.) wunderbar einsetzen um die Terme zu
reduzieren.
Jetzt kommt aber ein Punkt ins Spiel: die Lesbarkeit des ganzen später
im Code. Zum Einen habe ich Probleme nach ein paar Tagen das einmal
Codierte wieder zu verstehen -> Es geht schon, ist aber zeitaufwändig.
Zum Anderen schleichen sich Fehler beim Codieren ein.

Da ist eine Wahrheitstabelle im Code wunderbar lesbar und die
Einleseroutine ist universell verwendbar, d.h. in allem Programmen
sieht das immer wieder gleich aus.

Gruß

UBoot-Stocki

Autor: crazy horse (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
für solche, offensichtlich willkürliche, Zuordnung nimmt man keine
Algebra, die kleinste Änderung in nur einem Bit, und schon bricht der
ganze Mist zusammen, d.h. du fängst komplett von vorn an. Ist auch
nicht gerade in 10min erledigt, nur schwer erweiterbar,
unübersichtlich.
Mit LPM ist schon der richtige Weg, dürfte die geringste Codegröße
haben, und auch die schnellste Laufzeit haben.
Alternativ könnte man den Kram auch im EEPROM unterbringen:

.eseg
.db 0,4,2,10

.cseg
read_eeprom_tabelle:
out EEAR, r16
sbi EECR, EERE
in r17, EEDR
ret

Liegt der Anfang der Tabelle nicht bei Adr0 (sollte man eigentlich
nicht verwenden) muss der entsprechende offset noch addiert werden.

Autor: Henk (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>>
             add ZL, r16              ;r16 enthält input
             brnc pointer_ok
             inc ZH                   ;falls übertrag ZL->ZH
pointer_ok: lpm                       ;liest das entsprechende byte

<<

when man immer ein register auf 0x00 hat

  clr r1

gehts sneller
             add ZL, r16              ;r16 enthält input
             adc ZH, r1
             lpm                       ;liest das entsprechende byte

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Es geht auch noch schneller:

;input: r30
;output: r0

        ldi     zh, high(table*2)
        lpm


        .org    pc + 0x7F & 0xFF80              ;alignment
table:  .db     0b100, 0b010, 0b001, 0b111


Peter

Autor: Henk (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>>
        .org    pc + 0x7F & 0xFF80              ;alignment
<<

schneller, aber ist das auch richtig?

        .org    pc + 0xFF & 0xFF00              ;alignment

Henk

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Henk,

es ist richtig, denn 128 Worte = 256 Byte.


Peter

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.