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!
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
Andreas Knaup schrieb: > aber wie lege ich diese Tabelle an? Steht doch oben schon. const unsigned char GrayCode[16] = { blabla , blabla ....};
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/
Das weiß ich schon, nur wie trage ich die hier const unsigned char GrayCode[16] = { blabla , blabla ....}; ein?
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.
> 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
Hab auch noch nicht viel Erfahrung, hat bei uns gerade in der Schule mit C angefangen. Jetzt weiß ich schonmal nen Ansatz, danke.
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...
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 } }
Wenn ich jetzt noch wüsste wie ich die Ports als Ausgang bzw. als Eingang schalten kann, wäre ich Glücklich.
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.
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?
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.