Forum: Mikrocontroller und Digitale Elektronik Mega8: VQC10 LED-Matrix 5x7 Zeitmultiplex - Bestimmte Bits eines unsigned char auf Ports ausgeben


von Sven L. (svenl)


Lesenswert?

Hallo AVR-Freaks,

ich versuche mich gerade an einer Zeitmultiplexsteuerung für zwei 
VQC10-LED-Matrixdisplays (4 Stellen 5x7 Matrix).

Das Display verfügt über 7 Zeilenleitungen, 5 Datenleitungen und 4 
Select-Leitungen für das aktive Digit.

Die 7 Zeilen sind über einen BCD-zu-1-aus-8-Decoder (i8205) mit dem 
PORTB des ATMegas verbunden (PB0-PB2).

Die 4-Select-Leitungen (bei zwei Displays sind es 8) sind ebenfalls über 
einen i8205 mit dem PORTD (PD5-PD7) verbunden, die Datenleitungen für 
die Spalten sind an PORTD (PD0-PD4) angebunden.

Meine momente Lösung arbeitet mit zwei verschachtelten For-Schleifen für 
die Stelle und die Zeile. So ungefähr:
1
unsigned char zeile, stelle, daten;
2
3
for (stelle = 1; stelle < 5; stelle++)
4
{
5
  PORTD |= stelle<<5;
6
  for (zeile = 1; zeile < 8; zeile++)
7
  {
8
    // Setze aktive Zeile
9
    PORTB = zeile;
10
    // Gebe Datenbyte aus
11
    PORTD &= daten;
12
    // warte...
13
    _delay_us(250);
14
  }
15
}

Das Problem ist, dass über PORTD die Daten der aktiven Zeile und die 
Stelle BCD-codiert auf den Bits PD5-PD7 ausgegeben werden müssen. - Die 
Schreibzugriffe auf PORTD überlagern sich und löschen Bits im oben 
genannten Beispiel.

Kennt jemand eine elagante Lösung wie ich zum Beispiel nur die ersten 5 
Bits eines unsigned char auf einen Port ausgebe, die restlichen 3 
Ausgabebits aber unberührt bleiben? (Port ist vollständig als Ausgabe 
definiert)

Des weiteren bin ich noch sehr an Informationen zu den VQC10 
interessiert. Der eine oder andere hier hat ja schon etwas mit diesen 
Anzeigen gemacht. - Wie genau funktioniert die Steuerung des 
Auffangregisters? - Wird mit CP1-4 die Digitauswahl bewerkstelligt?

Ich bin von der Standardbeschaltung laut Datenblatt abgewichen. Den 
K155ID3 brauche ich nicht, da ich nur zwei Displays habe (reicht ein 
weiterer 8205) und den 8212 habe ich wegrationalisiert, da der ATMega 
den Bus problemlos treiben kann.

Ihr seht...viele Fragen! :)

Gruß!

Sven

von Toralf W. (willi)


Lesenswert?

Lang ist es her,
ich habe auch noch ein paar dieser Kraftwerke hier zu liegen. 
Ansteuerung wenn ich mich richtig erinnere: 1. Zeile an +UB, Daten für 
Matrix1 anlegen und mit Takt an CP1 übernehmen, dann Daten für Matrix2 
anlegen und mit Takt an CP2 übernehmen, dann Matrix3... Matrix4, jetzt 
2. Zeile an +UB und dann wieder nacheinander die Daten für Matrix1 bis 
4, dann 3.Zeile usw
Dabei bleiben die daten einer Zeile solange im Display stehen, wie die 
+UB an der Zeile anliegt oder bis zum nächsten CP Impuls. Multiplex muss 
als nur in 7 Schritten erfolgen, das geht mit dem mega8 auch ohne weiter 
treiber ic, einzig die Zeilen müssen über PNP oder ulns geschaltet 
werden.
[[http://www.jaero.sk/elektro/VQC10.PDF]]
Gruß Willi

von Sven L. (svenl)


Lesenswert?

Naja, die 8205 habe ich nur zum Leitungen sparen eingesetzt. - Das 
Datenblatt ist etwas verwirrend was das Auffangregister angeht. Sieht so 
aus, also ob die Daten bei steigender Taktflanke übernommen werden!?

Nagut...ich werde noch etwas damit rumprobieren.

Die Ansteuerung der Zeilen geschieht mit PNP-Transistoren. Ich wollte 
auch schon einen ULN nehmen, aber erst wenn die Helligkeit wirklich 
nicht zufriedenstellend ist. Jedoch mit BC327-25 kein Problem mit der 
Helligkeit! :)

Nun suche ich nur noch nach einer eleganten Möglichkeit das 
entsprechende Ausgabeport mit einer begrenzten Anzahl von Bits aus einem 
unsigned char zu setzen, ohne die restlichen Bits zurück zu setzen. - 
Leider gibt die Suchfunktion hierzu nicht allzu viel her.

Beispiel: PORTD hat irgendeinen gesetzten Zustand. Jetzt müssen die 
Daten für die nächste Zeile in den Bits PD0-PD4 geschrieben werden, 
PD5-7 müssen aber erhalten bleiben. Die Daten stehen in einem unsigned 
char, also 8 Bit breit. PD5-7 sind im Datenbyte immer 0.

PD0-4 könnte man folgendermaßen nullen und dann neu mit dem Datenbyte 
verodern:
1
PORTB &= 0xE0;
2
PORTB |= 0x15;

Geht es denn vielleicht auch eleganter? PD0-4 werden ja für einen Zyklus 
0.

Vielen Dank für die Infos!

Sven

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Sven L. schrieb:

> PD0-4 könnte man folgendermaßen nullen und dann neu mit dem Datenbyte
> verodern:
>
>
1
> PORTB &= 0xE0;
2
> PORTB |= 0x15;
3
>

Die aufgeoderten Bits liegen aber nich in der Maske 0xe0. Ein 
zwischenzeitliches Ändern von PORTB wemeidet man über ine lokale 
Variable:
1
uint8_t portb;
2
// Bits 5,6,7 löschen
3
portb = PORTB & ~(0x7 << 5);
4
// Bits einfügen ab Bit 5
5
portb |= (data & 0x7) << 5;
6
// Zurückschreiben
7
PORTB = portb;

> Geht es denn vielleicht auch eleganter? PD0-4 werden ja für einen Zyklus
> 0.

Eleganter nicht wirklich.

Je nachdem, ob die Änderung am Port atomar sein muss (also keine 
ungültigen Zwischenstände auftreten dürfen) oder asynchrone Zugriffe auf 
PORTB erfolgen (z.B. wenn in einer ISR PORTB.0 verändert wird) kann man 
unterschiedliche Ansätze wählen, die je nach Umfeld korrekt sind oder 
nicht.

Johann

von Sven L. (svenl)


Lesenswert?

Es wird darauf hinauslaufen, dass die Ansteuerung des Displays durch 
eine ISR ausgelöst wird durch Timer-Overflow.

Die Lösung mit der Zwischenvariable ist nicht wirklich "schöner", aber 
die Zustände an dem Port bleiben atomar und das ist wichtig. :)

Wie gesagt Bit 0-4 als Daten und Bit 5-7 als BCD-Zeilenansteuerung. Der 
eben veroderte Wert war ein Denkfehler. :)

Vielen Dank erst einmal!

Ich werde über den weiteren Fortgang mit der VQC10 berichten.

Viele Grüße!

Sven

von Michael U. (amiga)


Angehängte Dateien:

Lesenswert?

Hallo,

ja, lang ist es her... ;)

Vielleicht hilft es Dir etwas.
Die Zeilen hingen über pnp-Treiber am AVR, diente nur zum Test, welche 
Anzeigen noch lebten...

Gruß aus Berlin
Michael

von Sven L. (svenl)


Lesenswert?

Ich habe noch einmal ein wenig rumprobiert...

Leider ist die Anzeige ziemlich "verwaschen". Die nachfolgenden Zeilen 
beinhalten teilw. Informationen der letzten Zeile. Die Pixel leuchten 
dann auch nicht so hell.

Es könnte evtl. ein Problem mit den Signalen sein, aber das weiß ich im 
Moment noch nicht, da ich keinen Oszi hier habe. - Ich steuere zumindest 
erst alle Zeilen eines Digits der Reihe nach an und fülle die Spalten 
mit Bitmustern. Man könnte ja auch die Spalten ansteuern und die Reihen 
mit Bitmustern füllen, aber so erschien es für mich einfacher, da meine 
Zeilen über einen BCD-Decode angesteuert werden und somit Bitmuster 
nicht möglich sind.

Ich nehme an, dass ich beim Timing etwas falsch mache? - Ich wähle erst 
die entsprechende Zeile aus, danach wähle ich das Digit über die 
Taktleitung. Nachdem die Taktleitung gesetzt ist (über Enable-Eingang 
vom 8205 nachdem das Bitmuster vom AVR gesetzt wurde), setze ich mit 125 
µs Verzögerung die 5 Datenbits für die einzelnen Spalten. Wieder 125 µs 
später Taste schalte ich den Enable-Eingang vom 8205 wieder aus und alle 
Taktleitungen gehen auf High.

Irgendwelche Ideen?

Gruß!

Sven

von Thomas K. (muetze1)


Lesenswert?

Moin!

Ich denke die Datenleitungen sollten schon belegt sein, vor der 
Selektion der Zeile. Also die Datensignale anlegen, dann Zeile 
selektieren über die Taktleitung und dann die Taktleitung wieder 
zurücksetzen, dann neues Bitmuster für nächste Zeile und das ganze geht 
von vorne los.

Grüsse,
Thomas

von Karl H. (kbuchegg)


Lesenswert?

mach aus der Not eine Tugend. Du kennst doch den Inhalt des Highbytes 
von PORTD. Gibs einfach nochmal mit aus.

[C]
unsigned char zeile, stelle, daten, maske;

for (stelle = 1; stelle < 5; stelle++)
{
  maske |= stelle<<5;
  for (zeile = 1; zeile < 8; zeile++)
  {
    // Setze aktive Zeile
    PORTB = zeile;
    // Gebe Datenbyte aus
    PORTD = ( daten & 0x1F ) | maske;
    // warte...
    _delay_us(250);
  }
}

von Toralf W. (willi)


Lesenswert?

Michael U. schrieb:
> Hallo,
>
> ja, lang ist es her... ;)
>
> Vielleicht hilft es Dir etwas.
> Die Zeilen hingen über pnp-Treiber am AVR, diente nur zum Test, welche
> Anzeigen noch lebten...
>
> Gruß aus Berlin
> Michael

Hallo Michael,
auch mal im WF gewesen?
Gruß Willi

von Michael U. (amiga)


Lesenswert?

Hallo,

Toralf Wilhelm schrieb:
> auch mal im WF gewesen?

Nö, aber ein Bekannter hatte noch so ca. 20 VQC10 von denen einige aber 
defekte Zeilen haben.

Keine Ahnung, was ich mit den Dingern mal baue...

Gruß aus Berlin
Michael

von Willi (Gast)


Lesenswert?

zuerst einmal ein gutes Netzteil und dann eine gute Lüfterreglung

hätte ja sein können (kommst ja aus Berlin)

Gruß Willi

von Axel R. (Gast)


Lesenswert?


von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Sven L. schrieb:

> Des weiteren bin ich noch sehr an Informationen zu den VQC10
> interessiert.

Kleine Warnung am Rande: die Dinger sind dafür berüchtigt, dass man
sie ganz schnell zerschießen kann, wenn das Multiplexen aus Versehen
hängen bleibt.  Man sollte also am besten einen Controller dafür
dediziert verwenden (damit die Firmware überschaubar bleibt) und
vielleicht auch noch den Wachhund scharf schalten, damit eine
Verklemmung der Firmware abgefangen wird.  Bei letzterem muss man
aber wieder vorsichtig sein, dass der Schuss nicht nach hinten los
geht: wenn nach dem Watchdog-Reset immer wieder die gleiche Stelle
angesteuert wird, arbeitet dieser Zeitschlitz ja praktisch auch im
Dauerbetrieb. :-o

Während der Experimentierphase also vielleicht besser mit stark
reduziertem Strom arbeiten, schließlich wachsen diese Teile nicht
mehr nach.

(Ich weiß auch noch nicht, was ich mit den paar Teilen mal mache,
die ich davon noch in der Kiste liegen habe.  Eigentlich wollte ich
sie ja ,,stilecht'' mit einem Z8 ansteuern. :)

von Michael U. (amiga)


Lesenswert?

Hallo,

Jörg Wunsch schrieb:
> (Ich weiß auch noch nicht, was ich mit den paar Teilen mal mache,
> die ich davon noch in der Kiste liegen habe.  Eigentlich wollte ich
> sie ja ,,stilecht'' mit einem Z8 ansteuern. :)

naja, stilecht wäre dann ja eher ein U880D... ;-)

Gruß aus Berlin
Michael

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Michael U. schrieb:

>> (Ich weiß auch noch nicht, was ich mit den paar Teilen mal mache,
>> die ich davon noch in der Kiste liegen habe.  Eigentlich wollte ich
>> sie ja ,,stilecht'' mit einem Z8 ansteuern. :)
>
> naja, stilecht wäre dann ja eher ein U880D... ;-)

Nö, Z8 ist schon OK, hieß halt UB8820D.  Eine andere Version davon
hätte ich ohnehin nicht in der Kiste liegen (OK, vielleicht noch
einen UB8831).

von Sven L. (svenl)


Lesenswert?

Jörg Wunsch schrieb:

> Kleine Warnung am Rande: die Dinger sind dafür berüchtigt, dass man
> sie ganz schnell zerschießen kann, wenn das Multiplexen aus Versehen
> hängen bleibt.  Man sollte also am besten einen Controller dafür
> dediziert verwenden (damit die Firmware überschaubar bleibt) und
> vielleicht auch noch den Wachhund scharf schalten, damit eine
> Verklemmung der Firmware abgefangen wird.  Bei letzterem muss man
> aber wieder vorsichtig sein, dass der Schuss nicht nach hinten los
> geht: wenn nach dem Watchdog-Reset immer wieder die gleiche Stelle
> angesteuert wird, arbeitet dieser Zeitschlitz ja praktisch auch im
> Dauerbetrieb. :-o

Davon habe ich hier auch gelesen. - Im Moment schalte per BC327 als 
Zeilentreiber nach Ub. Da gibt es von Gleichspannung bis 250 µs keine 
Probleme mit der Helligkeit oder Defekten der Anzeige. Wenn der Takt 
noch schneller wird, dann wird es natürlich dunkler.

Jedoch habe ich immer noch kein vernünftiges Ergebnis. Vielleicht ist es 
auch einfach keine gute Idee den Latch-Eingang über einen 8205 laufen zu 
lassen. Der Baustein erwärmt sich schon ein wenig und der H-Pegel liegt 
bei knappen 3,7 V. Ohne angeschlossene Anzeigen entspricht der H-Pegel 
Ub. SIeht so aus, als ob die Latch-Eingänge einfach zu viel Strom 
brauchen?

So benötige ich halt problemlos 5 Leitungen weniger und gerade am Mega8 
ist man damit nicht so reichlich bedient. Schließlich soll ja noch ein 
DCF-Empfänger und 1-2 Tasten mit dran.

Hat jemand vielleicht einen Vergleichs-Quellcode in C? - Irgendwas mache 
ich verkehrt...

Gruß!

Sven

von Mike (Gast)


Lesenswert?

Du kannst die auf den Ports ausgegeben Daten auch wieder einlesen. In 
deinem Beispiel wären das PINB und PIND.

Am Decoder für die Select-Signale solltest du auch unbedingt ein 
Enable-Signal benutzen. Beim Wechsel der Eingangssignale entstehen 
üblicherweise Glitches und es fühlen sich die falschen Stellen 
angesprochen.

> Jedoch habe ich immer noch kein vernünftiges Ergebnis. Vielleicht ist es
> auch einfach keine gute Idee den Latch-Eingang über einen 8205 laufen zu
> lassen. Der Baustein erwärmt sich schon ein wenig und der H-Pegel liegt
> bei knappen 3,7 V. Ohne angeschlossene Anzeigen entspricht der H-Pegel
> Ub. SIeht so aus, als ob die Latch-Eingänge einfach zu viel Strom
> brauchen?

Die Wärmeentwicklung dürfte bei diesen Uralt-Highspeed TTL (i8205 
scheint 74s138 zu entsprechen) eher normal sein. Der Spannungsabfall ist 
etwas hoch, befindet sich aber noch im grünen Bereich.

> DCF-Empfänger und 1-2 Tasten

Ah, eine Funkuhr :). Ich habe mir vor kurzem ein ähnliches Projekt 
gebaut. Allerdings mit neumodischen 8x8 Anzeigen (3x) und einem 
Mega8535. Ein paar VQC10 liegen hier zwar auch noch herum, allerdings 
hat mich der etwas hohe Stromverbrauch bei gleichzeitig ziemlich kleiner 
Zifferngröße und -helligkeit abgeschreckt.

von Sven L. (svenl)


Lesenswert?

Mike schrieb:

> Du kannst die auf den Ports ausgegeben Daten auch wieder einlesen. In
> deinem Beispiel wären das PINB und PIND.

Laut Simulation in AVR-Studio passt der Inhalt der Ports. Ich arbeite 
über eine lokale Variable um Änderungen am Port atomar zu machen.

> Am Decoder für die Select-Signale solltest du auch unbedingt ein
> Enable-Signal benutzen. Beim Wechsel der Eingangssignale entstehen
> üblicherweise Glitches und es fühlen sich die falschen Stellen
> angesprochen.

DAS ist ja mal eine Aussage! :) Bisher habe ich das Enable-Signal 
(Eingang E3, Active-High) zur Erzeugung der Taktflanke für das Latch 
benutzt, jedoch beim Setzen der Taktleitung den Eingang eingeschaltet 
gelasssen. Das würde den Effekt der unsauberen Ansteuerung erklären. - 
Ich werde das gleich einmal ausprobieren.

> Ah, eine Funkuhr :). Ich habe mir vor kurzem ein ähnliches Projekt
> gebaut. Allerdings mit neumodischen 8x8 Anzeigen (3x) und einem
> Mega8535. Ein paar VQC10 liegen hier zwar auch noch herum, allerdings
> hat mich der etwas hohe Stromverbrauch bei gleichzeitig ziemlich kleiner
> Zifferngröße und -helligkeit abgeschreckt.

Ja, es soll eine Funkuhr werden und zwar eine UTC-Funkuhr, die egal ob 
Sommer- oder Winterzeit, die korrekte UTC-Zeit anzeigt. Vielleicht auch 
noch Umschaltbar auf MEZ/MESZ. Der Stromverbrauch und die 
Wärmeentwicklung ist nicht ohne, ist jedoch bei genügend schneller 
Ansteuerung auch in den Griff zu bekommen. - Der Mega8 läuft mit 16 MHz 
und sollte genügend Leistung für Multiplex und Funkuhrfunktionalität 
gleichzeitig haben. Ob die Rechenleistung wirklich ausreicht, werde ich 
noch sehen. Ansonsten muss ich den Mega8 zum SPI-Controller mit 
integriertem Zeichensatz für die VQC10 umstricken und einen zweiten 
Controller für die Uhr nehmen. Dann hätte ich auch die Möglichkeit 
einige Relais mit programmierbaren Schaltzeiten anzusteuern.

Ich habe diese beiden VQC10 vor vielleicht 12-14 Jahren originalverpackt 
von einem befreundeten Funkamateur bekommen und sie lagen die ganze Zeit 
herum. :) Jetzt wird es Zeit mit denen etwas zu machen! - Sicherlich 
gibt es einfachere Alternativen wie HD44780-kompatible Displays oder 
LED-Matrix-Anzeigen mit SPI-Schnittstelle, aber es macht unheimlich viel 
Spaß diese alten Anzeigen zum Leben zu erwecken! :)

Evtl. Ergebnisse poste ich hier im Thread.

Gruß!

Sven

von Toralf W. (willi)


Lesenswert?

So ich noch einmal, ich habe an der Quelle gewerkelt und da gab es immer 
Anzeigen mit def Chips, die wurden meistens von Hand ersetzt, trotzdem 
ist genug Ausschuß zum experimentieren über geblieben. Die bekommt man 
eigentlich nur tot, in dem man die "SpaltenLatches" überlastet durch 
gleichzeitiges aktivieren der Zeilenspannung. Wer davor Angst hat, muß 
halt überwachen, das nur immer eine Zeile an UB liegt. Der Ausfall des 
multiplexen und somit ein Dauerleuchten der letzten Zeile führt nicht 
zum Ausfall der LEDs (das halten die aus). Sollte man aber trotzdem 
nicht machen!
Gruß Willi

von Axel R. (Gast)


Lesenswert?

Die Zeit "time" liegt als zurechgebastelter String "9:59" im 
Speicher.Die Numerischen Elemente "Minute" und "Sekunde" werden 
sekündlich heruntergezählt und neu in einen String gewandelt, bis eben 
"0:00" im Display steht. Das habe ich jetzt mal weggelassen.
1
Sub zeit_anzeigen()
2
  s_displ_akt=time  
3
        display_data(20,15)
4
End Sub
um einen String darzustellen, ist die globale Variable "s_displ_akt" 
entsprechend zu belegen. "Dimm" und "stelle" erlauben zb die 2te Stelle 
hell darzustellen und allle anderen Stellen dunkel. (hier nicht 
dargestellt, einfache Software PWM in 16(dimm)stufen)
1
Sub Display_data(dimm As Byte, stelle As Byte)
2
  
3
    dimm_global=dimm
4
    stelle_zum_dimmen=stelle
5
    MemCopy(4,VarPtr(s_displ_akt),VarPtr(a))
6
    idx_st0= (a-32) * 8
7
    idx_st1= (b-32) * 8
8
    idx_st2= (c-32) * 8
9
    idx_st3= (d-32) * 8
10
11
End Sub

Der enable vom Ecoder ist ständig an. Es handelt sichum einen 74154er 
(im schmalen Gehäuse) am PortC.
Bei jedem Interrupt (100us) werden
 - alle Zeilen dunkelgetastet (PortC > 7)
 - die spaltendaten aus dem Flash geholt(Zeichentabelle)
 - Zeile n der vier Stellen mit den Spaltendaten versorgt
   (CS der Spalten 1 bis 4 liegen an den Ausgängen 8 - 11 der 154er).
 - Die Zeile n aktiviert (über PNP BC 807)
(n=0 bis 7)
1
Interrupt Ovf0()
2
3
   Incr zeile
4
  If  zeile = 8  Then 
5
            zeile = 0
6
  End If
7
8
   daten_st1 = idx_st0+zeile
9
   daten_st2 = idx_st1+zeile
10
   daten_st3 = idx_st2+zeile
11
   daten_st4 = idx_st3+zeile
12
   temp11 = spaltendaten(daten_st1)
13
   temp22 = spaltendaten(daten_st2)
14
   temp33 = spaltendaten(daten_st3)
15
   temp44 = spaltendaten(daten_st4)
16
   PORTC = 8
17
   PORTB = temp11
18
   PORTC = 9
19
   PORTB = temp22
20
   PORTC = 10
21
   PORTB = temp33
22
   PORTC = 11
23
   PORTB = temp44
24
   PORTC = zeile
25
End Interrupt

Ich hoffe, ich werde fürs FastAVR Basic nicht gesteinigt ;-))

Viele Grüße
Axelr.

@Jörg
hatte kurzfristig noch VQC10 von 'nem WFler erhalten. Vielen Dank für 
dein Angebot. sry wegens nich melden...

von Sven L. (svenl)


Lesenswert?

Ich habe heute noch einmal mehrere Varianten durchprobiert und ich 
bekomme nichts sinnvolles auf dem Display angezeigt.

Die Taktleitungen hängen an einem 8205 (1-aus-8 Decoder), sodass immer 
eine Stelle ansprechbar ist.

Das Multiplex läuft so, dass ich eine Stelle mit allen Reihen beschreibe 
und dann zur nächsten Stelle wechsel.

Ich setze den Enable-Eingang 3 (Active-High) vom 8205 auf Low, damit 
gehen alle Takteingänge an den beiden VQC10 auf H. Dann setze ich den 
BCD-Code für die ausgewählte Stelle am Port und schalte mit 20 µs 
Verzögerung den 8205 wieder ein. Die Taktleitung an der entsprechenden 
Stelle geht auf L.

Wieder 125 µs später (laut Datenblatt) setze ich die Spaltendaten. Mit 
weiteren 125 µs Verzögerung setze ich den Enable-Eingang vom 8205 wieder 
auf L, die Taktleitungen gehen auf H und die steigende Flanke löst den 
Latch für die entsprechende Displaystelle aus. Hier folgt eine 
Verzögerung von ca. 250 µs, damit man das Leuchten der LEDs auch 
erkennt. - Dann passiert das ganze wieder von vorn mit der nächsten 
Zeile.

Das Timing sollte nun so sein wie im Datenblatt beschrieben. Ich habe es 
auch anders herum probiert, dass ich die Daten vor dem Setzen des 
BCD-Codes für die Stelle (Taktleitungseingang VQC10) gesetzt habe, aber 
das führte auch nicht zum Ziel...

Kann mir irgendwer weiterhelfen, der die Dinger schonmal am Laufen 
hatte? - Mich würde das Timing interessieren.

Im Notfall muss ich eben den 8205 rauswerfen und die Taktleitungen 
direkt ansteuern. In der Beispielapplikationsschaltung wurde jedoch auch 
ein K155ID3 genommen. Da ich jedoch nur zwei VQC10 ansteuere reicht auch 
ein 8205. - Das Auffangregister 8212 benutze ich nicht. Da ist mir mein 
letztes Exemplar schon im Frühstadium des Steckbrettaufbaus durch 
Kurzschluss gestorben.

Sven

von Axel R. (Gast)


Lesenswert?

>Das Multiplex läuft so, dass ich eine Stelle mit allen Reihen beschreibe
>und dann zur nächsten Stelle wechsel.

Machs anders: schreibe erst die Daten für die obere Zeile für alle 
Stellen, danach aktivierst Du den PNP, um die komplette Zeile auf allen 
4 Stellen gleichzeitig anzeigen zu lassen.

Dann tastest Du dunkel und schreibst für alle 4Stellen die Daten der 
Zeile darunter rein. Nun aktivierst Du den PNP für diese Zeile.

Und so weiter, bis alle Zeilen durch sind. Ob nun von oben nach unten 
oder unten nach oben hängt nur von der Organisation deines Zeichensatze 
im Flash ab.

So mach ich das und das funktioniert gut.

Kann man die .3gp Sequenz eigentlich mit Windiows Hausmitteln anzeigen 
lassen?

http://www.mikrocontroller.net/attachment/39569/MOV00656.3GP

Gruß
Axelr.

von Axel R. (Gast)


Lesenswert?

Ich hätte das mal aufzeichnen sollen :-((
Ist alles als Nudelsuppe mit einfarbig brauner, recht dicker PVC-Litze 
auf Lochraster...

Ich habe nur den Mega8, den 74154, die VQC10 und einen Drehencoder fürs 
Menü drann.

Muss ich wohl noch aufmachen, den Belichter ;-))

von Toralf W. (willi)


Lesenswert?

Axel Rühl schrieb:

> Machs anders: schreibe erst die Daten für die obere Zeile für alle
> Stellen, danach aktivierst Du den PNP, um die komplette Zeile auf allen
> 4 Stellen gleichzeitig anzeigen zu lassen.
>
> Dann tastest Du dunkel und schreibst für alle 4Stellen die Daten der
> Zeile darunter rein. Nun aktivierst Du den PNP für diese Zeile.
>
> Und so weiter, bis alle Zeilen durch sind. Ob nun von oben nach unten
> oder unten nach oben hängt nur von der Organisation deines Zeichensatze
> im Flash ab.
>
> So mach ich das und das funktioniert gut.

Hallo Axel,
so hast Du das bestimmt nicht gemacht, Du hast ja nur D1-5 als 
Dateneingänge, das reicht nur für eine der vier Anzeigestellen!
also noch einmal: nach einander die daten für die vier Anzeigestellen 
Anlegen und mit dem entsprechenden cp Eingang in die Latches übernehmen.
Dann stehen die Daten für eine komplette Zeile in den Latches und nan 
kann mit dem pnp die Zeile einschalten.
Ich habe einmal eine DCC Zentrale mit 90s4433 gebaut, ich schaue heute 
Abend einmal ob das ASM File noch da ist, die Hardware war ist auch nur 
Lochraster mit 7 pnp für die Zeilen.
Gruß Willi

von Axel R. (Gast)


Lesenswert?

D1 bis D5 sind die 5 LEDs von links nach rechts
1
xxxxx ..... ..... ..... 
2
..... ..... ..... .....
3
..... ..... ..... .....
4
..... ..... ..... .....
5
..... ..... ..... .....
6
..... ..... ..... .....
7
..... ..... ..... .....
1
xxxxx xxxxx ..... ..... 
2
..... ..... ..... .....
3
..... ..... ..... .....
4
..... ..... ..... .....
5
..... ..... ..... .....
6
..... ..... ..... .....
7
..... ..... ..... .....
1
xxxxx xxxxx xxxxx ..... 
2
..... ..... ..... .....
3
..... ..... ..... .....
4
..... ..... ..... .....
5
..... ..... ..... .....
6
..... ..... ..... .....
7
..... ..... ..... .....
1
xxxxx xxxxx xxxxx xxxxx 
2
..... ..... ..... .....
3
..... ..... ..... .....
4
..... ..... ..... .....
5
..... ..... ..... .....
6
..... ..... ..... .....
7
..... ..... ..... .....

So, 4 x 5 bits reingesspeichert. Jetzt aktiviere ich für die obere Zeile 
den entsprechenden PNP Treibertransistor. Die Zeile (alle 4 Stellen 
gleichzeitig)leuchtet.
1
***** ***** ***** ***** 
2
..... ..... ..... .....
3
..... ..... ..... .....
4
..... ..... ..... .....
5
..... ..... ..... .....
6
..... ..... ..... .....
7
..... ..... ..... .....

Jetzt den Transistor 100uS oderso an lassen, abschalten und wie oben von 
vorn:
alles aus
1
..... ..... ..... .....
2
..... ..... ..... .....
3
..... ..... ..... .....
4
..... ..... ..... .....
5
..... ..... ..... .....
6
..... ..... ..... .....
7
..... ..... ..... .....
8
9
Daten für Stelle1 aber immernoch aus
1
..... ..... ..... .....
2
xxxxx ..... ..... .....
3
..... ..... ..... .....
4
..... ..... ..... .....
5
..... ..... ..... .....
6
..... ..... ..... .....
7
..... ..... ..... .....
Für Stelle2
1
..... ..... ..... .....
2
xxxxx xxxxx ..... .....
3
..... ..... ..... .....
4
..... ..... ..... .....
5
..... ..... ..... .....
6
..... ..... ..... .....
7
..... ..... ..... .....
Für Stelle3
1
..... ..... ..... .....
2
xxxxx xxxxx xxxxx .....
3
..... ..... ..... .....
4
..... ..... ..... .....
5
..... ..... ..... .....
6
..... ..... ..... .....
7
..... ..... ..... .....
Für stelle4
1
..... ..... ..... .....
2
xxxxx xxxxx xxxxx xxxxx
3
..... ..... ..... .....
4
..... ..... ..... .....
5
..... ..... ..... .....
6
..... ..... ..... .....
7
..... ..... ..... .....
Alle Zeilendaten liegen vor, aber immernoch aus
und PNP für die Zeile einschalten, 100us an lassen abschalten und von 
vorn
mit der dritten zeile usw.
1
..... ..... ..... .....
2
***** ***** ***** *****
3
..... ..... ..... .....
4
..... ..... ..... .....
5
..... ..... ..... .....
6
..... ..... ..... .....
7
..... ..... ..... .....


von links nach rechts die Zeile mit Daten befüllen und dann diese eine 
Zeile gemeinsam alle 4Stellen aktivieren.

Könnte man mal 'ne Animation von machen, kA.wie.
Besser erklären kann ich es nicht.

von Axel R. (Gast)


Lesenswert?

>also noch einmal: nach einander die daten für die vier Anzeigestellen
>Anlegen und mit dem entsprechenden cp Eingang in die Latches übernehmen.
>Dann stehen die Daten für eine komplette Zeile in den Latches und nan
>kann mit dem pnp die Zeile einschalten.

Naja, sag ich doch...

von Michael P. (protactinium)


Angehängte Dateien:

Lesenswert?

haben bei uns in der Hochschule auch ein Paar von den Anzeigen beim 
Aufräumen gefunden.

Natürlich gleich mal ne Platine für 5 Anzeigen gemacht (ist im Anhang).
Ein wenig Quellcode zum Testen gibts auch schon. Ist aber nur für eine 
Anzeige (auch im Anhang).

von Sven L. (svenl)


Angehängte Dateien:

Lesenswert?

So, es gibt Neuigkeiten:

Es ist mir gelungen etwas sinnvolles auf dem Display anzuzeigen. Jedoch 
wird jeweils die letzte Stelle um eine Zeile nach unten versetzt 
angezeigt? Also auch, wenn ich bei 8 möglichen Stellen nur 6 ansteuere, 
dann ist bei der sechsten Stelle das Zeichen um eine Zeile nach unten 
versetzt und die letzte Zeile steht in der ersten. - Laut Quelltext kann 
das aber gar nicht sein! :) - Ich gehe mal davon aus, dass meine 
Verkabelung stimmt, da das bei jeder Stelle reproduzierbar ist.

Ich fülle die Spalten von allen Stellen wie vorgeschlagen mit Daten und 
speichere diese dann in den Auffangsregistern bevor ich die Reihe für 
100 µs einschalte.

Das ganze sieht in etwa so aus:
1
for (row = 0; row < 7; row++)
2
{
3
    for (disp = 0; disp < 8; disp++)
4
    {
5
        // Setzen der Datenbits auf jeder Stelle
6
        vqc_setdata(disp, pgm_readbyte(&chartab[scancode][row]));
7
    }
8
    // Setzen der aktiven Zeile
9
    vqc_setrow(row);
10
    // Wartezeit
11
    _delay_us(100);
12
}

chartab ist ein zweidimensionales Array im Flash-Speicher, welches den 
ASCII-Zeichensatz in 5x7 für das VQC10 beinhaltet. vqc_setdata() setzt 
die Datenbits an der entsprechenden Displaystelle und vqc_setrow() 
aktiviert die aktuelle Zeile.

Es sieht so aus, als ob beim letzten Durchlauf der inneren for-Schleife 
der Wert für row bereits inkrementiert ist, was ja aber mit dieser 
Programmlogik nicht sein kann. Es müsste erst noch die korrekte erste 
Zeile eingeschaltet werden und dann ist die äußere for-Schleife beendet 
und danach wird row inkrementiert, was aber keinen Einfluss auf die 
aktuelle Spalte hat, da die Ausgangspins bereits gesetzt sind.

Jedenfalls habe ich den Quellcode dessen ungeachtet noch ein wenig 
vorangetrieben und die komplette Displayansteuerung in ein extra Modul 
gepackt und lasse das Display nun über eine ISR aktualisieren, wobei 
Timer0 durch Überlauf die Interruptquelle darstellt (CPU-Takt/256). 
Soweit erst einmal so gut.. :) - Wenn der Quellcode zur 
Displayansteuerung fertig ist, dann stelle ich in hier gern zur 
Verfügung. Er ist zumindest so allgemein gehalten, dass man 1-4 VQC 
ansteuern kann und die Anschlussbeine über Makros festlegen kann. Bei 
noch mehr Anzeigen wird sich Multiplex sicherlich nicht mehr lohnen und 
man nimmt Schieberegister. Mit dem Quellcode wäre es aber bestimmt 
möglich SPI-enabled VQC10-Displays zu bauen... ;)

Ich hoffe, dass noch genügend Rechenleistung übrigbleibt, um korrekt die 
DCF-Telegramme zu lesen. Multiplex von 280 LEDs ist nunmal kein 
Pappenstiel, die Taktfrequenz von 16 MHz allerdings auch nicht.

Jedoch nervt immer noch dieses Zeilenproblem. Vielleicht sehe ich ja den 
Wald vor lauter Bäumen nicht?

Gruß!

Sven

PS: Auf dem angehängten Bild sieht man es bei dem Buchstaben 'H'. Der 
Buchstabe beginnt erst in der zweiten Zeile und die 7. Zeile landet in 
der ersten. Deswegen ist der Mittelstrich beim H auch zu tief. Bei allen 
anderen Buchstaben fällt das natürlich mehr auf.

von Axel R. (Gast)


Angehängte Dateien:

Lesenswert?

im Anhang eine kurze Skizze, wie ich eine VQC10 mit einem Mega8 
verheiratet habe.

von Axel R. (Gast)


Lesenswert?

>Das ganze sieht in etwa so aus:
1
for (row = 0; row < 7; row++)
2
{
3
    vqc_setrow(8); // <--===   Alle Zeilen ausschalten   
4
    for (disp = 0; disp < 8; disp++)
5
    {
6
                      // Setzen der Datenbits auf jeder Stelle
7
        vqc_setdata(disp, pgm_readbyte(&chartab[scancode][row]));
8
    }
9
    // Setzen der aktiven Zeile
10
    vqc_setrow(row);
11
    // Wartezeit
12
    _delay_us(100);
13
}

ich würde die Zeilen dunkeltasten, BEVOR ich neue Daten hineinschreibe.
zu deinem SW Problem habe ich als "C-Gelegenheitsprogramierer" folgendes 
gefunden )ohne Gewähr;-)):

aus: http://info.baeumle.com/c06.html#3-2
1
Die for-Schleife
2
3
Die for-Schleife in C ist ein sehr mächtiges Konstrukt, das durchaus nicht nur für die klassischen Zählschleifen verwendet wird.
4
5
Die Syntax hat die Form
6
7
for ( <expression1> ; <expression2> ; <expression3> ) <statement>
8
9
Mit Ausnahme der später zu besprechenden continue-Anweisung ist die for-Schleife äquivalent zu
10
11
<expression1>;
12
while (<expression2>)
13
{
14
   <statement>
15
   <expression3>;
16
}
17
18
Das bedeutet: <expression1> ist eine Anweisung, die vor dem eigentlichen Schleifenbeginn ausgeführt wird. <expression2> ist die 
19
logische Bedingung, die die weitere Schleifenverarbeitung regelt: solange <expression2> erfüllt (d.h. ungleich 0) ist, 
20
wird <statement> ausgeführt. Schließlich ist <expression3> eine Anweisung, die zum Abschluß eines jeden Schleifendurchgangs 
21
ausgeführt wird, die sogenannte Reinitialisierung.
22
23
Beispiel: Die nachstehende for-Anweisung summiert alle ganzen Zahlen von 0 bis 9 in der Variablen sum auf; dabei wird 
24
sum kompakterweise auch noch im Kopf der for-Schleife initialisiert.
25
26
for (sum=i=0; i<10; i++)
27
{
28
29
   sum += i;
30
31
}

demnach müsstest Du eigentlich schreiben:

for (row = 0;row < 6;row++)
{

}

oder? Denn es sind ja nur sieben Zeilen und nicht acht.

von Sven L. (svenl)


Lesenswert?

Nein, die Elemente 0 bis 6 einschließlich 0 und 6 sind 7 Elemente. Damit 
die Bedingung erfüllt ist, muss es row < 7 heißen, denn sonst würde bei 
6 kein Schleifendurchlauf mehr stattfinden.

Ich kann mir echt nicht vorstellen woran das liegt!?

Zu Deiner Beruhigung habe ich das mit 6 anstatt der 7 ausprobiert und es 
fehlte wie erwartet die letzte Zeile. :)

Wenn ich das Zeitintervall zwischen den Zeilen auf 1 Sekunde erhöhe, 
dann sieht man sehr gut, dass bereits beim Setzen der 1. Zeile der 
falsche Wert eingetragen wurde. Das kann aber nicht sein, da an der 
entsprechenden Stelle im Flash der korrekte Wert steht und das Byte über 
die entsprechende Variable row ausgewählt wird. - Ich kann mir nur 
vorstellen, dass der Compiler hier etwas falsch macht und die Variable 
vorher inkrementiert wird und das darf nicht sein!

Ich teste das nochmal mit AVR-Studio und debugge nochmal durch.

Sven

von Sven L. (svenl)


Lesenswert?

Ich habe es noch einmal durchgespielt und komme zu dem Ergebnis, dass 
die Variablen den richtigen Wert zur richtigen Zeit beinhalten, jedoch 
die letzte Stelle immer noch eine Zeile nach unten rutscht.

Die Verkabelung habe ich auch noch einmal überprüft und es ist alles in 
Ordnung. Da das Bitmuster für jede Stelle anhand der gerade aktiven 
Zeile aus dem Flash geholt wird und alle Stellen außer der letzten 
korrekt beschrieben werden, bin ich mit meinem Latein am Ende. :(

Gerade scrollt der ASCII-Zeichensatz komplett durch und die Zeichen sind 
immer auf der letzten Stelle um eine Reihe nach unten versetzt und auf 
allen anderen Stellen ok. Seltsam, nicht?

Sven

von Sven L. (svenl)


Angehängte Dateien:

Lesenswert?

Soooo....

Ein paar Probleme habe ich lösen können. - Jetzt habe ich zumindestens 
schon mal eine Quarzuhr! :)

In der Zählschleife 1000 ms warten war viel zu viel. So bei 770 ms 
entspricht eine Sekunde dann auch in etwa einer Sekunde. Die restliche 
Zeit vertrödelt der Controller beim Multiplexen und sonstigem Code.

Das Multiplex wird über eine ISR bei Counter-Überlauf von Counter0 
ausgelöst. Momentan werden in der Multiplex-Routine noch der 
anzuzeigende String in die entsprechenden ASCII-Codes aus dem Flash 
übersetzt. Das soll in Zukunft vorher passieren und die ISR dann nur 
noch einen Buffer mit dem Displayinhalt fertig übersetzt auslesen. Wie 
"dramatisch" der Geschwindigkeitszuwachs sein wird, werde ich noch 
sehen. - Ich kann mir aber vorstellen, dass pgm_read_byte() nicht 
besonders performant ist.

Als Prescaler nehme ich Clock/512. Da hat das Display eine angenehme 
Helligkeit und kein Flimmern.

In Zukunft soll nach erfolgter Dekodierung das Inkrementieren der 
Zeitvariablen über die Flanke des DCF-Signals passieren. Oder soll ich 
dafür einen Timer nehmen? - Ich werde mir wohl noch den einen oder 
anderen DCF-Code anschauen müssen.

Anbei ein kleines Video...schaut soweit schonmal ganz gut aus! Das 
Display ist übrigens ASCII-enabled, sodass man den gesamten Zeichensatz 
darauf darstellen kann. Der 5x7-Font entspricht weitestgehend dem 
HD44780-Original.

Sven

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Sven L. schrieb:

> Ich kann mir aber vorstellen, dass pgm_read_byte() nicht
> besonders performant ist.

Es ist genau einen Takt weniger performant als das Lesen aus dem
SRAM.  Dieser Takt ist der systembedingte Gewinn, den Zugriffe auf
den Datenspeicher in einer Harvard-Architektur normalerweise haben
(durch die Nutzung getrennter Busse für Daten und Befehle).  Der
einzige weitere Nachteil ist, dass auf Grund der Inline-Assembler-
Implementierung der Compiler nicht in der Lage ist, ein LPM rd,Z
durch ein LPM rd,Z+ zu ersetzen wenn er feststellt, dass die Adresse
direkt danach zu inkrementieren ist.

von Denis K. (denis_tbg)


Lesenswert?

Hallo.

Hat jemand nen einfachen Quelltext um eine VQC10 zu testen?
Ich verwende die Schaltung von Axel Rühl.
Einfach ein Segmenttest oder so. Ich bin gerade erst am C lernen, daher 
kann ich mit den einzelnen Codeschnipseln nicht viel anfangen...

MfG

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.