Forum: Mikrocontroller und Digitale Elektronik 4x7-Segment Anzeige Zeitmultiplex bei 8051 Silicon


von Max L. (max-lenz)


Lesenswert?

Hallo zusammen.

Wir benutzen gerade im Praktikum ein 8051-Board von Silicon.

Die Aufgabe ist: die 4 x 7-Segment-Anzeige mit Hilfe von 
Zeitmultiplex-Verfahren zu steuern, also vonn 0000 bis 9999 hochzählen. 
Der Quellcode soll in C geschrieben und sowohl auf Interrupt als auch 
auf die delay-Funktion verzichtet werden.

Ich habe bißchen zu dem Thema Zeitmultiplex in Foren was durchgelesen. 
Ich weiß nur, dass das menschliche optische Versagen dafür vrantwortlich 
ist, aber verstanden, hab ich das Verfahren nicht.

Ich weiß, dass ich aufjeden Fall einen Zähler brauche, der von 0000 - 
9999 hochzählen soll:
1
 unsigned int cnt = 0;
1
 if (cnt > 9999) cnt = 0;
1
 if (cnt < 0) cnt = 9999;

Dann habe ich einen Look up table für die jeweiligen Zahlen angelegt:
1
 unsigned char LUT[10] = {0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};

Als Hinweis steht, dass wir uns darübr Gedanken machen sollen, wie man 
von einer 16-bit Zahl in dualer Darstellung einzelne Dezimalstellen 
isolieren kann.

Da habe ich folgenden Ansatz:

    tausender = Zahl / 1000;
    hunderter = (Zahl % 1000)/100;
    zehner    = ((Zahl % 1000)%100)/10;
    einser    = (((Zahl % 1000)%100)%10);

Aber ich weiß nicht, wozu man es braucht?

Vielen Dank für Eure Antworten.

von Peter D. (peda)


Lesenswert?

Max Lenz schrieb:
> sowohl auf Interrupt als auch
> auf die delay-Funktion verzichtet werden.

Ohne Delay ist klar, das ist Murks.
Aber ohne Timerinterrupt, wie soll das denn gehen?


Max Lenz schrieb:
> Da habe ich folgenden Ansatz:
>
>     tausender = Zahl / 1000;
>     hunderter = (Zahl % 1000)/100;
>     zehner    = ((Zahl % 1000)%100)/10;
>     einser    = (((Zahl % 1000)%100)%10);
>
> Aber ich weiß nicht, wozu man es braucht?

Also ein kleines bischen Mathe solltest Du schon können.

Man kann dafür auch sprintf() nehmen.


Peter

von Max L. (max-lenz)


Lesenswert?

So steht in der Aufgabenstellung.

Ist die Berechnung der Ziffern so falsch?

von Jan (Gast)


Lesenswert?

>Ohne Delay ist klar, das ist Murks.
>Aber ohne Timerinterrupt, wie soll das denn gehen?

indem du einfach den Takt als Timer nimmst.
--> ein Zyklus Segment 1 anzeigen,
--> nächsten Zyklus Segment 2. usw

du kannst auch ein Vielfaches des Takts nehmen, falls der die Frequenz 
zu ist.
Wenn der Controller nur dieses Programm abarbeitet gibts auch kaum 
Helligkeitsunterschiede.

von mux (Gast)


Lesenswert?

Max Lenz schrieb:
> Aber ich weiß nicht, wozu man es braucht?

Die darzustellende Zahl wird doch sehr wahrscheinlich in einer 16Bit 
Variablen hochgezählt. Wie sieht denn die prozessorinterne Darstellung 
aus?

Um die Elemente in LUT zu adressieren brauchst du die gerade 
darzustellende Wertigkeit der Dezimalstelle.

Ob die Berechnung richtig ist? Kein Simulator laufen?

von Max L. (max-lenz)


Lesenswert?

Die Berechnung stimmt aber ich weiß nicht was si mit multiplexing zu tun 
hat. Ich weiß nicht mal wie multiplexing funktionieren soll??

was meinst du mit gerade?
soll ich di Werte mal 2 nehmen?

von mux (Gast)


Lesenswert?

Max Lenz schrieb:
> was meinst du mit gerade?

Ergibt sich aus dem Multipexing und soll "in diesem Moment" bedeuten. 
Finde gerade den entsprechenden Artikel nicht im µC net deshalb:
http://www.rn-wissen.de/index.php/Siebensegmentanzeige#Multiplexing

von Dietrich L. (dietrichl)


Lesenswert?

Max Lenz schrieb:
> Die Aufgabe ist: die 4 x 7-Segment-Anzeige mit Hilfe von
> Zeitmultiplex-Verfahren zu steuern, also vonn 0000 bis 9999 hochzählen.

Das verstehe ich noch nicht ganz. Ist damit wirklich ein Hochzählen 
gemeint?
"Multiplex" und "Anzeige" lässt mich eher vermuten, dass die Anzeige 
matrixförmig angeschlossen ist und entsprechend angesteuert werden muss: 
zyklisch über Zeilen und Spalten. Das müsste man dann bei der HW sehen 
bzw. bei der Angabe, wie die Anzeige angeschlossen ist (Portbelegung).

Hast Du einen Schaltplan von dem Board oder eine genaue 
Typenbezeichnung?

Gruß Dietrich

von Max L. (max-lenz)


Angehängte Dateien:

Lesenswert?

Es soll einfach von 0 bis 9999 hochgezählt werden.

von Dietrich L. (dietrichl)


Lesenswert?

Max Lenz schrieb:
> Es soll einfach von 0 bis 9999 hochgezählt werden.

Wenn das Deine Schaltung ist, dann ist das ja genau so, wie ich sagte.

Du brauchst dazu 2 Programmteile:
- Ansteuern der Anzeige per Multiplex: die einzelnen Anzeigen SEG1 bis 
SEG4 werden nacheinander einzeln angesteuert, und zwar so schnell, dass 
das Auge die Pausen nicht sieht (eine einzelne Anzeige kann ja nur 25% 
der Zeit eingeschaltet sein). Das Ganze passiert dann zyklisch: SEG1 - 
SEG2 -SEG3 - SEG4 - SEG1 - SEG2 ... usw. und läuft unabhängig vom Rest 
des Programms dauernd.
- Ein Zähler wird hochgezählt; der Wert muss dann noch im Format 
gewandelt werden von der binären Darstellung des Zählers in die dezimale 
Darstellung der Anzeige (aber die Umrechnung hattest Du ja schon - ich 
habe sie allerdings nicht geprüft).

Gruß Dietrich

von Max L. (max-lenz)


Lesenswert?

Ich hab folgende Idee:
1
 
2
#include <compiler_defs.h>
3
#include <C8051F020_defs.h> 
4
5
#define FOREVER while(1)
6
#define NOT !
7
#define DISPLAY_OFF DIGIT1 = DIGIT2 = DIGIT3 = DIGIT4 = 1
8
9
sbit DIGIT1   = P3^0; // 7Segment LEDs, 1. Ziffer, 1000er
10
sbit DIGIT2   = P3^1; // 7Segment LEDs, 2. Ziffer, 100er
11
sbit DIGIT3   = P3^2; // 7Segment LEDs, 3. Ziffer, 10er
12
sbit DIGIT4   = P3^3; // 7Segment LEDs, 4. Ziffer, 1er
13
sbit SPEAKER   = P3^4; // Lautsprecherausgang
14
sbit LED1   = P3^5; // rote LED, links
15
sbit LED2   = P3^6; // gelbe LED, mittig
16
sbit LED3   = P3^7; // gruene LED, rechts
17
sbit DPNT   = P2^7; // 7Segment LED: Dezimalpunkt
18
19
void main ( void )
20
{
21
  const unsigned char code ziffer[10] = \
22
  { 0xc0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8, 0x80, 0x90 };
23
  unsigned int cnt = 0;
24
  unsigned int dly = 0;
25
  unsigned int rst = 0;
26
  unsigned int num = 0;
27
  
28
  WDTCN = 0xDE; 
29
  WDTCN = 0xAD;
30
  P2MDOUT = 0xFF; 
31
  P3MDOUT = 0xFF;
32
  P1 = 0xf7;
33
  XBR2 = 0x40;
34
  DISPLAY_OFF; 
35
        
36
        FOREVER {
37
  if ( ++dly % 200 == 0 ) { cnt++;
38
        if (cnt > 9999) cnt = 0;
39
  if (cnt < 0) cnt = 9999;}

Meine Frage lautet:
kann ich den Code so schreiben:
1
 num = cnt % 10;
2
    P2 = ziffer[num];
3
    DISPLAY_OFF; DIGIT4 = 0;

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.