Hallo mal wieder.
Habe folgendes Problem:
Bin gerade etwas am rumbasteln mit 7 segment Anzeigen im
Multiplexverfahren.
Es scheint ja gängig zu sein, für das ansteuern der jeweiligen Anzeige
die Zahlen/Symbole durch ein entsprechendes array zu codieren also in
z.B:
const char 7SEG[] = {hexwert für 0, hexwert für 1, hexwert für 2, usw.};
um dies dann über einen 8 bit breiten PORT ausgeben zu können:
PORTX = 7SEG[1];
nächstes digit();
PORTX = 7SEG[2];
soweit so primitiv.
Was mache ich jetzt aber, wenn ich z.B aus Platzgründen die Pins von
mehreren PORTs
zusammenfassen muss sagen wir z.B PD0-PD5 für Segmente a-e und PC0-PC2
für Segmente f und DP, um auf meine 8 bits zu kommen. Wie könnte ich mir
in C einen "virtuellen" PORT erstellen, welcher meinen 8 bit wert wie
ich es mir wünsche auf die Portpins verteilt?
Du kannst dir ein Struct bauen, indem du die Pointer auf den jeweiligen Port speicherst, aber wirklich viel bringen tut das nicht, sobald du mehr als einen Port benutzt musst du auch entsprechend viele Schreibzugriffe auf die einzelnen Portes machen. Verschiedene Ports haben immer den Nachteil das man das Digit nicht in einem schreiben kann und je nachdem wieviele benutzt werden dauert es natürlich länger. eine Alternative wäre ein externer IO Expander bzw. ein 7-Segment Treiber.
Gast
#7050620
Meines Wissens geht das nicht direkt. Aber du kannst dir natürlich eine Funktion schreiben, die das aufdröselt und das übergebene Byte an PD0-PD5 und PC0-PC2 schreibt.
Gast
#7050628
Ja, einfach eine Funktion, die nur genau für diese Kombination die Bits aufdröselt. Jede elegante und wiederverwendbare Lösung bringt mehr Verwirrung als Nutzen.
Gast
#7050630
Da gibt es viele Möglichkeiten, jeweils mit Vor- und Nachteilen behaftet. Z.B.: man kann das Array so lassen, wie es ist und mit ein oder zwei Schleifen jeden Port-Pin einzeln setzen/löschen - mit einer Schleife und in der Schleife ein if-Statement zum entscheiden, ob der eine oder der andere Port gerade bearbeitet wird - mit zwei Schleifen, eine für den einen Port, die andere für den anderen Port, das spart das if oder man bleibt bei dem Array, so wie es ist, und manipuliert die Ports/Array-Daten durch Maskieren und entsprechendes verschieben der Bits. PORTX = PORTX & 0b11000000 | 7SEG[1] & 0b00111111 // im Beispiel aus der Frage wäre das für PD PORTX = PORTX & 0b11111100 | 7SEG[1] >> 6 // im Beispiel aus der Frage wäre das für PC der erste &-Teil löscht erst die Pins, die verändert werden sollen und behält die 2 MSB bei, der zweite &-Teil sorgt dafür, dass die Daten in 7SEG nicht die 2 MSB "überschreiben" oder man hat eine sehr zeitkritische Anwendung aber noch etwas Speicher frei, dann kann man die Daten natürlich auch schon entsprechend vorbereitet in 2 Arrays bereitstellen und spart sich das 2te & bzw. das verschieben der MSB.
oder man nimmt einen TM1637 -> 2 Pins , 6 Segmente oder einen max7219 -> 3 Pins , 8 Segmente
Na ich glaube das mit dem Maskieren ist in meinem Fall wohl das Angenehmste. Habe mir auch sowas in der Art überlegt nur habe ich was das Thema Bitmanipulation angeht noch viel zu lernen ;) Großes Danke an euch!
Gast
#7050674
Mach einfach ein SEG-Array für jeden Port. Kein gumgeshifte und kompakt. Z.B.:
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
Gast
#7051111
Holger Z. schrieb: > oder man nimmt einen TM1637 -> 2 Pins , 6 Segmente Wie kommst Du jetzt da drauf, der kann genauso 8 Segmente für jede der 6 Stellen.
Gast
#7051148
Kevin M. schrieb: > Verschiedene Ports haben immer den Nachteil das man das Digit nicht in > einem schreiben kann und je nachdem wieviele benutzt werden dauert es > natürlich länger. Bei einer Multiplexperiode von z.B. 10ms ist es natürlich gaaanz schlimm, wenn Segmengruppen mit einem Zeitversatz von vielleicht 1µs angesteuert werden ;-)
Gast
#7051298
- Segmente seriel ausgeben (Schiberegister) - I2C 7-Segment Treiber verwenden - BCD zu 7-Segment Dekoder verwenden
Ohh wenn ich das hier so Lese, weiss ich gerade wieder Warum ich die MSP430 MPUX V2 und Assembler so liebe, 1 Befehl, beschreibt oder List mir grad alle oder die Gewünschte anzahl Ports :-D Leider in "C" von IAR noch nicht Implementiert Der Compiler macht da immer noch eine Spagetti-Rutiene :-(
Gast
#7051332
Markus P. schrieb: > const char 7SEG[] = {hexwert für 0, hexwert für 1, hexwert für 2, usw.}; Ist das C++ oder Arduino oder was? vgl. K&R "The C Programming Language": 2.1 Variable Names Although we didn't say so in Chapter 1, there are some restrictions on the names of variables and symbolic constants. Names are made up of letters and digits; the first character must be a letter. The underscore `` _ '' counts as a letter; it is sometimes useful for improving the readability of long variable names.
Markus M. schrieb: >> const char 7SEG[] = {hexwert für 0, hexwert für 1, hexwert für 2, usw.}; > > Ist das C++ oder Arduino oder was? Das ist Pseudocode, kein vollständiger, korrekter C Code.
Frage dazu, (rein Interessenshalber) habe ja mit Arduino nix am Hut. Aber der Prozessor unterstützt doch auch Befehle die mehrere Adressen mit einem Rutsch von a nach B schiebt? Dann kann man doch das Display als Shadowbereich im Ram ablegen und mit 1 Befehl das ganze in die Ports schieben, so das garantiert kein "Gezappel" im Display ist? Für Direkt CRT an µC verwende ich das Prinzip auch, das beim Bildaufbau kein Geflicker auf dem CRT/LCD zu sehen ist, und spart nebenbei noch erheblich Code. Wen ich Segmentdisplays habe nehme ich e die µC mit integriertem LCD Kontroller, das macht es erheblich einfacher.. alles etwas OT,(Sorry) aber selbst der Z80 kannte schon den LDIR befehl?
Gast
#7051356
Patrick L. schrieb: > Frage dazu, (rein Interessenshalber) habe ja mit Arduino nix am Hut. Das merkt man, nichtmal eine grobe Übersicht ist vorhanden... > Aber der Prozessor unterstützt doch auch Befehle die mehrere Adressen > mit einem Rutsch von a nach B schiebt? Nun, ich bin auch nicht gerade Arduino-Fan, aber so viel weiß ich dann doch: Das hängt vom Prozessor ab. "Arduino" gibt's schon seit undenklichen Zeiten für (ziemlich verschiedene) Prozessoren, in jüngerer Zeit ist deren Zahl sogar förmlich explodiert.
c-hater schrieb: > nichtmal eine grobe Übersicht ist vorhanden... Richtig erkannt :-) Trotzdem Danke für die Antwort, auch wenn die Frage dabei noch offen bleibt. Etwas Spezifisziert: @TO hat der den Du verwendest, nicht ein µC Drauf der die Befehle unterstützt?
Gast
#7051374
Patrick L. schrieb: > @TO hat der den Du verwendest, nicht ein µC Drauf der die Befehle > unterstützt? Das alleine würde ja noch nicht reichen. Es müssten zusätzlich auch die PORT-Register an linear aufsteigenden Adressen liegen oder sich zumindest irgendwie so hinmappen lassen. Und das ist (zumindest bei den "Arduino-Prozessoren", die ich kenne) bei keinem der Fall. Und selbst wenn es irgendeinen Exoten gibt, bei dem das möglich wäre, wäre es ziemlicher Unsinn, dieses exotische Feature zu verwenden. Eben weil es dann bei allen anderen nicht funktioniert. Sollte logisch sein, oder?
Gast
#7051376
Patrick L. schrieb: > Der Compiler macht da immer noch eine Spagetti-Rutiene :-( Schreib lieber "Befehlsfolge". Vielleicht stehen da die Chancen besser, dass du das unfallfrei hinbekommst. ;-)
Gast
#7051427
Markus P. schrieb: > > Bin gerade etwas am rumbasteln mit 7 segment Anzeigen im > Multiplexverfahren. > > Was mache ich jetzt aber, wenn ich z.B aus Platzgründen die Pins von > mehreren PORTs zusammenfassen muss sagen wir z.B PD0-PD5 für Segmente a-e > und PC0-PC2 für Segmente f und DP, um auf meine 8 bits zu kommen. Keinen Zweifel, das geht sicher - irgendwie. Z.B. könnte man im 7Segment-Code für a-e (resp. PD0-PD5) die unteren 6 bits reservieren und bei der Ausgabe PD6-PD7 trickreich rein- und rausmaskieren. Oder du könntest dir aus Langeweile ein Loch ins Knie bohren und Backpulver einfüllen ... Ich würde mir aber diesen Stress nicht machen, sondern die Ports sinnvoll zuordnen. Aber mach mal wie Du denkst, ist schließlich dein Projekt...
Gast
#7051590
Patrick schrieb: > Ohh wenn ich das hier so Lese, weiss ich gerade wieder Warum ich die > MSP430 MPUX V2 und Assembler so liebe, > > 1 Befehl, beschreibt oder List mir grad alle oder die Gewünschte anzahl > Ports :-D Erzähl mal mehr - kann nichts darüber finden (nur über die MPU, und die kann sowas nicht).
> Das ist Pseudocode, kein vollständiger, korrekter C Code.
DIES!
Gast
#7051696
Markus M. schrieb: > Oder du > könntest dir aus Langeweile ein Loch ins Knie bohren und Backpulver > einfüllen ... Ein wirklich weiterführender Ratschlag. Gelle? Also, daß man sich die Ports nicht so heraussuchen kann, wie es einem grad genehm ist, das ist recht üblich. Oftmals sind die Ports nur bei der größten Gehäuseform (BGA) komplett herausgeführt oder irgendwelche Pins mittendrin sind bereits anderweitig belegt. So konzentriert sich das Problem darauf, eine bestimmte Datenmenge auf verschiedene Ports und Pins zu verteilen. Das muß nicht ein Byte sein, es kann auch mal irgend eine andere Datenbreite haben. Schlußendlich wird man in den meisten Fällen darauf kommen, daß eine stupide Einzelverteilung (hi oder lo) nach dem Übersetzen zum effektivsten Maschinencode führt. Ohne Schleifenkonstrukte und ohne Arrays. Sowas führt hier nur zu zusätzlichem Verwaltungsaufwand. W.S.
W.S. schrieb: > Schlußendlich wird man in den meisten Fällen darauf kommen, daß eine > stupide Einzelverteilung (hi oder lo) nach dem Übersetzen zum > effektivsten Maschinencode führt. Ohne Schleifenkonstrukte und ohne > Arrays. Sowas führt hier nur zu zusätzlichem Verwaltungsaufwand. Wenn die Pin-Verteilung zur Compile-Zeit bekannt ist, kann dieses GCC-Builtin hilfreich sein: --> __builtin_avr_insert_bits https://gcc.gnu.org/onlinedocs/gcc/AVR-Built-in-Functions.html https://godbolt.org/z/sh4bM64Ke
Antwort schreiben
Bitte melde dich an, um einen Beitrag zu schreiben.