7-Segment multiplexen - was bedeutet DB-Angabe mit Duty-Cycle?

Gast #2758824
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?
Gast #2758858
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 ;)
Gast #2758905
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!
#2758913
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.
Gast #2759191
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?
#2759211
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
}
Gast #2759372
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.
#2759381
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.
#2759389
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.

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