mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik unsaubere Darstellung der Zahlen bei 7-seg Multiplex


Autor: Tom (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Schönen guten Tag,

ich versuche gerade, 3 7 Segment Anzeigen per Multiplex über einen 
AtMega8 anzusteuern. Alles läuft auch gut, die 3 Anzeigen leuchten und 
zeigen das an, was sie sollen, jedoch nicht so, wie sie es sollen.
Angenommen, es erscheint auf dem Display die Zahl „412“, dann leuchten 
nicht nur die Segmente, welche die 3 Zahlen darstellen, sondern auch 
noch ein paar andere Segmente schwächer. Dadurch lässt sich die Anzeige 
schlechter ablesen und irgendwie wirkt es auch unsauber. Je nach 
eingestellter Zahl leuchten eben andere Segmente noch schwächer mit, die 
es aber nicht sollen. Ich hab mal ein Bild davon angefügt. Die 
fehlerhaft schwach leuchtenden Segmente sind grün umrandet. Außerdem ein 
Bild vom groben Überblick über die LED-Beschaltung mit dem µC.

Die Vorwiderstände für die Segmente sind jeweils 300 Ohm, die 3 
Basiswiderstände für die Transistoren jeweils 1KOhm. Transistortyp: 
BC550B

Ist das Problem nun schaltungsbedingt oder programmabhängig?

Kurioserweise wird das Leuchten der „falschen“ Segmente immer schwächer, 
je niedriger die Multiplexgeschwindigkeit gewählt ist. Nur leider fängt 
die Anzeige dann an zu flackern, logischerweise.


Hier mal die Routinen für das Multiplexing:

  k[1]= Displ1Out;    //Multiplex Transistor 1 schalten
  k[2]= Displ2Out;    //Multiplex Transistor 2 schalten
  k[3]= Displ3Out;    //Multiplex Transistor 3 schalten

//****Zahlen den Segmenten zuweisen****
    j[1] = x[d1];    //Stelle 1
    j[3] = x[d2];    //Stelle 2
    j[2] = x[d3];    //Stelle 3
//*************************************

//****7-Segment-Multiplex**************
    for (i=1;i<=3;i++)
    {
      Out3 = j[i];  //Zahl ausgeben
      _delay_us(100);  //nach 100us weiterschalten
      Out2 = k[i];  //nächstes Segment ansteuern
    }
  }
}
//*************************************


Ich hoffe, dass das bischen Quellcode genügt. Das Programm an sich ist 
ziemlich lang.

So, dann bedank ich mich schon mal!

Grüße Tom

Autor: Matthias Lipinsky (lippy)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das Problem könnte an den übersteuerten Transistoren liegen. 10kHz 
Mux-Frequenz sind ziemlich viel! Baue mal pnp als Kollektorschaltung 
(ohne Basiswiderstände!) ein.

Autor: ARM-Fan (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Was mir beim kurzen Blick auf den Code auffällt:

Mit wievielen Elementen sind denn deine Felder definiert?
Was steht an Index 0 ?

  j[3] = x[d2];    //Stelle 2
  j[2] = x[d3];    //Stelle 3

Hat der Dreher hier einen Grund?

Insgesamt fehlt zur Beurteilung des Codes halt der Rest.
Zumindest alle im Codeschnipsel verwendeten Definitionen.

Autor: capellone (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du solltest vor dem wechsel auf einen anderen multiplextransi
alle segmente ausmachen und erst nach dem wechsel die zu dieser stelle 
gehörigen segmente einschalten. Im Bild sieht man wunderbar in der 
zweiten stelle die 4 der ersten schwach leuchten.

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ Tom (Gast)

>Dateianhang: atme.JPG (144,7 KB, 30 Downloads)

Bildformate

Deine Bauteile in Schaltplan haben kein Werte.

>Basiswiderstände für die Transistoren jeweils 1KOhm. Transistortyp:
>BC550B

Aha, so macht man das heute.

>Ist das Problem nun schaltungsbedingt oder programmabhängig?

Sowohl als auch. Das Nachleuchten ist das zu langsame Abschalten der 
Spaltentransistoren. icht weil die so langsam sind, sondern weil die 
Ansteuerung suboptimal ist.

>//****7-Segment-Multiplex**************
>    for (i=1;i<=3;i++)
>    {
>      Out3 = j[i];  //Zahl ausgeben
>      _delay_us(100);  //nach 100us weiterschalten
>      Out2 = k[i];  //nächstes Segment ansteuern
>    }
>  }
>}
>//*************************************

Komisches Multiplexing. Schon mal was von einem Timer gehört`?
Ausserdem muss zwischen den Umschaltungen ei Pause von 1.2us her, 
solange brauchen deine Tranistoren zum umschalten. Das kann man 
beschleunigen, indem man ca. 22ßpF parallel zu den Basiswiderständen 
lötet.

MFG
Falk

Autor: Tom (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Oh, viele Antworten, Dankeschön!

@ Matthias Lipinsky, wenn ich die Zeit statt 100µs auf 5ms setze, ist 
das Nachleuchten fast weg. Aber dann bild ich mir ein, dass es leicht 
flackert. Außerdem scheint da ja noch ein anderes Prob zu sein, wie alle 
schreiben.

@ ARM-Fan, hier noch die defines zum besseren Verständnis:

#define Out2    PORTB
#define Out3    PORTD
#define Displ1Out  1<<PORTB0
#define Displ2Out  1<<PORTB1
#define Displ3Out  1<<PORTB2

Über den Zahlendreher, der mir im Moment auch schleierhaft vorkommt, 
muss ich noch mal nachdenken. Hab den code vor nen halben Jahr 
programmiert, die Sache aus Zeitmangel auf Eis gelegt und will nun 
weiterarbeiten.

@ capellone, gute Idee, bin dabei, es zu testen.

@ Falk Brunner, die Timer sind alle in Verwendung und werden unbedingt 
gebraucht. Dieser AVR hat ja leider nur 2. Ein Timer dient als 
„Taktgeber“ für einen exakten 1s. Takt, der Andere zum Abtasten eines 
Präzisionsgebers.
Wenn ich nun die Pause einfüge, ändert sich leider nichts. Du meintest 
das doch so, oder:

>//****7-Segment-Multiplex**************
>    for (i=1;i<=3;i++)
>    {
>      Out3 = j[i];  //Zahl ausgeben
>      _delay_us(100);  //nach 100us weiterschalten
>      Out2 = k[i];  //nächstes Segment ansteuern
       _delay_us(1.2);  //nach 100us weiterschalten
>    }
>  }
>}
>//*************************************

Autor: Matthias Lipinsky (lippy)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Takt, der Andere zum Abtasten eines Präzisionsgebers.

Das ist doch ideal. Wie schnell läuft der?
Pack die Mux-Ausgabe da mit rein.
delay ist immer Mist.


>5ms setze,..flackert
Natürlich, dann sinkt die Effektive Frequenz auf (Größenordnung) von 
50Hz.

Autor: crazy horse (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Timer kann man mehrfach verwenden.
Stell ihn z.B. so ein, dass er alle 1ms einen Interrupt erzeugt.
Davon leitest du beliebige andere Zeiteinheiten ab.

Autor: Tom (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Der Timer zur Abfrage läuft gerade mit 3,9 KHz (256µs). In dieser ISR 
steht aber schon allerhand drinn. Wird dann irgendwie unübersichtlich. 
Es muss doch aber auch ohne Einsatz eines Timers gehen.

Autor: Chris D. (m8nix)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du musst, bevor du die nächste Ziffer auf dem nächsten Segment ausgibst, 
die Matrix-Transistoren alle abschalten, dann die neue Ziffer auf den 
Port legen und erst dann den entsprechenden Matrixtransistor wieder 
ansteuern. Ansonsten "verschleifst" du die Ziffer die du am folgenden 
Segment ausgeben willst auf das momentan angesteuerte Segment.

Gruss Chris

Autor: Christian L. (lorio)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also das Problem hatte ich auch mal...nach einigem Grübeln bin ich dann 
auf das Problem gekommen:

Mein Vorgehen (so wie auch deins) war:
... -> Zahl ausgeben -> warten -> nächstes Segment ansteuern -> ....

Das Problem hierbei ist, dass während du schon zum nächsten Segment 
schaltest noch die "alten" Daten anliegen.

Das erklärt auch, dass das Problem bei niedrig werdender 
Multiplexfrequenz kleiner wird, denn diese "Übergangszeit" wird dann im 
Vergleich zur "Verweilzeit" immer unbedeutender.

Prinzipiell gibt es hierfür 2 Lösungsansätze:

... -> Zahl ausgeben -> nächstes Segment einschalten -> warten -> 
Segment ausschalten (über Transistor) -> ...

oder:

... -> Zahl ausgeben -> warten -> 0b00000000 ausgeben (Segment aus) -> 
nächstes Segment ansteuern -> ...

----------------------------------------------

Beide Lösung machen davon Gebrauch, dass die Komplette Anzeige für eine 
kleine Zeit ausgeschaltet sind.
Prblem mit sich überlappenden Zuständen (alte Daten, neues Segment) bzw. 
Schaltzeiten der Transistoren sollten damit behoben werden.

Gruß
Christian

PS.: Siehe Chris D. über mir, der ein Bisschen schneller war ;-)

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ Tom (Gast)

>@ Falk Brunner, die Timer sind alle in Verwendung und werden unbedingt
>gebraucht. Dieser AVR hat ja leider nur 2.

Ja und? Das reicht dicke.

> Ein Timer dient als
>„Taktgeber“ für einen exakten 1s.

Dort kann man PROBLEMLOS eine MUX-Funktion unterbringen. Siehe [[AVR - 
Die genaue Sekunde / RTC]. Das Ganze könnte PROBLEMLOS mit einem 
einzigen Timer laufen. Das wäre sogar besser, weil deterministischer.

> Takt, der Andere zum Abtasten eines Präzisionsgebers.

Du meinst Drehgeber? Auch kein Problem. Dein Delays verballern 
sinnlos CPU-Power.

>Wenn ich nun die Pause einfüge, ändert sich leider nichts. Du meintest
>das doch so, oder:

Ja, wobei ich eher 1 bis 2 Mikrosekunden meinte, nicht 1 KOMMA 2 ;-)
Ist aber egal. Probier mal ein wenig mehr, so bis 10us.

MFG
Falk

Autor: Klaus R. (klaus2)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
...ich hatte (die Woche) auch so meine Probleme mit genau der selben MUX 
Ansteuerung und ähnlichen Fehlern - bin dann über die "Zählschleife" 
letztendlich auch bei ISR gelandet, alles andere ist Mist. Also lern 
draus, ohne ISR sind die Displays zu dunkel bzw werden nicht optimal 
angesteruert. Die beste Ansteuerung ist, wenn NUR die ISR zu definierten 
Zeitpunkten die Anzeige weiterschaltet, quasi ohne "Pause" oder 
"Auszeiten"...

Gruß, Klaus.

Autor: Tom (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sooo,

es Läuft! Einwandfrei. Immer wieder äußerst hilfreich dieses Forum! 
Vielen dank euch Allen! Also, hier meine Lösung:

for (i=1;i<=3;i++)
{
  Out3 = j[i];  //Zahl ausgeben
  _delay_us(100);  //nach 5ms weiterschalten

  Out3 &= ~(SegA | SegB | SegC | SegD | SegE | SegF | SegG);
  _delay_us(100);  //nach 5ms weiterschalten

  Out2 = k[i];  //nächstes Segment ansteuern
}

Die 2 Zeilen zwischen den Lehrzeilen haben also gefehlt. So läuft es 
erstmal. Ich werd in den kommenden Tagen das ganze Prog noch verfeinern 
und mich euren Vorschlägen annehmen, auch bzgl. des Timers.

Kurze Frage, warum "verballert es CPU-Takt"? Ich mein, das Programm 
läuft doch so einwandfrei. Wie wirkt sich dies nachteilig aus? Kann man 
die CPU-Auslastung denn irgendwie berechnen? Sind diese delay-Fkt. 
wirklich so unvorteilhaft? Warum?

Grüße Tom

Autor: Matthias Lipinsky (lippy)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Sind diese delay-Fkt. wirklich so unvorteilhaft? Warum?

Warum wohl? Was wird denn während dieser Zeit gemacht??
Richtig. Der µC wird (sinnlos) damit beschäftigt, eine Variable 
herunterzuzählen...

Man könnte während dieser Zeit auch was sinnvolles machen...

Autor: crazy horse (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Es gibt eine einzige Anwendung, wo man das machen könnte: wenn die 
Displaysteuerung die einzige Funktion der main ist (d.h. der Rest 
irgendwie in Interrupt-Routinen abgearbeitet wird). Dann ist es im 
Prinzip egal, ob du deine Prozessorzeit direkt mit Warteschleifen 
vertüdelst oder wartest, bis ein Timer dir sagt, die Zeit ist vorbei.
Besser ist es dennoch, einen Timer zu benutzen. Vorteile vor allem bei 
späteren Programmerweiterungen - dann kannst du die gesparte Zeit sicher 
sinnvoller verwenden.
Wie gesagt - die Displaysteuerung benutzt nur wenige Takte in einer ISR.

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Falk Brunner wrote:

> Ausserdem muss zwischen den Umschaltungen ei Pause von 1.2us her,
> solange brauchen deine Tranistoren zum umschalten. Das kann man
> beschleunigen, indem man ca. 22ßpF parallel zu den Basiswiderständen
> lötet.


Oder man nimmt PNPs in Kollektorschaltung, dann braucht man das Delay 
beim Umschalten nicht.
Den Basiswiderstand spart man auch ein.
Und bei 5V hat man noch genügend Spannung für die LEDs.


Peter

Autor: Willi Warlord (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Diese Übersprechen ist normal bei 7-Segmentanzeigen. Die wahrgenommene 
Helligkeit ist eine log Funktion. Durch die minimale Zeitverzögerung 
beim
Abschalten der Transistoren werden Segmente der Anzeige kurzeitig 
angesprochen und man hat deshalb diesen Effekt. Die einzige Abhilfe 
dagegen ist das Ausschalten aller Segmente währen des Umschaltens auf 
die nächste Anzeige. Dieses Ausschalten sollte ca 50us lang sein und in 
die entstprechende Statemaschine berücksicht werden.
Das Umschalten sollte in dieser Reihenfolge passieren:

Ausschalten alles Segmente.
25uS Warten.
Andere Anzeige auswählen.
25us Warten
Segmente Einschalten.

Willi Warlord

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ Willi Warlord (Gast)

>Diese Übersprechen ist normal bei 7-Segmentanzeigen. Die wahrgenommene
>Helligkeit ist eine log Funktion.

Ja, siehe LED-Fading.

>>die nächste Anzeige. Dieses Ausschalten sollte ca 50us lang sein und in

Naja, alles relativ. Der UDN2981 braucht so lange.
Die Diskreten Transistoren wie hier im Beispiel so 1..2us.
PNPs in Kollektorschaltung 100ns, eher weniger.

Die Logik besser so sortieren.

Ausschalten aller Segmente
Neue Ziffer dekodieren
2..50us warten
Neue Ziffer ausgeben
Neues Segmant aktivieren

hat den Vorteil, dass die "aufwändige" Zifferndekodierung der nächsten 
Stelle gleichzeitig als Wartezeit genutzt werden kann.

MFG
Falk

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Falk Brunner wrote:

> PNPs in Kollektorschaltung 100ns, eher weniger.

Ja stimmt: eher weniger.

Es reicht dann völlig aus:

- alle Digits aus
- neues Segmentmuster setzen
- nächstes Digit ein

ganz ohne jede zusätzliche Wartezeit (AVR@16MHz).


> hat den Vorteil, dass die "aufwändige" Zifferndekodierung der nächsten
> Stelle gleichzeitig als Wartezeit genutzt werden kann.

Mach ich dann doch lieber in der Mainloop einmalig bei der Ausgabe einer 
neuen Zahl. Spart nochmals einige Promille an CPU-Last für andere Tasks. 
Auch hab ich die Interrupts gerne so kurz wie möglich.


Peter

Autor: Tom (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mal eine Frage, warum hat man diesen Effekt nicht bei pnp's in 
Kollektorschaltung? Das müsste doch völlig egal sein, ob pnp oder npn, 
zeitmäßig gesehen. Warum spart man sich da den Basiswiderstand?

Es ist in der Tat schon so, dass in der Main außer der Initialisierung 
nichts stattfindet. Okay, es wird ein Unterprogramm aufgerufen, was eben 
die Ansteuerung der 7-Seg. Anzeige übernimmt, aber der ganze Rest 
befindet sich in den ISR's.

Autor: crazy horse (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
weil in dieser Schaltung die Transisoren nicht in die Sättigung 
kommen/nicht übersteuert werden. Deshalb kann der Transistor schneller 
sperren (überschüssige Ladungen müssen nicht erst abfliessen)

Autor: HildeK (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>warum hat man diesen Effekt nicht bei pnp's in
>Kollektorschaltung?
Bei der Kollektorschaltung ist der Transistor nie in der Sättigung. PNP 
oder NPN ist da gleich, hier nur deshalb, weil es ein deinem Fall dann 
ein PNP sein müsste.

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Tom wrote:

> Es ist in der Tat schon so, dass in der Main außer der Initialisierung
> nichts stattfindet. Okay, es wird ein Unterprogramm aufgerufen, was eben
> die Ansteuerung der 7-Seg. Anzeige übernimmt, aber der ganze Rest
> befindet sich in den ISR's.

Mit diesem Konzept wirst Du nicht froh werden.

Das heißt ja, wenn alles in den Interrupts gemacht werden muß, dauern 
die auch schön lange und erhöhen das Delay im Main.
Damit wird Deine Anzeige immer flackern, sobald ein Interrupt ausgelöst 
wird.
Außerdem können sich so lange Interrupts leicht gegenseitig blockieren 
(Uhr geht nach, UART verliert Daten usw.).


Andersrum, wenn der Timer das Multiplexen macht, stört es überhaupt 
nicht, wenn im Main mal 100ms lang gerechnet werden muß.
Daß ne neue Zahl erst nach 100ms angezeigt wird, merkt kein Mensch.


Peter

Autor: Chris D. (m8nix)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Eine grundsätzliche Sache noch....

Man legt Multiplexer üblicherweise nie so aus das bei einem 
Prozessorreset alle Segmente sofort angesteuert werden. Reset bedeutet 
dass alle Ports als Eingangsports geschaltet werden. Nach Außen hin 
stellt sich ein Reset so dar, das die Potleitungen, „High-Level“ 
annehmen und in deinem Fall alle Segmente mit "888" angesteuert werden. 
Das mag bei drei Segmenten und den hier verbauten Vorwiderständen noch 
kein Problem darstellen. Aber beim Multiplexen von üppigeren Matrizen 
werden weitaus kleinere Vorwiderstände eingesetzt damit die 
Lichtausbeute der einzelnen Segmente unserem Auge eine schöne, helle und 
homogene Anzeige vorgaukeln kann. In der Zeit bis die Portleitungen dann 
initialisiert werden, könnten sich mit deiner Hardware bereits einige 
LED’s wegen Überbelastung in die ewigen Segmentgründe verabschiedet 
haben...

Und wer hier denkt das Watchdog- oder Brown-out-Detection dem 
Segmentsterben Einhalt gebieten können, der irrt gewaltig. Genau das 
Gegenteil ist der Fall, denn beide Detektoren belaufen sich auf einen 
Prozessorreset hinaus – und der kann durchaus zyklisch sein.

Darum sollte man eine Multiplexschaltung immer so auslegen das Segment- 
und Segmentmatrix immer unterschiedliche Potentiale zur Ansteuerung 
benötigen. (Also einen der beiden Signalbusse invertieren ;-)

Gruss Chris

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Chris D. wrote:
> Man legt Multiplexer üblicherweise nie so aus das bei einem
> Prozessorreset alle Segmente sofort angesteuert werden.

Ein ganz kurzer Blick auf die Schaltung verrät, hatter nicht.


> Reset bedeutet
> dass alle Ports als Eingangsports geschaltet werden. Nach Außen hin
> stellt sich ein Reset so dar, das die Potleitungen, „High-Level“
> annehmen und in deinem Fall alle Segmente mit "888" angesteuert werden.

Das ist 2-mal Quatsch mit Soße:
1. Eingänge floaten beim AVR.
2. LEDs und Bipolartransistoren brauchen echten Strom, sonst sind sie 
aus.

High könntest Du nur dann sehen, wenn Du noch echte TTL-ICs dazwischen 
schalten würdest.


Peter

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Peter Dannegger (peda)

>>Tom wrote:

>> die Ansteuerung der 7-Seg. Anzeige übernimmt, aber der ganze Rest
>> befindet sich in den ISR's.

>Mit diesem Konzept wirst Du nicht froh werden.

Genau, deshalb ist die Lektüre des Artikels Interrupt 
empfehlenswert.

@ Chris D. (m8nix)

>Man legt Multiplexer üblicherweise nie so aus das bei einem
>Prozessorreset alle Segmente sofort angesteuert werden.

Richtig, werden sie aber hier nicht.

> Reset bedeutet
>dass alle Ports als Eingangsports geschaltet werden. Nach Außen hin
>stellt sich ein Reset so dar, das die Potleitungen, „High-Level“
>annehmen

Nöö, das ist bestenfalls bei den 8051ern so. Und selbst dort sind es nur 
schwache Pull-Ups.

>und in deinem Fall alle Segmente mit "888" angesteuert werden.

Aber nur, wenn die gemeinsamen Kathoden durchsteuern, was sie nicht tun.

>homogene Anzeige vorgaukeln kann. In der Zeit bis die Portleitungen dann
>initialisiert werden,

. . . halten richtig platzierte Pull-Ups oder Pull-Downs die 
Spaltentreiber im AUS-Zustand.

>Darum sollte man eine Multiplexschaltung immer so auslegen das Segment-
>und Segmentmatrix immer unterschiedliche Potentiale zur Ansteuerung
>benötigen.

Nöö, vollkommen unnötig. Siehe LED-Matrix.

MfG
Falk

Autor: Jens G. (jensig)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ Chris D.
nach dem Reset sind die Ports üblicherweise als Eingang geschaltet - 
keine Gefahr.
Selbst wenn die internen Pullups aktiv sein sollten (sofern für die 
betreffenden Ports welche existieren sollten) - keine Gefahr. Denn die 
liefern ja nur einen sehr geringen Strom in die Transistorbasen. Und 
selbst wenn die Transistoren damit einige mA als Ic liefern könnten, 
können Sie es nicht, weil die Segmentleitungen ja auch nur über die 
Pullups gezogen werden, was nur paar µA Segmentstrom verursacht - da 
brauchste einen Sekundärelektronenvervielfacher, um eine 888 zu sehen.
Zusätzliche PullUps/Downs sind also eigentlich komplett überflüssig an 
dieser Stelle - die würden weder eine nicht vorhandene Gefahr 
eliminieren, noch der Anzeige irgendeine besondere "Ausstrahlung" 
verleihen.

Noch was zur Matrixansteuerung in der main(). Du versuchst ja, den Takt 
mit dem Delay vorzugeben. Wie schon jeder sagte, ist das meistens 
schlecht, nicht weil CPU-Power sinnlos verbraten wird (ist wohl eher das 
kleiner Übel), aber wenn der µC nebenbei noch andere Dinge in der main() 
macht, die noch dazu unterschiedlich in jedem Schleifendurchgang 
brauchen, hast Du eben auch das Flackern in der Anzeige, oder die Digits 
leuchten unterschiedlich hell (das ist wohl das, was Falk mit 
Deterministic meinte).
typisches Beispiel aus der Praxis: einfache oder älter Fernsehgeräte 
u.a. - wenn Du da auf irgendwelche Tasten drückst, geben die oft eine 
hübsche Lichtorgel her (bei manchen siehste das Flackern sogar rhytmisch 
auch ohne Tastendruck - offensichtlich beschäftigt sich der µC gerade 
dann mit dem I2C)

Auch wenn Du später was zur main() hinzufügst, änderst Du damit auch das 
gesamte Timing.

Autor: Ingenieur (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich würde langsamer schalten 1kHz reicht eigentlich aus. Das sind immer 
ncoh 300 Hz je Anzeige. Ausserdem sollten die Transistroen etwas Totzeit 
bekommen, also nicht mit den Daten umschalten, sondern VOR dem 
Datenumschalten abschalten und erst NACH dem Datenumschalten wieder 
anschalten.

Früher (als wir nur mit 10-20 Hz wechseln konnten) haben wir das so 
gemacht, daß wir über Dioden rausgegangen sind, an denen Kondensatoren 
hingen. Das ergabe ein schönes Nachleuchten und eine stabile Anzeige 
ganz ohne "Hetze"!

Autor: Tom (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
So, dann muss ich mich auch mal wieder zu Wort melden. Hat sich ja in 
der Zwischenzeit einiges getan. Und zum Weiterprogrammiern bin ich auch 
noch nicht gekommen. Werd ich mir für das Wochenende aufheben.

Also, was gäbe es denn noch an meiner Schaltung grob zu änder? Ihr 
schreibt alle was von Kollektorschaltung mit pnp. Ich mein, ist das 
wirklich erforderlich? Das Blinken ist ja nun erstmal verschwunden durch 
den (provisorischen) Einbau dieser 2 Zeilen, die ich gestern hier 
genannt hatte. Aber okay, noch hab ich Spielraum in der Gestaltung der 
Schaltung.

Den Quellcode werd ich dann auch noch verändern und evtl. umschreiben. 
Aber wie gesagt, momentan mit dieser kleinen Änderung ist alles perfekt. 
Kein flackern, alle Anzeigen gleich hell und keine Verwischungen.

Noch eine kleine Frage nebenbei: Insgesammt sind dort 2 Taster 
angeschlossen. Durch die internen pullups kann ich mir doch die externen 
sparen, oder?

Zweite Frage, wie schon richtig erkannt, ist dort ein Drehimpulsgeber 
angeschlossen. Laut dem angehangenen Schaltbild werden dort ja 3 pullups 
benötigt. Kann ich diese auch weglassen?

Das ich die pullups softwareseitig erst aktivieren muss, versteht sich 
von selbst.

Vielen Dank!

Autor: Tom (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Ingenieur, gar nicht mal so schlecht die Idee mit den Dioden und 
Kondensatoren. Die Muplexzeit hab ich auch noch ein wenig 
heruntergestellt.

Ach übrigens, der AVR läuft mit 8 Mhz, zur Info.

Autor: Chris D. (m8nix)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Man sollte eben so spät Nachts nichts mehr Posten .... :-D
Aber ich kann schon wieder nicht einschlafen....

Find ich aber schon bedenklich das die ATmega's beim Reset in Tri-State 
gehen. Ich ging davon aus das die Ports als Eingang und mit Pullups 
resetet werden.

Freut mich das es jetzt geht @ Tom (Gast). Ich habe allerdings bedenken 
das du weisst weshalb ?!

Autor: Michael H* (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Chris D. wrote:
> Find ich aber schon bedenklich das die ATmega's beim Reset in Tri-State
> gehen. Ich ging davon aus das die Ports als Eingang und mit Pullups
> resetet werden.
Die coolen 's bei den Plural's scheinen ja manchen Leuten's ganz schön 
zu gefallen. Leider gibts aber nicht mal bei den Angelsachen's ein 's 
bei den Plural's.

> Freut mich das es jetzt geht @ Tom (Gast). Ich habe allerdings bedenken
> das du weisst weshalb ?!
Lass uns an deinen Weisheiten's doch weiterhin teilhaben  (plenk)  !


außerdem stimmts einfach nicht, dass die atmel pins in einen richtigen 
tristate gehen. schau einfach im datenblatt ins DDRX-register und vor 
allem an die Reset's-Werte's. Du wirst merken, es sind Eingänge's.
Wann genau die Richtungen's für die jeweilige Programmierschnittstelle 
gesetzt werden, findet sich irgendwo, wo es ums Beschreiben vom Flash 
geht.

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.