Forum: Mikrocontroller und Digitale Elektronik binäre logik by HanneS


von Klaus Bröntgen (Gast)


Lesenswert?

so, ich mal wieder!

beim Schreiben meiner ASMs gucke ich gerne mal in die Töpfe der
anderen, v.a. den von HanneS. Der kocht nämlich gerne mit logischen
Ausdrücken, was sehr effizient ist (und mir daher gefällt), aber mir
immer wieder Kopfzerbrechen  bereitet...
Aktuell sitze ich am Beschreiben des Pollin-4x27-LCD. Adressierung habe
ich (glaube ich) soweit verstanden. Hier ein Auszug aus HanneS'
"4x27.inc", (locate-macro):

 >;Zeile in Bit 6, Spalte in den Rest:
 >ldi wl,128+((@0 & 1)<<6)+(@1 & 63)

Anmerkung: "@0" enthält die Zeile (0..3) und "@1" die Spalte
(0..26)

der Ausdruck "(@0 & 1)" liefert also eine "00" für die jeweils
obere Zeile und eine "01" für die jeweils untere. Mit "<<6" schiebe
ich diese 00 bzw. 01 and das Bit6, also wird Bit7=0 und Bit6=0 bzw. 1.
Soweit in Ordnung, der Controller ist so adressiert, daß eine "1" an
Bit6 in die zweite Zeile springt. Aber warum erst das "128+...", (=1
an Bit7), wenns dann doch mit 0 überschrieben wird?
Und warum "+(@1 & 63)". Kann man nicht einfach "+ @1" schreiben,
das Ergebnis sollte doch das gleiche sein (Bit0..4 erhalten die
Spalten-Nr., Bit5 bleibt 0)?
Na und dann dieses hier zur Controller-Wahl:

sbr flags,((@0 & 2)<<(lcdcontroller2-1))|((!(@0 & 2))<<lcdcontroller1)

Daran verzweifel ich völlig. HanneS, in welcher Reihenfolge stehen die
Flags im Register? Oder spielt es gar keine Rolle? Ich krieg mit Stift
und Zettel nur Murks raus.....

"(@0 & 2)" liefert eine "00" für Zeile 0/1 (=contr1)und eine "10"
für Zeile 2/3 (=contr2). Entsprechend ergibt "!(@0 & 2)" eine "11"
für Zeile 0/1 und eine "01" für Zeile 2/3. Aber ich bekomme den
Gesamtausdruck nicht aufgelöst....
Ist "(lcdcontroller2-1)" die Stelle rechts vom lcdcontroller2-Flag?
Und warum schiebst Du dorthin?

PS: ist kein Genöle an Deinem Stil, Hannes, ganz im Gegenteil. Ich habe
das locate per logischem Schieben und brcs gelöst, brauche aber dafür 21
Zeilen, deswegen würde ich gerne die andere Denkweise raffen...

Natürlich "darf" auch jeder andere antworten..... ;-)

mfg,
klaus

von Suzanna (Gast)


Lesenswert?

Hi,


> Aber warum erst das "128+...", (=1 an Bit7), wenns dann doch mit 0

> überschrieben wird?

Das wird doch durch die Addition eben nicht überschrieben...

> Und warum "+(@1 & 63)". Kann man nicht einfach "+ @1" schreiben,
> das Ergebnis sollte doch das gleiche sein (Bit0..4 erhalten die
> Spalten-Nr., Bit5 bleibt 0)?

Um sicher gehen, dass sich da wirklich kein hohes Bit mit rein verirrt,
würde ich sagen. Wenn das schon sichergestellt ist, kann man das auch
weglassen.

von Klaus Bröntgen (Gast)


Lesenswert?

>Mit "<<6" schiebe ich diese 00 bzw. 01 and das Bit6, also wird
>Bit7=0 und Bit6=0 bzw. 1.
...ist demzufolge falsch? Die Null wird NICHT auf Bit7 geschoben?

von AxelR. (Gast)


Lesenswert?

Jahaa, der HanneS der KanneS.
<Zitat
 Mit "<<6" schiebe
ich diese 00 bzw. 01 and das Bit6, also wird Bit7=0 und Bit6=0 bzw. 1.
</Zitat

Du schiebst eine 0 oder eine 1 an Bitnr.6 und keine "00" oder "01".
Bitnr.7 wird nicht beeinflusst. Selbst wenn ich mich irren sollte, wird
durch die Addition mit 128 das siebente Bit und (nur dieses) wieder
gesetzt.
..
> Aber warum erst das "128+...", (=1 an Bit7), wenns dann doch mit 0
..
das "128+(" steht VOR der Klammer. Dann wird es doch erst behandelt,
wenn der restliche Term abgearbeitet ist.

Ist wie, wenn einer ein Bild malt. wenn ich es sehe, sag ich KLASSE
(wenns gefällt). Aber ich würde nie auf die Idee kommen, die Farben so
zu mischen, wie der Künstler das gemacht hat.

Ich glaube, auch das ist hier schon fast Kunst.
Wär ich NIE drauf gekommen das so zu machen!

Ich eagle dafür lieber NanoBoards :-))

Viele Grüße an alle

AxelR.

von Suzanna (Gast)


Lesenswert?

Die Addition "128+" ist wie ein binäres ODER mit dem MSB (wenn's
keinen Überlauf gibt), aber das (@0 & 1) maskiert ja nur ein Bit,
nämlich das vormals niederwertigste. Es wird also nicht 01 oder 00
"geschoben" sondern 1 und 0. So fehlt allerdings was von deinem
Bereich 0..3, was ich mir noch nicht erklären kann.

von Klaus Bröntgen (Gast)


Lesenswert?

hm, jetzt, wo Du es sagst, erscheint mir auch logisch. das mit der
Klammer ebenfalls (da hätte ich nun wirklich drauf kommen können!)
jetzt wäre nur noch interessant zu wissen, wozu es die "128" braucht,
lt Datenblatt wird von 0..26 (Zeile1)und 64..90 (Zeile2)adressiert. das
weiß dann wohl nur der Meister selbst....

danke erstmal, ich wusel mich da mal weiter durch....

von Klaus Bröntgen (Gast)


Lesenswert?

@Suzanna:
>So fehlt allerdings was von deinem Bereich 0..3,...

das ist schon in Ordnung, eigentlich wird nur zwischen Zeile 1 und 2
und dann noch zwischen Controller 1 und 2 unterschieden, da das Display
so aufgebaut ist:

Zeile1/Controler1=Zeile 0 (bzw. 1)
Zeile2/Controler1=Zeile 1 (bzw. 2)
Zeile1/Controler2=Zeile 2 (bzw. 3)
Zeile2/Controler2=Zeile 3 (bzw. 4)

von Hannes L. (hannes)


Lesenswert?

> Der kocht nämlich gerne mit logischen
> Ausdrücken, was sehr effizient ist (und mir daher gefällt), ...

Da bin ich aber noch absoluter Anfänger. Wenn du davon etwas mehr sehen
willst, musst du dir die Codes von Peter Dannegger ansehen...
Da bin ich nämlich auch immer am Verzweifeln. Das Verstehen der
Entprellroutine hat auch seine Zeit und viel Graphit & Papier
gebraucht...

;-)

Dass ich dieses Makro geschrieben habe, ist nun schon weit über ein
Jahr her. Wenn ich sowas schreibe, beschäftige ich mich (aktuell) sehr
intensiv damit, wenn es fertig ist, dann benutze ich das nur noch und
kümmere mich nicht mehr um jedes Bit.

Die ganze Bitschieberei hätte man auch dem AVR aufholzen können, aber
das Locate-Makro wird sehr oft aufgerufen, wobei jedesmal der gesamte
AVR-Code eingefügt wird, da muss man den AVR-Code schon klein halten
und die (Rechen-) Arbeit dem Assembler überlassen.

Was soll das Makro tun?
Es soll aus den Angaben Zeile und Spalte die Cursor-Position (eine
Zahl, die in ein Byte passt) errechnen und als CMD an das LCD senden.
Es soll weiterhin dafür sorgen, dass der richtige (und nur der
richtige) Enable-Eingang aktiviert wird, was die Auswahl obere/untere
Displayhälfte bewirkt. Letzteres wird über die beiden Bits im Register
Flags realisiert (Code der LCD-Treiberroutine und des Hauptprogramms
ansehen, Kommentare lesen...)

Die Addition der 128 (es hätte auch ein OR sein dürfen) sorgt dafür,
dass Bit7 gesetzt wird, was zur Folge hat, dass das LCD dies als "Set
DD-RAM-Adress"-Befehl erkennt (es soll doch die Ausgabeposition
gesetzt werden, oder). Mit den restlichen 7 Bit können nun 128
Positionen adressiert werden. Bit 6 bestimmt, ob unter oder über (ab)
64 adressiert wird, also ob die obere Zeile oder die untere Zeile
angesteuert werden soll. Die restlichen 6 Bit geben die Position in der
Zeile an. Das ANDen der Zwischenergebnisse begrenzt das Ergebnis auf die
erlaubten Bits, falls beim Aufruf zu hohe Werte angegeben werden. Dies
kann ohne böse Absicht passieren, denn ich arbeite auch viel mit einem
Display mit 8 Zeilen je 24 Zeichen (Controller MS50530), wobei ich
lediglich eine andere Treiber-Datei einbinde und die gleiche
Print-Sammlung benutze.

Tip:
Denke dir ein paar Variablen für Zwischenergebnisse und zerlege den
Term in einzelne Aufgaben. Berechne dabei jede Bitgruppe separat (das
Datenblatt des LCD ist dabei hilfreich), achte aber dabei darauf, dass
durch falsche Aufrufwerte keine falschen Bits beeinflusst werden
können. Setze dann die einzelnen Bitgruppen wieder zum kompletten
Command-Byte zusammen. Wenn du dann versuchst, wieder alles in eine
Zeile zu pressen, dann sieht dein Term meinem sicher sehr ähnlich,
vermutlich hast du OR statt + verwendet, was in diesem speziellen Fall
nichts ändert (OR ist in jedem Fall richtiger!).

...

von Hannes L. (hannes)


Lesenswert?

Ups...

Da waren aber Viele schneller als ich, da hätt' ich mir ja das
Antworten sparen können...

...

von Klaus Bröntgen (Gast)


Lesenswert?

>(Code der LCD-Treiberroutine und des Hauptprogramms ansehen,
>Kommentare lesen...)

...ja, bin gerade drüber. hab dann auch Dein Uhr-Programm gefunden. Da
ist ersichtlich, daß die Controllerflags so stehn:
 2-1-..(anderer kram)..
warum dann das: "(lcdcontroller2-1)" ist das nicht gleichbedeutend zu
"lcdcontroller1" ?

>dass der richtige (und nur der richtige) Enable-Eingang...

das wird wohl über das konstrukt (@0 & 2)....|(!(@0 & 2).... erreicht,
glaube ich soweit gesehen zu haben.

>Die Addition der 128 .... sorgt dafür, dass Bit7 gesetzt wird, was
>zur Folge hat, dass das LCD dies als "Set DD-RAM-Adress"-Befehl
>erkennt

ja, die frage hätte ich mir sparen können. in einem anderen Programm
mit 2x16 hab ichs ja genauso (wenn auch anders) gemacht....war wohl zu
verweifelt....

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.