Problem beim Multiplexen von Siebensegmentanzeigen

OP #2538367
Lesenswert?

Hallo zusammmen,


Ich habe eine Problem beim Multiplexen von Siebensegmentanzeigen.

Anbei oben die Schaltung der DIP in der Schaltung wäre der Anschluss für 
meinen Atmega 128.

Problem:

Auf den Anzeigen schimmern immer schwach die Zahlen der anderen Segmente 
durch. Wenn ich über all die selbe Zahl hinschicke sieht alles gut aus 
nur sobald ich verschiedene Zahlen Anzeige sehen ich immer die segment 
schwach von der anderen mit. Vll hat jemand ne idee.

Danke schonmal

Gruß

Reck
Angehängte Dateien:
#2538377
Lesenswert?

Matthias R. schrieb:

> Auf den Anzeigen schimmern immer schwach die Zahlen der anderen Segmente
> durch. Wenn ich über all die selbe Zahl hinschicke sieht alles gut aus
> nur sobald ich verschiedene Zahlen Anzeige sehen ich immer die segment
> schwach von der anderen mit. Vll hat jemand ne idee.

Programmfehler in der Multiplexroutine.
Du musst die Stellentreiber (rechts im Schaltplan) komplett abschalten, 
ehe du die neue Segmentbelegung mit dem linken Schaltplanteil ausgibst.
OP #2538392
Lesenswert?

Hier ist die Routine dafür schalte ich sie damit nicht gleich aus?
1
void Anzeige(void)
2
{  
3
  //Variablen zum Multiplexen der 7 Segmentanzeigen  
4
  int i;
5
  int segmentp=0;                      // Variablen um das anzusteuerde Segment umzuschalten 
6
  int segmentu=0; 
7
  int stellep[]={1000,100,10,1};              //Arrays für die Spaltentreiber 
8
  int stelleu[]={1000,100,10,1};
9
  for(i=0; i<=3; i++)
10
  {
11
    PORTB=((punkte/stellep[segmentp])%10)|(16<<segmentp);  //Anzuzeigende Zahl und Segmentnummer filtern und in Port schieben
12
    PORTC=((uhr/stelleu[segmentu])%10)|(16<<segmentu);
13
    _delay_ms(4);
14
    segmentp=(segmentp+1)&3;                //erhöhen der für das nächste Segment
15
    segmentu=(segmentu+1)&3;
16
                          //Warteschleife
17
  }
18
 }
#2538418
Lesenswert?

Matthias R. schrieb:
> Hier ist die Routine dafür schalte ich sie damit nicht gleich aus?

Probiers mal so

...
>   for(i=0; i<=3; i++)
>   {
      PORTB = 0;   // alles aus
      PORTC = 0;   // alles aus

>     PORTB=((punkte/stellep[segmentp])%10)|(16<<segmentp);
> //Anzuzeigende Zahl und Segmentnummer filtern und in Port schieben
>     PORTC=((uhr/stelleu[segmentu])%10)|(16<<segmentu);
>     _delay_ms(4);
>     segmentp=(segmentp+1)&3;                //erhöhen der für das
> nächste Segment
>     segmentu=(segmentu+1)&3;
>                           //Warteschleife
>   }
>  }
> [/C]

wenn das nicht reicht, dann könntest du noch versuchen eine kleine Pause 
zwischen ausschalten und neu einschalten einzulegen. Die Fets brauchen 
auch ein wenig Zeit um abzuschalten!

PS: dieser Multiplex ist Mist. Du brauchst eine Timer-ISR, die 
regelmässig aufgerufen wird. Und in der schaltest du bei jedem 
ISR-Aufruf um 1 Stelle weiter. Gewöhn dir besser gleich jetzt auf der 
Stelle ab, _delay_ms zu verwenden. Am besten vergisst du gleich wieder, 
dass es diese Funktion gibt. Sie führt bei Leuten, die damit nicht 
umgehen können fast immer zu schlechtem Programmdesign. (Soll heißen: 
Man kann sie verwenden, muss aber wissen was man tut)
Ganz zu schweigen von der unnötigen Rechnerei während des Multiplexens.
OP #2538429
Lesenswert?

Hmm ja das war jetzt auch mein gedanke wo das mit dem ausschalten kam.
Ja mit nem Interrupt wäre bestimmt besser aber ich bin noch ziemlicher 
Anfänger daher wollte ich es erstmal auf eine relativ einfache art 
lösen.
Falls es nicht klappt muss ich es wohl anders versuchen

Danke schonmal
#2538432
Lesenswert?

Matthias R. schrieb:
> Hmm ja das war jetzt auch mein gedanke wo das mit dem ausschalten kam.
> Ja mit nem Interrupt wäre bestimmt besser aber ich bin noch ziemlicher
> Anfänger daher wollte ich es erstmal auf eine relativ einfache art
> lösen.

FAQ
ganz unten, letztes Kapitel - Timer.
Ist einfacher als du denkst. Und irgendwann musst auch du ins kalte 
Wasser springen. Also, warum nicht hier. Zumal das nur Vorteile hat.
#2538443
Lesenswert?

Ach, da seh ich noch was.

Du verwendest exzessiv int.
Tu das nicht! int ist auf deinem AVR 16 Bit gross, d.h. du jagst deinen 
AVR in unnötige 16 Bit Arithmetik rein. Kostet nur Rechenzeit, bringt 
dir aber nix.

Für zb
   for( i = 0; i < 3; i++ )

sind 8 Bit (0 bis 255) völlig ausreichend. Mehr braucht es nicht.

ALso: überlegen welchen Wertebereich Variablen haben können/sollen und 
dann dementsprechend den Datentyp festlegen

  uint8_t       8 Bit ohne Vorzeichen  ( 0 .. 255 )
  int8_t        8 Bit mit Vorzeichen   ( -128 ... 127 )
  uint16_t     16 Bit ohne Vorzeichen  ( 0 .. 65535 )
  int16_t      16 Bit mit Vorzeichen   ( -32768 ... 32767 )

Und plain vanilla int streichst du gleich mal aus deinem Wortschatz.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren