Problem beim Multiplexen von Siebensegmentanzeigen

OP #2538367
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
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
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
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
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
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
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

Eine eigene Frage? Dieser Thread ist über 14 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.