Forum: Mikrocontroller und Digitale Elektronik Wie Wahrheitstabelle implementieren ?


von UBoot-Stocki (Gast)


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

von UBoot-Stocki (Gast)


Lesenswert?

Hi.

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

Gruß

Uboot-Stocki

von ERDI - Soft (Gast)


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.

von crazy horse (Gast)


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

von Armin Kniesel (Gast)


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

von Jens Renner (Gast)


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

von Thomas Burkhardt (Gast)


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

von Ripper (Gast)


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.

von crazy horse (Gast)


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

von UBoot-Stocki (Gast)


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

von ERDI - Soft (Gast)


Lesenswert?

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

von Thomas Burkhardt (Gast)


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

von UBoot-Stocki (Gast)


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

von Rainer (Gast)


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?

von UBoot-Stocki (Gast)


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

von crazy horse (Gast)


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.

von Henk (Gast)


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

von Peter D. (peda)


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

von Henk (Gast)


Lesenswert?

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

schneller, aber ist das auch richtig?

        .org    pc + 0xFF & 0xFF00              ;alignment

Henk

von Peter D. (peda)


Lesenswert?

@Henk,

es ist richtig, denn 128 Worte = 256 Byte.


Peter

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.