Forum: Mikrocontroller und Digitale Elektronik Gray Code -> 7Segment


von Andreas K. (sulospace)


Lesenswert?

Hallo,

ein bisschen Erfahrung habe ich schon in C und den µC. Für die 
Technikerschule zu einem Referat bräuchte ich einen Gray Code->7-Segment 
Codewandler. Ich brauche 4 Eingänge und 7 Ausgänge, der Attiny2313 würde 
da ja ausreichen.
Über Fotodioden wird mit einer Codierscheibe (0-15) der Code abgefragt. 
Wenn eine Fotodiode kein Licht empfängt dann soll dann soll dies quasi 
das High sein.
Nur zur Programmierung habe ich da eine Frage, wie ich da am besten 
vorgehe.
Ich würde eine Schleife machen in der die einzelnen Eingänge abgefragt 
werden:
z.B:
Wenn Eingang 0 Low und Eingang 1 Low und Eingang 2 High und Eingang 
....dann Ausgang X,Y,.. High... usw...
Muss ich dies für jede Mögliche Kombination am eingang machen (also 16 
mal), oder kann man das Irgendwie vereinfachen? Wie setze ich die 
Wertetabelle am besten als C-Programm um?
Wäre froh wenn ihr mir ein paar Tipps geben könntet.

Danke!

von Helmut L. (helmi1)


Lesenswert?

Andreas Knaup schrieb:
> Muss ich dies für jede Mögliche Kombination am eingang machen (also 16
> mal), oder kann man das Irgendwie vereinfachen? Wie setze ich die
> Wertetabelle am besten als C-Programm um?

Du machst eine Tabelle mit 16 Eintraegen.


const unsigned char GrayCode[16] = { 7_Segmentcode fuer0, 7_SegmentCode 
fuer 1, usw. };

In einer Schleife fragst du laufend die 4 Eingaenge an und nimmst diesen 
Wert als Tabellenindex.

unsigned char index

while(1)
{
    index = GRAYPORT & 0x0f;
    SEGMENTPORT = GrayCode[index];
}

GRAYPORT ist dein Eingangsport (Die Eingaenge sind an Bit 0..3)
SEGMENTPORT ist dein 7 Segment Port

von Andreas K. (sulospace)


Lesenswert?

Ok, das Prinzip habe ich verstanden, aber wie lege ich diese Tabelle an?

von Helmut L. (helmi1)


Lesenswert?

Andreas Knaup schrieb:
> aber wie lege ich diese Tabelle an?

Steht doch oben schon.

const unsigned char GrayCode[16] = {  blabla , blabla ....};

von Andreas K. (sulospace)


Lesenswert?

Ich meine was ich für das bla,bla eintragen muss.

von bingo (Gast)


Lesenswert?


von Frank B. (foobar)


Lesenswert?

Viel Erfahrung hast du aber scheinbar noch nicht, daher hier im Detail: 
Für bla,bla schreibst du den Ausgangswert für den Graycode der 
jeweiligen Position rein. Der Beispielcode von Helmut ging davon aus, 
daß GRAYPORT in den Bits 0 bis 3 den Zustand der Portpins zurückliefert, 
an dem deine Gray Code Scheibe angeschlossen ist. Mit "& 0x0f" werden 
alle anderen Bits ausmaskiert, sodaß "index" auf jeden Fall zwischen 0 
und 15 liegt. Damit kannst du dann direkt in der Tabelle nachschlagen, 
welcher Wert mit dem entsprechenden Graycode gemeint ist. Sowas nennt 
man Lookup-Table.

Wenn die Port-Zustände übrigens an anderer Stelle als den Bits 0 bis 3 
liegen, dann musst du die vorher verschieben. Z.B. wenn die an Bit a, b, 
c und d liegen würden:
1
int index = (((GRAYCODE & (1 << a)) >> a) << 3) |
2
(((GRAYCODE & (1 << b)) >> b) << 2) |
3
(((GRAYCODE & (1 << c)) >> c) << 1) |
4
((GRAYCODE & (1 << d)) >> d);

Wenn a, b, c und d Konstanten sind, dann optimieren gute Compiler das 
sehr gut.

Ich habe übrigens mal ein kleines Lisp-Programm geschrieben, was alle 
Gray Codes ausgibt, die bei gegebener Bitlänge möglich sind, denn für 4 
Bits gibt es 24 mögliche Sequenzen:

http://www.frank-buss.de/graycode/

von Andreas K. (sulospace)


Lesenswert?

Das weiß ich schon, nur wie trage ich die hier const unsigned char 
GrayCode[16] = {  blabla , blabla ....}; ein?

von Helmut L. (helmi1)


Lesenswert?

Andreas Knaup schrieb:
> Ich meine was ich für das bla,bla eintragen muss.

Deine 7 Segment Codes. Also welche Segmente bei z.B. einer '0' 
aufleuchten sollen.

Nehmen wir mal an die Segmente a,b,c,d,e,f,g waeren an den Portbits 
0,1,2,3,4,5,6 angeschlossen.

Eine '0'  soll so aussehen

    -
   | |
   | |
    -

Dann muessen die Segmente a = bit 0 , b = bit1  , c = bit 2 , d = bit 3
e = bit 4  , f = bit 5 gesetzt sein.

Hex waere das dann 0x3f.

Also sit der erste Tabellen eintrag

const unsigned char GrayCode[16] = { 0x3f, ....};

Die anderen 7 Segment Abbilder muessen dann weiter eingetragen werden.

von Wegstaben V. (wegstabenverbuchsler)


Lesenswert?

> Ich meine was ich für das bla,bla eintragen muss.


steht auch oben da:

>> bla, bla  = { 7_Segmentcode fuer0, 7_SegmentCode
fuer 1, usw. };


an welchem Port du welches Segment der 7-Segment-Anzeige anklemmst, und 
was das für eine Anzeige ist (gemeinsame Anode oder gemeinsame Kathode) 
das weißt nur du allein. Abhängig von der realen Beschaltung wirst du 
ein "leuchtendes Segment" wohl entweder als 0 oder als 1 in diesem Array 
abspeichern

von Andreas K. (sulospace)


Lesenswert?

Hab auch noch nicht viel Erfahrung, hat bei uns gerade in der Schule mit 
C angefangen. Jetzt weiß ich schonmal nen Ansatz, danke.

von Andreas K. (sulospace)


Lesenswert?

Ok, die Tabelle kann ich erstellen. Aber wie bringe ich das Programm 
dazu bei zB am Eingang 0001 am Ausgang die richtige Kombination zu 
senden?

Hab mir da wohl für meine Anfängerkenntnisse doch etwas zuviel 
vorgenommen...

von Helmut L. (helmi1)


Lesenswert?

Andreas Knaup schrieb:
> Ok, die Tabelle kann ich erstellen.

Schoen.

> Aber wie bringe ich das Programm
> dazu bei zB am Eingang 0001 am Ausgang die richtige Kombination zu
> senden?

Stand oben auch schon drin.


void main(void)
{
      unsigned char index;

      while(1)
      {
            index = GRAYPORT & 0x0f;        // Graycode Port
                                            // einlesen
                                            // und Bits 0..3 maskieren
            SEGMENTPORT = GrayCode[index];  // mit diesem Index in 
Tabelle
                                            // gehen und 7Seg Code
                                            // holen und ausgeben
                                            // und das forever
      }
}

von Andreas K. (sulospace)


Lesenswert?

Wenn ich jetzt noch wüsste wie ich die Ports als Ausgang bzw. als 
Eingang schalten kann, wäre ich Glücklich.

von Helmut L. (helmi1)


Lesenswert?

Andreas Knaup schrieb:
> Wenn ich jetzt noch wüsste wie ich die Ports als Ausgang bzw. als
> Eingang schalten kann, wäre ich Glücklich.

Dazu gibt es das DataDirectionRegister.

Schau mal nach DDRA , DDRB, DDRC Register im Datenblatt.
Eine '1' an der betreffenden Bitstelle schaltet den Port auf Ausgang um.

von Andreas K. (sulospace)


Lesenswert?

Eine Frage nach, wenn ich das so mache, dann muss die Codierscheibe beim 
Einschalten der Schaltung immer auf 0 sein, oder? Oder was passiert wenn 
die Codierscheibe auf einer anderen Codezahl steht?

von Helmut L. (helmi1)


Lesenswert?

Die kann stehen wie sie will. Das ganze ist doch ein absolutes Verfahren 
und kein inkrementelles.

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.