Hallo, habe einen Absolutwertencoder, der einen 16 Bit Gray Code ausgibt. Wie kann ich den denn am einfachsten in Dezimal umrechnen? Gruß Reinhard
Ich kann kein Bascom, aber folgender C-Code sollte das Prinzip verdeutlichen, so dass du es sicher leicht in Bascom umsetzen kannst:
1 | unsigned int graydecode(unsigned int graycode) { |
2 | unsigned int result = 0, i; |
3 | |
4 | for(i=0; i<16; i++) { /* 1 Schleifendurchklauf pro Bit */ |
5 | result ^= graycode; /* result = result xor graycode (bitweise) */ |
6 | graycode >>= 1; /* graycode 1 Bit nach rechts schieben */ |
7 | }
|
8 | return result; |
9 | }
|
Ich kann kein BASCOM, aber in Assembler würde ich eine Lookup-Tabelle mit 16 Bytes im Flash ablegen, bei der die eingelesenen Graycode-Werte als Index auf die gewünschten Dezimalwerte als Inhalt zeigen. In Hochsprachen könnte man das mit einem Konstanten-Array machen, wenn man in der Lage ist, das Array im Programmspeicher anzulegen. ...
@Hannes: > Ich kann kein BASCOM, aber in Assembler würde ich eine Lookup-Tabelle > mit 16 Bytes im Flash ablegen, bei der die eingelesenen Graycode-Werte > als Index auf die gewünschten Dezimalwerte als Inhalt zeigen. Reinhards Encoder liefert aber nicht nur 16, sondern 2 hoch 16, also 65536 unterschiedliche Werte, was die Tabelle ziemlich aufblähen würde.
Sorry, das hatte ich übersehen, ich ging von 16 Werte (4 Bit) aus. Zu schnell und falsch gelesen... (schäm) ...
Hallo Allerseits, besten Dank für die Antworten! Peinlicherweise muß ich eingestehen, das ich von C null Ahnung habe. Das der Wert mit einem anderen XOR verglichen wird und danach um 1 Bit nach rechts verschoben wird, bekomme ich mit, den Gesamtzusammenhang vermag ich leider nicht zu erkennen. Es war auch blöd, das ich angefragt habe, wie man es mit Bascom macht. Wenn jemand mal kurz schreiben würde, wie man da prinzipiell rangeht, genügt das völlig. Das Umsetzen in Bascom wäre kein Problem, ich weiß nur nicht, was das Prinzip der Umrechnung ist. Gruß Reinhard
spasseshalber einfach mal gegoogelt, umrechnung graycode binär schon der 1. Treffer gibt ganz gute Informationen: http://support.automation.siemens.com/WW/llisapi.dll?func=ll&objid=6198414&lang=de&siteid=cseus&aktprim=3&objaction=csopen
> Wenn jemand mal kurz schreiben würde, wie man da prinzipiell > rangeht, genügt das völlig. Ich versuche einmal, eine prinzipielle Herangehensweise zu beschreiben, der Einfachheit halber für 4 statt für 16 Bits. Die 4 Bits des Graycodes seien g3 g2 g1 g0, die 4 Bits des dekodierten Zahlenwertes (der gesuchte "Dezimalwert", der, streng genommen, gar keiner ist) d3 d2 d1 d0. Die Bits des dekodierten Werts errechnen sich wie folgt: d3 = g3 d2 = g3 xor g2 d1 = g3 xor g2 xor g1 d0 = g3 xor g2 xor g1 xor g0 (1) Warum? Ist eben so, das hängt mit der Definition des Graycodes zusammen. Setzt man dies direkt in ein Programm um, müssen die einzelnen Bits erst aus dem Graycodewert extrahiert und hinterher wieder zum Ergebnis zusammengesetzt werden. Eleganter, und effizienter geht es, wenn man sich die bitweise xor-Operation, wie sie die meisten Programmiersprachen (und auch die Prozessorhardware) bieten, zunutze macht. Bei dieser Operation werden nicht einzelne Bits, sondern alle Bits eines Bytes oder eines Integer-Werts in einem Schritt miteinander veknüpft. Folgendes Beispiel verdeutlicht dies: a = 11011101 b = 10100110 ------------------- a bxor b = 01111011 Ich habe hier anstelle des "xor" ein "bxor" geschrieben, um anzudeuten, dass es sich dabei um eine Operation handelt, die mehrere Bits gleichzeitig berechnet. Werden die Formeln in (1) zur Berechnung der Bits des dekodierten Werts geometrisch etwas anders angeordnet d3 = g3 d2 = g3 xor g2 d1 = g3 xor g2 xor g1 d0 = g3 xor g2 xor g1 xor g0 (2) und anschließend um 90° nach links gedreht, ensteht folgendes Berechnungsschema: g3 g2 g1 g0 g3 g2 g1 g3 g2 g3 ----------- d3 d2 d1 d0 (3) In der ersten Zeile steht nun der ursprüngliche Graycode, in der zweiten der gleiche Wert, dessen Bits um eine Stelle nach rechts verschoben sind (g0 fällt dabei heraus), in der dritten Zeile den abermals um 1 Bit nach rechts verschobenen Wert usw.. Die einzelnen Bits jeder Spalte liefern verxort die Ergebnisbits. Nimmt man dafür die bitweise xor-Operation, kann man immer eine komplette Zeile in einem Schritt bearbeiten, also (d3 d2 d1 d0) = (g3 g2 g1 g0) bxor (g2 g1 g0) bxor (g1 g0) bxor (g0) Bei dieser Methode entfällt das explizite Extrahieren und Zusammensetzen der Einzelbits. In C würde der obige Ausdruck so aussehen: d = g ^ (g>>1) ^ (g>>2) ^ (g>>3) Packt man die wiederholten xor-Operationen in eine Schleife, kommt der C-Code aus meinem früheren Beitrag heraus. Alles klar? Ich weiß jetzt natürlich nicht, ob es in Bascom eine bitweise xor-Operation gibt. Eine Operation dieses Namens scheint es zwar zu geben, aber arbeitet diese bitweise? Du kannst dies herausfinden, indem du entweder die Dokumentation liest oder testweise den Ausdruck 1234 xor 4321 berechnen lässt. Kommt 5171 heraus, ist das xor für den Algorithmus geeignet, sonst muss er anders aufgebaut werden. P.S.: Die umgekehrte Umrechnung, nämlich die Generierung eines Graycodes ist übrigens noch einfacher und kommt bei Verwendung des bitweisen xor ohne Schleife aus. g3 = d3 g2 = d2 xor d3 g1 = d1 xor d2 g0 = d0 xor d1 d.h. jedes Bit des Ergebnisses errechnet sich als xor von jeweils zwei benachbarten Bits des "Dezimalwerts". In C mit bitweisem xor: g = d ^ (d>>1)
Beitrag "Re: Drehgeber auslesen" da gab es schon mal eine Diskussion. Es gibt nicht nur DEN Graycode, der sich mit einfachen EXORs umwandeln läßt. Es hängt vom Hersteller des Drehgebers ab, ob man das so einfach machen kann. Der von mit dort genannte Bourns-Drehgeber läßt sich nur über eine Tabelle umwandeln.
@Christoph Kessler: Huch, hab mir das gerade angeschaut, der Code sieht wirklich krank aus. Ich frage mich, was das soll. Vielleicht dient die Redundanz von einem Bit der Fehlererkennung. Damit könnte man z.B. wirksam die Verschleißgrenze erkennen, die gerade bei solchen elektromechanischen Teilen eine wichtige Rolle spielt. Aber ich glaube, einen 16-Bit-Geber wird man normalerweise nicht so bauen, dass er nur über eine Tabelle dekodiert werden kann. Dazu bräuchte man ja mindestens 128 KB Speicher, mit einem 17. redundanten Bit sogar 256 KB, wenn man die Redundanz nutzen will, sogar noch mehr. Mit solchen zusätzlichen Bits lassen sich natürlich unendlich viele beliebig unregelmäßige Graycodevarianten entwickeln. @alle: Was mich deshalb brennend interessieren würde: Gibt es einen nichtredundanten Graycode (also einer, bei dem sich aufeinanderfolgende Werte immer genau in einem einzelnen Bit unterscheiden, und bei dem alle 2**n Werte ausgeschöpft werden), der sich in nichttrivialer Weise von dem Standard-Graycode, der in allen Lehrbüchern angepriesen wird, unterscheidet? Mit nichttrivialer Unterscheidung vom Standardcode meine ich, dass sich der gesuchte Code nicht durch - das Vertauschen der Bitpositionen, - das Umdrehen der Zählrichtung (aufsteigend/absteigend), - oder die Verschiebung der Nullposition in den Standardcode überführen lässt. Für bis zu 3 Bits gibt es danach tatsächlich nur DEN Graycode, das habe ich gerade ausprobiert. Weiß jemand, wie es mir höheren Bitzahlen aussieht? Ich werde mir, wenn heute Abend nichts gescheites im Fernsehen kommt (wovon ich ausgehe) selber auch mal ein paar Gedanken machen.
Aah, nachdem ich das Datenblatt dieses Bourns-Gebers noch einmal angeschaut habe, ist mir klar geworden, warum der Code redundant und so krumm ist: Der Geber hat nicht etwa 8 Spuren mit Bitmustern drauf, sondern nur eine einzige, die an 8 verschiedenen Winkelpositionen abgetastet wird. Sehr interessant, dass so etwas geht.
In BASCOM gibt es die Funktion Gray2Bin welche den Gray-code in einen Binär (Dezimalwert) umrechnet. http://avrhelp.mcselec.com/GRAY2BIN.html Grüße Josef
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.