Forum: Mikrocontroller und Digitale Elektronik 4-stellige 7-Segment-Anzeige (8051)


von Raphael B. (epron)


Lesenswert?

Guten Tag,
da ich doch recht unerfahren mit Mikrocontrollern bin, suche ich eure 
Hilfe.
Ich möchte einen Zähler machen, der von 0000 - 9999 zählt, jedoch 
scheitere ich schon bei der Anzeige.

Mein aktueller Sourcecode:
1
#include <AT898252.h>
2
3
unsigned char seg7code[] = {0x3F, 0x6, 0x5B, 0x4F, 0x66, 0x6D, 0x7C, 0x7, 0x7F, 0x67};
4
5
void setVisual(char display, char number) {
6
  P0 = 0x0F; // Deaktiviere 4-stellige 7-Segment-Anzeige
7
8
  switch (display) {
9
    case 0: P0 = 0x0E; P1 = number; break;
10
    case 1: P0 = 0x0D; P1 = number; break;
11
    case 2: P0 = 0x0B; P1 = number; break;
12
    case 3: P0 = 0x7;  P1 = number; break;
13
  }// switch     
14
15
  P0 = 0; // Aktiviere 4-stellige 7-Segment-Anzeige
16
}// end setVisual
17
18
void main(void) {
19
  setVisual(0, seg7code[1]);
20
  setVisual(1, seg7code[2]);
21
  setVisual(2, seg7code[3]);
22
  setVisual(3, seg7code[4]);
23
24
  while(1) {
25
    // ...
26
  }// while
27
}// end main

8051winXL (muss ich leider verwenden):
http://i.epvpimg.com/7Hhjg.png


Das Problem:
Wenn ich alle Anzeigen freigebe (P0 = 0), dann übernehmen alle Anzeigen 
den aktuellen Wert von P1. Wie kann ich dies verhindern? Es soll 
testweise 4,3,2,1 angezeigt werden.

Vielen Dank :)

von Peter D. (peda)


Lesenswert?

Du benötigst einen Timerinterrupt zum Multiplexen, sonst wird das 
nichts.

Auch wenn Anfänger das nicht einsehen wollen, Multiplexen im Main ist 
großer Murx.

Vor dem Umschalten aufs nächste Digit, erstmal das alte aus, sonst gibts 
Geister.

Und zeig mal den Schaltplan.


Peter

von Raphael B. (epron)


Angehängte Dateien:

Lesenswert?

Also ich habe es jetzt mal mit Timer0 versucht.
Soweit funktioniert das auch, jedoch flackern die Anzeige in 8051winXL 
doch sehr stark und wenn ich den Reloadwert kleiner wähle, dann sieht 
man eben nur eine Ziffer.

Es existiert kein Schaltplan, ich benutze die Standardelemente von 
8051winXl, d.h. die aktuelle Anzeige wird mit P0.0 - P0.3 gesteuert und 
die Ziffer wird mit P1 übergeben.

Im Anhang habe ich meinen aktuellen Code angehängt.

von Klaus (Gast)


Lesenswert?

>Es existiert kein Schaltplan
Hmmm, du hast doch im ersten Beitrag einen Link auf ein Schaltbild 
angegeben!
Haste das so aufgabaut?
Wenn JA: Du hast die Strombegrenzungswiderstände in den Segmentleitungen 
vergessen!
Am Port P1.0 bis P1.7 müssen unbedingt Serienwiderstände rein.
Beispiel / Annahme: Betriebsspannung 5,0 Volt ; Anzeige LED grün (2,0 
Volt) ; Sollstrom 20 mA in Mux.
Ergibt  R = U / I ;  R = (5,0 Volt - 2,0 Volt) / 20 mA = 150 Ohm.
Du brauchst 8 Stück davon (weil auch Dezimalpunkt verdrahtet).

Und die Ratschläge von Peter Dannegger (peda) beachten.

Gruss

von Achim S. (Gast)


Lesenswert?

Hallo Raphael,

nur um sicher zu gehen, dass ich dein System richtig verstehe: du 
benutzt eine Simulationssoftware und wunderst dich, dass dort eine 
gemultiplexte Anzeige stark flackert, richtig?

Das dürfte dann einfach daran liegen, dass die Simulationsoftware das 
Programm sehr viel langsamer ausführt, als es ein realer Mikrocontroller 
tun würde. In einer realen Schaltung würden die Ziffern alle paar µs 
weiter geschaltet werden (was viel zu schnell ist), dort müsstest du den 
Timer-Reload deutlich kleiner wählen.

Außerdem zeigt dein PC-Monitor, der das Simulationsergebnis ausgibt, nur 
ca 60 mal in der Sekunde ein neues Bild. Selbst wenn der Simulator 
schneller Ergebnisse ausgeben sollte kann es passieren, dass du die 
viele dieser Ergebnisse nicht angezeigt bekommst, was du evtl. auch als 
Flackern wahrnimmst.

schöne Grüße

Achim

von Raphael B. (epron)


Lesenswert?

Ich mache das ganze in einer Simulationssoftware, daher kann ich 
schlecht Bauteile einbauen...

Ist das denn so richtig was ich da gemacht habe?
Wenn es nur an der Software liegt bin ich beruhigt.

von Achim S. (Gast)


Lesenswert?

> Ist das denn so richtig was ich da gemacht habe?

dein Code sieht jedenfalls vernünftig aus. Ob wirklich jedes einzelne 
Bit stimmt habe ich jetzt nicht überprüft, das macht man am besten mit 
einem Simulator :-)

Unschön finde ich, dass im Kommentar "// Timer0 Modus2" steht, 
tatsächlich aber der Modus 1 verwendet wird.

Für eine reale Hardware wäre wie schon erwähnt der Timer-Reload Wert 
viel zu hoch. Die Ausgabe auf den Sieben Segment Anzeigen würde völlig 
verschieren, und deine Software würde sich >90% der Gesamtzeit im 
Timerinterrupt befinden.

Als nächsten Schritt willst du ja weitere Funktionen programmieren 
(Zähler 0-999). Falls du dazu eine Zeitbasis benötigst, würde für beide 
Zwecke Timer 2 im 16-bit Auto-Reload Modus verwenden. Damit kannst du 
z.B. genau jede ms einen Interrupt auslösen. In der ISR kannst du das 
Multiplexen erledigen und außerdem ein Flag setzen. Und in der main 
kannst du das Flag auswerten, um die Zeitbasis für deinen Zähler zu 
erzeugen.

viele Grüße

Achim

von Raphael B. (epron)


Lesenswert?

Vielen Dank,
im Simulator funktioniert das soweit (habe Reloadwert geändert, sodass 
es auch als im Main bleibt).

Kommentar wird natürlich sofort geändert :)

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.