[F] 7-Segment multipl.

OP #1132907
Hallo zusammen, ich versuche 3x 7-Segmentaneigen zu multiplexen!
Funktioniert soweit auch!
Meine Frage ist nun, warum die hunderter-Stelle heller leuchtet als die 
anderen!
1
unsigned int Merker =0;
2

3
void Display(int num)
4
{  
5

6
  switch (num) 
7
  {
8
    case 0: 
9
    PORTB = 0B11000000;
10
    PORTD = 0B11101000;break;
11
    case 1:
12
    PORTB = 0x00;
13
    PORTD = 0xA0;break;
14
    case 2:
15
    PORTB = 0x80;
16
    PORTD = 0x78;break;
17
    case 3:
18
    PORTB = 0x80;
19
    PORTD = 0xF0;break;
20
    case 4:
21
    PORTB = 0x40;
22
    PORTD = 0xB0;break;
23
    case 5:
24
    PORTB = 0xC0;
25
    PORTD = 0xD0;break;
26
    case 6:
27
    PORTB = 0xC0;
28
    PORTD = 0xD8;break;
29
    case 7:
30
    PORTB = 0x00;
31
    PORTD = 0xE0;break;
32
    case 8:
33
    PORTB = 0xC0;
34
    PORTD = 0xF8;break;
35
    case 9:
36
    PORTB = 0xC0;
37
    PORTD = 0xF0;break;
38
    default:
39
    PORTB = 0x00;
40
    PORTD = 0x00;break;  
41
  }
42
}
43
      
44
void SegmentNummer(int zahl)
45
{
46
  if (zahl >999)
47
  {
48
    zahl=999;
49
  }
50
  
51
  int hunderter = zahl/100;      
52
  int  zehner = (zahl-(hunderter*100))/10;
53
  int einer = (zahl-(hunderter*100) - (zehner*10));
54
  
55
        
56
  if(Merker == 0)
57
  {        
58
  PORTC &= ~(1<<PC5);
59
  PORTC &= ~(1<<PC3);
60
  PORTC |= (1<<PC4);
61
  Display(einer);
62
  Merker ++;
63
  _delay_ms(2);
64
  }
65
  if(Merker == 1)
66
  {
67
  PORTC &= ~(1<<PC4);
68
  PORTC &= ~(1<<PC3);
69
  PORTC |= (1<<PC5);
70
  Display(zehner);
71
  Merker ++;
72
  _delay_ms(2);
73
  }
74
  if(Merker == 2)
75
  {
76
  PORTC &= ~(1<<PC4);
77
  PORTC &= ~(1<<PC5);
78
  PORTC |= (1<<PC3);
79
  Display(hunderter);
80
  Merker = 0;
81
  _delay_ms(2);
82
  }
83
}


Dieser Code wird über ein Interrupt regelmäßig ausgelöst!
PORTC3-5 sind die Kathoden der Segmente! Die Zahlen in der 
switch-Anweisung kommen soweit alle hin!
Jemand ne Idee !?

Danke schonmal :)
#1132976
Till H. wrote:
> Dieser Code wird über ein Interrupt regelmäßig ausgelöst!

Das ist schlecht.

Ein enormes riesengroßes Delay von superlangen 6ms hat in einem 
Interrupt nichts verloren.
Man landet sonst in der Programmiererhölle.


Der Trick beim Multiplexen ist, daß pro Interrupt immer nur ein einziges 
Digit ausgegeben wird.
Dann fällt das superlange Delay weg und alle Digits leuchten gleich 
hell.

Es ist auch nicht sinnvoll, in jedem Interrupt immer wieder neu die 
Digits zu berechen.
Effizienter ist es, das im Main zu machen und der Interrupt zeigt nur 
an.
Ein Mensch kann eh nicht schneller als einen Wert pro 200ms ablesen.


Peter
#1133003
1 Durchlauf durch die ISR

Angenommen Merker sei gleich 0

  if(Merker == 0)

ist der Fall. Dieser then wird also genommen. Innerhalb des then 
passiert

   Merker ++;

Merker wird dadurch zu 1. Irgendwann ist dieser then Zweig erledigt und 
es geht in der ISR weiter

  if(Merker == 1)

Yep. Ist der Fall Merker wurde kurz vorher auf 1 hochgezählt.
Also wird auch dieser then Zweig genommen. Dort passiert wieder

   Merker ++;

und Merker wird zu 2

Der Fall Merker gleich 1 ist abgearbeitet, und es geht weiter

  if(Merker == 2)

Auch das ist jetzt der Fall.


Die Variable Merker hat bei dir eigentlich keinerlei Funktion. Alle 3 
Fälle werden bei jedem ISR Durchlauf abgearbeitet :-)

Es hätte dich stutzig machen sollen, dass du ohne die delay nichts an 
den Einern und Zehnern siehst.
1
  if(Merker == 0)
2
  {        
3
     ...
4
  }
5
  else if(Merker == 1)
6
  {
7
     ...
8
  }
9
  else if(Merker == 2)
10
  {
11
     ...
12
  }

und Peter hat absolut recht: schmeiss die delays raus.

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 17 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.