Hallo, vielleicht hat hier jemand eine Idee für mich. Ich betreibe an einem Atemga8 fünf 7-Segmentanzeigen per Multiplexing. Für das Multiplexing verwende ich einen der Timer, Sprache ist C. Jetzt würde ich aber gerne einen Eingabemodus realisieren und komme nicht weiter. Mittels zweier Taster (links - rechts) soll durch die Anzeigen geschaltet werden und mit zwei weiteren Tastern (up - down) sollen die Werte sich ändern lassen. Wie realisiere ich es, dass je nachdem in welcher Anzeige ich mich befinde, diese blinkt und mir die "Editierbarkeit" damit signalisiert? Ich hoffe mein Vorhaben ist einigermaßen verständlich geworden. Hat vielleicht jemand sowas realisiert und würde mir seinen C-Code zur Verfügung stellen?
...das Auslesen der Taster ist nicht mein Problem. Geht im Grunde nur um die Umsetzung des Blinkens einzelner Digits.
Martin schrieb: > Hat vielleicht jemand sowas realisiert und würde mir seinen C-Code zur > Verfügung stellen? Ich würde vorschlagen: lerne einfach mal programmieren. Zumindest den Urschleim. Sehr wahrscheinlich hast du praktisch nix des existierenden Codes selber programmiert oder auch nur verstanden. Immer nur stumpfblöd C&P betrieben. Tja, so ein "Entwicklungskonzept" findet irgendwann ein natürliches Ende...
Es hängt ein wenig davon ab, wie du die Displays multiplext. Aus der Ferne würde ich ein Bitfeld vorschlagen, in dem jedes Bit für ein Digit steht. Ist das Bit gesetzt, wird das Digit gezeigt, sonst bleibt es aus. (Schritt 1) Entweder lässt man nun durch einen 2. Timer das Bit an und aus schalten, oder man lässt im gleichen Timer noch eine Zählvariable als static mitlaufen. Die Menüsteuerung kümmert sich um das Bitfeld.
Martin schrieb: > Wie realisiere ich es, dass je nachdem in welcher Anzeige ich mich > befinde, diese blinkt und mir die "Editierbarkeit" damit signalisiert? Teile und herrsche! Die Aufgabe in Teile zerlegen: - Ziffern 0-9 = 10 Zustände. Zustand Aus = "elfte Ziffer" - Über 4 Flags die jeweilige Stelle Deiner Anzeige ausschaltbar machen, unabhängig davon was der Wert in einer Variable ist die Deine Anzeige normalerweise darstellt. - Eine Variable die von 0 bis 4 geht. 0 = Alle Anzeigen am, 1-4 die entsprechende Stelle aus. - Ein Blinker im Takt wie Du möchtest - Eine Logik um die Tasten Links-Rechts auszuwerten und die Stelle 1-4 auszuwählen die editiert werden soll. Stelle 0 = nichts editieren. - Programmteile die eine Stelle hoch oder runter zählen - Etwas Logik die das alles miteinander verbindet.
c-hater hat eigentlich alles gesagt...
Martin schrieb: > Hat vielleicht jemand sowas realisiert und würde mir seinen C-Code zur > Verfügung stellen Schreiben wir mal einen
1 | volatile uint8_t pos,muxpos; |
2 | volatile char ziffer[5]; |
3 | volatile uint32_t milli; |
4 | char keydown(void) |
5 | {
|
6 | static uint8_t lastkey=0; |
7 | uint8_t key=~PINC; // Tasten an Port C nach Masse schaltend |
8 | uint8_t down=~lastkey&key; |
9 | lastkey=key; |
10 | return down; |
11 | }
|
12 | void timermux(void) // jede Millisekunde |
13 | {
|
14 | muxpos++; if(muxpos>5) muspos=0; |
15 | PORTD=~(1<<muxpos); // Digitdriver an Port D, 0 schaltet Stelle ein |
16 | if(milli/1000<500) |
17 | {
|
18 | PORTB=segment[zahl[muxpos]]; // Segmente an Port B 1 schaltet ein |
19 | }
|
20 | else // natürlich nur wenn im Eingabemode |
21 | {
|
22 | PORTB=0x04; // Unterstrich |
23 | }
|
24 | milli++; |
25 | }
|
26 | void loop() |
27 | {
|
28 | switch(keydown()) |
29 | {
|
30 | case LEFT: if(pos<4) pos++; break; |
31 | case RIGHT: if(pos>0) pos--; break; |
32 | case UP: if(ziffer[pos]<9) ziffer[pos]++; break; |
33 | case DOWN: if(ziffer[pos]>0) ziffer[pos]--; break; |
34 | }
|
35 | delay_ms(10); |
36 | }
|
zahl ist ziffer[0]+10*ziffer[1]+100*ziffer[2]+1000*ziffer[3]+10000*ziffer[4];
Gut, einige Korrekturen
1 | void timermux(void) // jede Millisekunde |
2 | {
|
3 | muxpos++; if(muxpos>4) muspos=0; |
4 | PORTD=~(1<<muxpos); // Digitdriver an Port D, 0 schaltet Stelle ein |
5 | if(pos==muxpos&&milli<500) |
6 | {
|
7 | PORTB=segment[zahl[muxpos]]; // Segmente an Port B 1 schaltet ein |
8 | }
|
9 | else // natürlich nur wenn im Eingabemode |
10 | {
|
11 | PORTB=0x04; // Unterstrich |
12 | }
|
13 | milli++; if(milli>1000) milli=0; |
14 | }
|
Entprellung der Taster mit delay - nunja.... muxpos sollte im Bereich 0...4 bleiben (5 Stellen), der Vergleich if(muxpos>5) ist also IMHO falsch. Du fragst nicht ab, ob die aktuelle Stelle blinken soll. Bei Dir dürften alle blinken. Aus if(milli/1000<500) sollte IMHO if ((milli/1000<500) || (pos != muxpos)) werden. milli und muxpos müssten bis hierher nicht volatile sein, sie werden nur im Interrupt genutzt. if(milli/1000<500) sollte wohl eher if((milli%1024)<512) sein. Wenn man seinen Editor nicht nach Zeilen bezahlt oder in Basic programmiert, braucht man mit Zeilenumbrüchen nicht gar so sparsam umgehen. Aber immerhin, Du hast was abgeliefert, zu dem man Vorschläge machen kann. Der Fragesteller hat nix vorgewiesen.
if(pos==muxpos&&milli<500) Anzeigen sonst Ausblenden Da blinkt dann einiges ;-)
Man macht sowas am einfachsten mit einer Zustandsmaschine (google "state machine"). In Abhängigkeit vom Zustand macht der Timer-Interrupt eben unterschiedliche Dinge, und zwischen den Zuständen gibt es definierte Übergänge, die entweder zeitgesteuert oder durch andere Aktionen ausgelöst werden. Einfach mal nachlesen, dann wird die Sache klar. Zustandsmaschinen sind auch einfach zu dokumentieren und haben dadurch den Vorteil, dass man sich auch nach Jahren noch in seinen Code einfinden kann.
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.