Forum: Mikrocontroller und Digitale Elektronik 7-Segment Display mit Einzeleingabe (einzelnd blinkede Digits) - C-Beispielcode gesucht


von Martin (Gast)


Lesenswert?

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?

von Martin (Gast)


Lesenswert?

...das Auslesen der Taster ist nicht mein Problem. Geht im Grunde nur um 
die Umsetzung des Blinkens einzelner Digits.

von c-hater (Gast)


Lesenswert?

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...

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

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.

von Experte (Gast)


Lesenswert?

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.

von Harry L. (mysth)


Lesenswert?

c-hater hat eigentlich alles gesagt...

von MaWin (Gast)


Lesenswert?

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];

von Experte (Gast)


Lesenswert?

Harry L. schrieb:
> c-hater hat eigentlich alles gesagt...

Arroganter Unsympath!

von MaWin (Gast)


Lesenswert?

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
}

von Frank O. (fop)


Lesenswert?

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.

von Frank O. (fop)


Lesenswert?

if(pos==muxpos&&milli<500)
Anzeigen
sonst
Ausblenden

Da blinkt dann einiges ;-)

von marais (Gast)


Lesenswert?

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
Noch kein Account? Hier anmelden.