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
Hi. erwähnen sollte ich wohl noch, dass ich die Ideen für Assembler suche ..... Gruß Uboot-Stocki
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.
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
Hi, muß das nicht >ldi ZH, high (2*tabelle) >ldi ZL, low (2*tabelle) heißen? weil der Ram ist doc Word-organisiert. Armin
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
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
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.
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
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
Ne, ich glaube, das Programm stimmt mit meiner Beschreibung ziemlich überein. (Hab bisher noch keinen AVR programmier. :-) )
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
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
Ä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?
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
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.
>>
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
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
>>
.org pc + 0x7F & 0xFF80 ;alignment
<<
schneller, aber ist das auch richtig?
.org pc + 0xFF & 0xFF00 ;alignment
Henk
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.