www.mikrocontroller.net

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


Autor: Till H. (mohman)
Datum:

Bewertung
0 lesenswert
nicht 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!
unsigned int Merker =0;

void Display(int num)
{  

  switch (num) 
  {
    case 0: 
    PORTB = 0B11000000;
    PORTD = 0B11101000;break;
    case 1:
    PORTB = 0x00;
    PORTD = 0xA0;break;
    case 2:
    PORTB = 0x80;
    PORTD = 0x78;break;
    case 3:
    PORTB = 0x80;
    PORTD = 0xF0;break;
    case 4:
    PORTB = 0x40;
    PORTD = 0xB0;break;
    case 5:
    PORTB = 0xC0;
    PORTD = 0xD0;break;
    case 6:
    PORTB = 0xC0;
    PORTD = 0xD8;break;
    case 7:
    PORTB = 0x00;
    PORTD = 0xE0;break;
    case 8:
    PORTB = 0xC0;
    PORTD = 0xF8;break;
    case 9:
    PORTB = 0xC0;
    PORTD = 0xF0;break;
    default:
    PORTB = 0x00;
    PORTD = 0x00;break;  
  }
}
      
void SegmentNummer(int zahl)
{
  if (zahl >999)
  {
    zahl=999;
  }
  
  int hunderter = zahl/100;      
  int  zehner = (zahl-(hunderter*100))/10;
  int einer = (zahl-(hunderter*100) - (zehner*10));
  
        
  if(Merker == 0)
  {        
  PORTC &= ~(1<<PC5);
  PORTC &= ~(1<<PC3);
  PORTC |= (1<<PC4);
  Display(einer);
  Merker ++;
  _delay_ms(2);
  }
  if(Merker == 1)
  {
  PORTC &= ~(1<<PC4);
  PORTC &= ~(1<<PC3);
  PORTC |= (1<<PC5);
  Display(zehner);
  Merker ++;
  _delay_ms(2);
  }
  if(Merker == 2)
  {
  PORTC &= ~(1<<PC4);
  PORTC &= ~(1<<PC5);
  PORTC |= (1<<PC3);
  Display(hunderter);
  Merker = 0;
  _delay_ms(2);
  }
}


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

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.
  if(Merker == 0)
  {        
     ...
  }
  else if(Merker == 1)
  {
     ...
  }
  else if(Merker == 2)
  {
     ...
  }

und Peter hat absolut recht: schmeiss die delays raus.

Autor: Till H. (mohman)
Datum:

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

MfG

Autor: Till H. (mohman)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
okee funzt jetzt und nie wieder delay in einem interrupt ;)

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.