Forum: Mikrocontroller und Digitale Elektronik 7-Segment multiplexen - was bedeutet DB-Angabe mit Duty-Cycle?


von Hans (Gast)


Lesenswert?

Hallo Leute!

Ich möchte 7 Stk. 7-Segment-Anzeigen multiplexen (SA52-11EWA von 
Kingbright). Diese haben einen normalen Vorwärtsstrom von 20mA. Mit 
diesem Wert werden die ja relativ schwach leuchten...also erhöht man ja 
den Strom beim Multiplexen.

Im DB steht jetzt max. 160mA 1/10 Duty-Cycle, 0,1ms Pulsweite. Was genau 
bedeutet das? Und wieviel Strom sollte ich verwenden pro Segment bei 7 
Stück? Einfach den siebenfachen wohl nicht, oder?

von dabidas (Gast)


Lesenswert?

Hallo Hans

Ein 7-Segment sind ja eigenlich sieben LED's. Wie du schon gesagt hast, 
werden diese kurzzeitig mit einem grösseren Strom beliefert um eine 
normale Helligkeit hinzubringen. Da nimmst du einfach diese 160mA vom 
Datenblatt.
Diese 0.1ms sind ebenfalls zum Schutz der LED's. Wenn diese Zeit länger 
wird, geht sie evtl. kaputt.
Wenn du nun mehr als 10% der gesamten Zeit eine LED leuchten lässt, 
musst du den Strom ein wenig reduzieren, aber grundsätzlich halten LED’s 
viel mehr aus, als im Datenblatt angegeben.

*alle Angaben ohne Gewähr

Lg dabidas ;)

von Hans (Gast)


Lesenswert?

dabidas schrieb:
> Wenn du nun mehr als 10% der gesamten Zeit eine LED leuchten lässt

Ja, ok, aber von welcher gesamten Zeit? 10% von 100us sind ja was 
anderes als 10% von einer Sekunde. Oder darf die längste Zeit halt nicht 
die 100us überschreiten?

von Schnell antworten (Gast)


Lesenswert?

Du darfst 160mA maximal für 0,1ms pro LED anlegen. Danach muss für 0,9ms 
ruhe sein und dann wieder von vorne. Also 1/10 von 1ms Wiederholrate.

von dabidas (Gast)


Lesenswert?

genau, diese 10% dürfen nicht länger als 0.1ms sein, wenn du das ganze 
schneller machst, bist du auf der sicheren Seite

von Route_66 H. (route_66)


Lesenswert?

Hallo!
Weil Du aber bei einer siebenstelligen Anzeige einen Dutycycle von 1/7 
oder bei Multiplex der Segmente (plus Dp) 1/8 hast, würde ich den 
Spitzenstrom etwas reduzieren (120 mA vielleicht).

von Hans (Gast)


Lesenswert?

Ahhh, alles klar! Das mit der 9/10 Ruhezeit klingelt jetzt. Vielen Dank!

von Hans (Gast)


Lesenswert?

Ist ja trotzdem ganz schön heftig...dann brauche ich ja schon 700mA 
allein für die Anzeige (mal 100mA angenommen). Kann ich ja noch die 
Segmente in den einzelnen Anzeigen zusätzlich multiplexen...aber dann 
müsste wohl noch ein größerer Strom her.

Alles klar, danke!

von Karl H. (kbuchegg)


Lesenswert?

Hans schrieb:
> Ist ja trotzdem ganz schön heftig...dann brauche ich ja schon 700mA
> allein für die Anzeige (mal 100mA angenommen).

Tja.
Mit Multiplexen lässt sich kein Strom sparen :-)

Allerdings: probier erst mal aus, ob du die 20mA überhaupt brauchst. Die 
meisten Anzeigen sind mit 15mA oder sogar noch weniger immer noch gut 
ablesbar. Kommt halt immer auf die Umgebungsbedingungen an.

von dabidas (Gast)


Lesenswert?

ja 700mA ist ja nicht so viel, mit deinen ca. 2V kommst du nur auf 1.4W

von Hans (Gast)


Lesenswert?

So, also da jetzt die Hardware geklärt ist...mal noch ein paar Fragen 
zur besten Umsetzung in C:

Ich schreibe mir die üblichen Funktionen zum Zerlegen von Zahlen in ihre 
einzelnen Ziffern usw.

Mal als Beispiel mit einer 4-stelligen Anzeige.Wenn ich hier jetzt einen 
Wert ausgeben will, wo mache ich welche Schritte am besten?

Mittels Timer schalte ich immer eine Stelle weiter - schicke ich in der 
ISR auch direkt die neuen Daten los, oder setze ich nur ein Flag, 
welches dann in der main die Daten schickt? Je nachdem, wie viel in der 
main berechnet wird, kann es ja evtl. zu ungleichmäßigen Zeiten zwischen 
den Anzeigen kommen.

Ich hatte z.B. schonmal den Fall, da hatte ich in der ISR auch nur die 
Anzeige markiert, die als nächstes ihre Daten bekommen sollte...je 
nachdem, wie groß die anzuzeigende Zahl war, dauerte die Zerlegung (da 
passierte natürlich noch mehr) unterschiedlich lang, was man an einem 
Flimmern erkennen konnte. Umso kleiner die Zahl wurde, desto besser 
wurde es dann wieder - so war auf jeden Fall nicht richtig gelöst.

Also wäre ich erfreut über Vorschläge, wie man es am Besten löst. Wenn 
ich in der ISR direkt die Daten losschicke, dann löst der Interrupt 
evtl. aus, wenn gerade die neuen Daten aufbereitet werden.

Wie macht man es am besten?

von Karl H. (kbuchegg)


Lesenswert?

Hans schrieb:

> Mittels Timer schalte ich immer eine Stelle weiter - schicke ich in der
> ISR auch direkt die neuen Daten los, oder setze ich nur ein Flag,
> welches dann in der main die Daten schickt?


weder noch.
Für jede 7-Seg-Anzeige hast du eine Variable (am besten als Array 
zusammenfassen), in dem schon fix fertig das Muster vorliegt, welches 
beim jeweiligen ISR Aufruf an die jeweilige Anzeige gehen muss.

Das wars dann schon.
DIe ISR macht nichts anderes, als reihum immer wieder einfach nur den 
Inhalt dieser Variablen auszugeben.

Wenn dein Programm einen bestimmten Zahlenwert ausgeben will, dann 
beschreibt sie diese Variablen mit den notwendigen Musterbytes.

> Je nachdem, wie viel in der
> main berechnet wird, kann es ja evtl. zu ungleichmäßigen Zeiten zwischen
> den Anzeigen kommen.

Du hast das Prinzip nicht verstanden.
Der Multiplex läuft STÄNDIG im Hintergrund und beschickt reihum die 
Anzeigen.

Dein Programm muss sich nicht mehr um 7-Seg kümmern. Wenn es etwas 
auszugeben hat, dann sind diese Hilfs-Muster Variablen sein 
Ansprechparter. Was immer es anzuzeigen gilt, wird in diese Variablen 
geschrieben. Für dein Programm SIND diese Mustervariablen die 
Ausgabe-Anzeigefläche! Es beschreibt sie ganz einfach je nachdem, wann 
Werte anfallen. Fertig.

1
#define MAX_STELLEN  7
2
volatile uint8_t Pattern[MAX_STELLEN];
3
4
ISR( ... )
5
{
6
  static uint8_t actStelle = 0;
7
8
  ... 7-Seg mit der Nummer actStelle abschalten
9
10
  actStelle++;
11
  if( actStelle == MAX_STELLEN)
12
    actStelle = 0;
13
14
  ... den Inhalt von Pattern[actStelle] auf die Segmentleitungen legen
15
16
  ... 7_seg mit der NUmmer actStelle aktivieren
17
}
18
19
// PatternCode[0] ist das Byte welches die Segmente codiert, die zur Anzeige
20
// der Ziffer 0 einzuschalten sind.
21
// 10 Ziffern -> 10 Einträge im Array
22
// und praktischerweise so angeordnet, dass man mit der Ziffer als Index
23
// zugreifen kann um das Muster zu erhalten, so dass die jeweils richtigen
24
// LED aufleuchten.
25
static uint8_t PatternCode[10] = { .., ... };
26
27
void showNumber( uint16_t num )
28
{
29
  uint8_t i;
30
31
  for( i = 0; i < MAX_STELLEN; ++i )
32
  {
33
    Pattern[MAX_STELLEN - 1 - i] = PatternCode[ num % 10 ];
34
    num /= 10;
35
  }
36
}

von Hans (Gast)


Lesenswert?

Hallo Karl-Heinz,

vielen Dank für den Beitrag. Ich merke gerade, ich habe eine wesentliche 
Information nicht hingeschrieben...sowohl die einzelnen Stellen, wie 
auch die Segmente einer jeden Stelle werden über zwei Schieberegister 
angesteuert. Ich schicke also nur 16Bit per SPI auf zwei 595er. Daher 
die Frage, ob ich die Daten in der ISR verschicken soll. SORRY.

Karl Heinz Buchegger schrieb:
> Für jede 7-Seg-Anzeige hast du eine Variable (am besten als Array
> zusammenfassen), in dem schon fix fertig das Muster vorliegt, welches
> beim jeweiligen ISR Aufruf an die jeweilige Anzeige gehen muss.

Genauso habe ich es auch.

Karl Heinz Buchegger schrieb:
> DIe ISR macht nichts anderes, als reihum immer wieder einfach nur den
> Inhalt dieser Variablen auszugeben.

Ja, ist klar, das verstehe ich, nur wie (keider jetzt erst erwähnt) 
schicke ich die Daten per SPI raus. Daher die Frage, ob Flag setzen, 
dass neue Stelle aktuell ist und Daten gesendet werden sollen.

Meine Idee:

Timer-ISR:

Neue Daten für nächste Stelle per SPI senden.


SPI-Senden-Fertig-ISR:

Latch für 595er togglen, damit zugleich neue Stelle und Zahlenmuster 
angezeigt wird.

Karl Heinz Buchegger schrieb:
> static uint8_t PatternCode[10] = { .., ... };

Das habe ich mir auch so zusammengebaut, das ist ganz praktisch.

Nun noch zu den veränderlichen Daten. Es kann ja garnicht vorkommen, 
dass ein Array-Element gerade geändert wird, wärend die ISR zuschlägt, 
da ich ja erstmal in einer zusätzlichen Variable das neue Byte erstelle 
und dieses dann komplett in das Array-Element kopiere - das passiert ja 
in einem Befehl, welcher nicht unterbrochen werden kann, richtig? (Jetzt 
mal angenommen, ich würde ein Byte erstellen und es nicht fertig aus 
einem #define herholen, was praktisch natürlich Unsinn ist).

Obwohl...:


Gruß, Hans

Karl Heinz Buchegger schrieb:
> void showNumber( uint16_t num )
> {
>   uint8_t i;
>
>   for( i = 0; i < MAX_STELLEN; ++i )
>   {
>     Pattern[MAX_STELLEN - 1 - i] = PatternCode[ num % 10 ];
>     num /= 10;
>   }
> }

Hier könnte es ja theoretisch schon vorkommen, dass gerade erst die 
halbe Zahl fertig ist, die ISR sich aber noch eine alte holt. Nur das 
wird man wohl kaum mitbekommen.

von Hans (Gast)


Lesenswert?

Das "Gruß, Hans" sollte natürlich nach unten ;-)

von Karl H. (kbuchegg)


Lesenswert?

Hans schrieb:
> Hallo Karl-Heinz,
>
> vielen Dank für den Beitrag. Ich merke gerade, ich habe eine wesentliche
> Information nicht hingeschrieben...sowohl die einzelnen Stellen, wie
> auch die Segmente einer jeden Stelle werden über zwei Schieberegister
> angesteuert. Ich schicke also nur 16Bit per SPI auf zwei 595er. Daher
> die Frage, ob ich die Daten in der ISR verschicken soll. SORRY.

Sicher sollst du.

Machs nicht kompliziert.
Der Multiplex-Machanismus soll ja dauernd laufen.
Das bischen per SPI rausschicken kostet dich doch nichts. In der Zeit, 
in der die Hardware das erste Byte rausjodelt, kannst du ja schon das 
nächste Byte bereitstellen.

ISR kurz halten bedeutet nicht, dass man gar nichts in einer ISR machen 
darf. Das bischen Zeit für 2 Bytes per SPI hast du allemal. Das kostet 
dir fast nichts.

von Karl H. (kbuchegg)


Lesenswert?

> Es kann ja garnicht vorkommen, dass ein Array-Element gerade
> geändert wird, wärend die ISR zuschlägt, da ich ja erstmal
> in einer zusätzlichen Variable das neue Byte erstelle
> und dieses dann komplett in das Array-Element kopiere

Und selbst wenn, wir reden von einer 7_Seg Anzeige. Spätestens beim 
nächsten Multiplex-Durchgang ist dann die Anzeige komplett richtig. Das 
ist ein paar Hunderstel Sekunden später. Das sieht unter Garantie kein 
Mensch, dass an der Anzeige ein paar Hunderstel lang eine falsche Ziffer 
angezeigt wurde. Oder kannst du im Winter bei den 
Ski-Fernsehübertragungen, wenn die Hunderstel an der Uhr durchlaufen 
sagen, ob da wirklich alle Ziffern von 0 bis 9 durchgelaufen sind? Erst 
dann wenn die Anzeige eine gewisse Zeit sich nicht mehr ändert, kannst 
du als Mensch den Wert ablesen und zuordnen.

von Hans (Gast)


Lesenswert?

Vielen Dank!

Ich werde das so erstmal umsetzen!

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.