Forum: Compiler & IDEs [F] 7-Segment multipl.


von Till H. (mohman)


Lesenswert?

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 :)

von Peter D. (peda)


Lesenswert?

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

von Karl H. (kbuchegg)


Lesenswert?

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.

von Till H. (mohman)


Lesenswert?

Hallo zusammen, danke für die Antworten :) Werd das gleich mal 
ausprobieren!

MfG

von Till H. (mohman)


Lesenswert?

okee funzt jetzt und nie wieder delay in einem interrupt ;)

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.