Forum: Mikrocontroller und Digitale Elektronik Agilent HCMS-29xx LED Display seriell ansteuern


von Dumpfbacke (Gast)


Lesenswert?

Hallo,

hat schonmal jemand mit o.g. Displays gearbeitet? Habe das Datenblatt 
durchforstet aber als µC Rookie ist mir das zu kompliziert um daraus 
einen lauffähigen Code zu erstellen. Wäre sehr dankbar wenn schonmal 
jemand was mit den Displays gemacht hat und einen Code-Auszug hier 
posten könnte.

THX!

von jjk (Gast)


Lesenswert?

>Hallo,

>hat schonmal jemand mit o.g. Displays gearbeitet?

Ja.

>Habe das Datenblatt
>durchforstet aber als µC Rookie ist mir das zu kompliziert um daraus
>einen lauffähigen Code zu erstellen.

Hmm.

>Wäre sehr dankbar wenn schonmal
>jemand was mit den Displays gemacht hat und einen Code-Auszug hier
>posten könnte.

Wie waere es denn dazu direkt beim Hersteller nachzusehen:
http://www.avagotech.com/products/product-detail.jsp?navId=H0,C1,C5231,C4941,C4964,C5096,P89901

Einfach mal nach unten scrollen und die beiden ersten App. Notes 
ansehen, D-002 und D-003. Da steht alles drin,  Anbindung an einen 
Controller samt Beispielcode  incl. Initialisierungsroutinen, 
Zeichensatztabelle und Schaltungsvorschlag zur Kaskadierung zweier 
Diplayzeilen.
Das Programm erzeugt eine Laufschrift: "Hewlett Packard" auf zwei 
8-stelligen Displays.

Die Ansteuerung selbst ist eigentlich einfach, Du brauchst halt immer 
eine separate Zeichensatztabelle.  Aber auch das ist in der App. Note 
D-003 bzw. im Beispielcode enthalten.

Versuch mal zuerst den gut dokumentierten und ausfuehrlich erlaeuterten 
Beispielcode zu verstehen (incl. der Control Word Sequenz) und das 
dann auf Deinen Controller zu uebertragen.

Wenn das funktioniert hat kannst Du den Code weiter ausbauen:
Z.B. eine vollstaendige ASCII Zeichensatztabelle mit Sonderzeichen 
anlegen.
Die Control Word Sequenz kann man auch anders programmieren.
Sinnvoll ist es auch einen eigenen Display-RAM-Bereich, Groesse 
entsprechend der Anzahl der Stellen, zu definieren. Von dort aus auf die 
Zeichensatztabelle zugreifen, den entsprechenden Zeichencode auslesen 
und seriell zum Display schicken, das laesst sich prima als kurze 
Display- Routine machen. Dann schreibt man naemlich in einer Anwendung 
lediglich ASCII Zeichen ins Display-RAM an die passende Stelle und ruft 
anschliessend nur noch die Display-Routine auf. Fertig.

Wenn Dir das zu kompliziert ist, HDSP 2112 bzw. OSRAM IPD 213x haben 
integrierte ASCII Zeichensatztabellen sowie ein Display RAM und werden 
auch genauso einfach wie ein RAM parallel angesteuert.

jjk

von Dumpfbacke (Gast)


Angehängte Dateien:

Lesenswert?

Hi jjk,

danke für die Links. Das Interfacing Dokument habe ich vorgestern auch 
bereits entdeckt. Das Dokument mit den Character-Codes wird mir auch 
eine grosse Hilfe sein, wenn denn erstmal das Display funktioniert ;)

Aus den Dokus ist die Bedeutung der Controlregister schon klar und auch 
wie CE, CLK, RS gesetzt werden müssen damit einmal Dot oder 
Controlregister beschrieben werden können. Anhand des 
Assembler-Beispiels und des Datenblatts habe ich
versucht mit einem C-Programm das Display anzusprechen. Bisher ohne 
Erfolg, das Display bleibt dunkel und wird nicht aus dem Sleep-Mode 
geweckt. Den Code habe ich schon zig mal überflogen, eigentlich die 
gleiche Funktion wie die Assembler-Routinen.

Werde dann mal weitersuchen dürfen, weshalb es nicht so funktioniert wie 
gewünscht

Den Code habe ich mal angehangen.

von jjk (Gast)


Lesenswert?

Hmm.

Also so kann ich Dir erst mal nicht weiterhelfen.
Ich muesste wissen wie Du das Display an was (uC?) angeschlossen hast.
Wie wird der Reset erzeugt?
Welches Display aus der 29er Serie verwendest Du?
4-, 8- oder 16-stellig?
Wie hast Du BLANK und SEL verdrahtet?


Ich kann zwar C im Prinzip lesen, mehr aber auch nicht, ich programmiere 
seit 20 Jahren ausschliesslich in ASM.
Was mir aber zunaechst auffaelt ist dass Du offenbar erst CW 0 
schreibst, dann CW 1. Das muss schon mal umgekehrt sein.

Vergiss mal die verschachtelte CW1/CW0 Sequenz und mach es stur der 
Reihe nach. Die Normale Sequenz sieht so aus:

1. Reset
Entweder per Port von einem uC oder parallel zum Resetpin eines 
Controllers.
Die 3 sec delay aus dem Beispielcode sind uebrigens voellig unnoetig, 
nach einem normalen Reset arbeiten die Displays auch ganz normal.

2. Nach dem Reset sind zwar alle Register des Displays auf 0 und das 
Display im sleep mode, aber die Datenregister enthalten Zufallsdaten, 
deshalb schreibt man da ja zu Beginn, bevor man das Display aufweckt, 
erst mal Nullen rein.
Bei einem 4-stelligen Display 5x8!x4=160 Nullen.
Bei 8-stelligem 320 Nullen usw.
Hier koenntest Du uebrigens als Test nach einem Reset das Display mit CW 
0 direkt aufwecken, dann muesstest Du irgendwelche Zufalls-LED-Muster 
sehen. Es ist naemlich unwahrscheinlich dass nach Reset zufaellig alle 
Datenregister Null sind.

3. CW 1
Fuer Simultanbetrieb mit internem Oszillator wird 81H in das 
Controllregister geschrieben.
Bei einem 8-stelligen Display genau 1x (das verbindet die beiden 
internen ICs einer 8-stelligen Anzeige). Ansonsten N-1 mal wenn man 
mehrere Displays kaskadiert.

Ich verwende aktuell 5x 8-stellige Displays kaskadiert, also 10 interne 
ICs bei insgesamt 40 Display-Stellen. Da wird dann CW 1 9x geschrieben.

Bei einem 4-stelligen Display ist es eigentlich unnoetig,
es sei denn man wollte es fuer ext. Oszillator konfigurieren.
Schaden kann da CW 1 mit 81H aber nicht.

4. CW 0
Sofern man das Display mit CW 1 auf Simultanbetrieb gesetzt hat (81H) 
wird CW 0 nur noch 1x fuer alle Displays geschrieben, egal wieviele 
kaskadiert sind.
Fuer den Normalfall reicht da Aufwecken und Helligkeit festlegen mit 
66H.
Bei normalen Lichtverhaeltnissen reichen 66H / 68H oder 6AH fuer CW 0 
voellig aus.

Jetzt ist das Display aktiv, aber alle Stellen dunkel.

Als naechstes kannst Du Dir fuer Testzwecke einen der Buchstaben des 
Beispielcodes aussuchen:

Nimm "H" und schick die dazugehoerenden 5 Bytes bitweise zum Display. 
Wenn Du das 1x machst dann steht "H" an letzter Stelle, Rest ist dunkel.
Oder 4x hintereinander, dann steht "H" an allen 4 Stellen.

Danach 3 sec delay und wieder zum Anfang zurueck als Endlosschleife.
Das sollte "H" mit 3 sec blinken lassen. Mit einem Scope kannst Du dann 
bequem auf Fehlersuche gehen.

Ein Schaltplan waere btw hilfreich.

jjk






von Dumpfbacke (Gast)


Lesenswert?

Hallo jjk,

die Datenleitungen des 4 Zeichen Display HCMS-2904 sind an einem 
ATMEGA168 (auf MyAVR Board) an den Pins C0-C3 angeschlossen. Der Atmega 
hat einen externen Quartz, 3.8 Mhz. Das Display soll den eingebauten 
internen Qszillator verwenden.

Den Hinweis das zuerst CW1 und dann CW0 gesetzt werden muss habe ich in 
der Dokumentation wohl überlesen bzw. falsch verstanden. Ich habe zuerst 
CW0 und dann CW1 geschrieben. Vielleicht war das schon der Grund weshalb 
sich das Display nicht aufwecken ließ.

Probiere ich heute Abend gleich mal aus.

Wenns nicht laufen sollte poste ich den Schaltplan.

Schonmal vielen Dank!

Gruß
  Arne

von jjk (Gast)


Lesenswert?

>die Datenleitungen des 4 Zeichen Display HCMS-2904 sind an einem
>ATMEGA168 (auf MyAVR Board) an den Pins C0-C3 angeschlossen. Der Atmega
>hat einen externen Quartz, 3.8 Mhz. Das Display soll den eingebauten
>internen Qszillator verwenden.

Ok. Dann ist auch CW1 mit 81h korrekt.

>Den Hinweis das zuerst CW1 und dann CW0 gesetzt werden muss habe ich in
>der Dokumentation wohl überlesen bzw. falsch verstanden. Ich habe zuerst
>CW0 und dann CW1 geschrieben. Vielleicht war das schon der Grund weshalb
>sich das Display nicht aufwecken ließ.

Naja, da bin ich mir nicht so sicher ;)

Ich war bisher von min. einem 8-stelligen Display ausgegangen da man mit 
4 Stellen ja eher wenig anfangen kann.

Aber bei nur "einem" 4-stelligen Display ist CW1 nicht unbedingt 
notwendig.
Reset setzt das Display ja automatisch auf internen Oszilator, also das 
was Du ohnehin willst.
CW1 braucht man nur wenn man entweder auf externen Oszilator umschalten 
will oder bei mehreren kaskadierten Displays, also ab 8 Stellen.
Wenn man via CW1 dann auf simultaneous umschaltet braucht man 
anschliessend CW0 nur noch einmal schreiben fuer alle Displays.
Bleibt man dagegen im serial mode, dann muss man CW0 eben fuer je 4 
weitere Stellen neu schreiben. Der Vorteil dabei ist aber dass man dann 
pro 4 Stellen jeweils die Helligkeit getrennt regeln kann bzw. auch 
4-stellige Blinkfunktionen rel. einfach implementieren koennte.

Ich verstehe nicht viel von C.
Werden die Ports zuerst am Anfang als Ausgaenge definiert?
Sieht fuer mich so aus als wuerdest Du die Ports erst spaeter 
konfigurieren, kann mich aber auch taeuschen.

Sorgt der print-Befehl in C fuer bit-weises Uebertragen?
In Assembler macht man das bit-weise Uebertragen mit Rotate ins 
Carry-Bit und uebertraegt dann das C-Bit. Ich hoffe mal dass Dein 
C-Compiler aus den print-Befehlen das auch so aehnlich macht.

Lass doch einfach mal alle unnoetigen Teile Deines Codes weg, auch CW1, 
definiere die Ports als Ausgaenge, mach dann einen Display Reset und 
schreib dann direkt CW0 mit 68H.
Danach probier nur 1 Zeichen aus und geh in eine Endlosschleife mit 
etwas delay dazwischen.

Was spricht eigentlich dagegen den Beispielcode in AVR Assembler zu 
uebernehmen? Das sind doch nur ein paar wenige Zeilen.
Kann Dein Compiler auch Assembler ausgeben?
Dann koennte ich Dir den Code korrigieren, AVR Assembler versteh ich, 
auch wenn ich nicht mit AVRs arbeite ;)

>Wenns nicht laufen sollte poste ich den Schaltplan.

Ist soweit ja schon klar, bis auf die Reset-Beschaltung des Displays 
sowie die BLANK und SEL-Pin Beschaltung, also Pin 8 und 10.
BLANK muss an GND und SEL bei nur einem Display an VCC.
Vled und Vlogic hast Du beide an VCC? So sollte es zumindest sein.

>Schonmal vielen Dank!

Gern geschehen.


juergen

von Dumpfbacke (Gast)


Lesenswert?

Hi Jürgen,

es war ein peinlicher Fehler. Die Makros zum bitweisen High und Low 
schalten der Ports habe ich aus einem LCD Sample Code aus diesem Forum 
kopiert. Dort hiess es

#define LCD_CLK_LOW()    PORTC &= ~PC0
#define LCD_CLK_HIGH()    PORTC |= PC0

richtig heissen muss es natürlich
#define LCD_CLK_LOW()    PORTC &= ~(1<<PC0)
#define LCD_CLK_HIGH()    PORTC |=  (1<<PC0)

Bin darauf gestossen weil ich auf dem CLK-Port kein Signal hatte, auf 
den anderen Ports aber schon. Naja, hauptsache jetzt glimmt das Display 
im schönsten Kaminfeuer-Orange und funktioniert.

Ich mache mich dann mal an die Character Umsetzung aus dem Datenblatt 
dessen Link du gepostet hast. Vielen Dank für deine Mühe!

Gruß
 Arne

von jjk (Gast)


Lesenswert?

Hallo Arne.

Schoen dass es jetzt prinzipiell funktioniert.

>Ich mache mich dann mal an die Character Umsetzung aus dem Datenblatt
>dessen Link du gepostet hast. Vielen Dank für deine Mühe!

Das ist ja ganz einfach, Du brauchst nur die Tabelle 1 abtippen.

Ich habe meine Tabelle genau so aufgebaut:

DB "A",7EH,09H,09H,09H,7EH
DB "B",7FH,49H,49H,49H,36H
DB "C",3EH,41H,41H,41H,22H

usw.

Meine Displayroutine sucht die Tabelle nach dem passenden Zeichen ab und 
uebernimmt die Werte die daneben stehen. Das ist alles.
In Deinem Fall mit nur 4 Zeichen wuerde ich trotzdem ein 
Mini-Display-RAM mit 4 Stellen verwenden.

Nach Reset werden ja zuerst direkt Nullen in die Dotregister 
geschrieben.

Ab dann arbeite ich komplett in ASCII:
Ich "loesche" das Display nur noch indem ich alle Display-RAM Stellen 
mit " " (ASCII Blank Zeichen) fuelle und dann zum Display schicke.
Wenn Du dann z.B. nur 2 Zeichen etwa an Stelle 1 und 3 anzeigen willst 
schreibst Du die an die passende Stelle im Display RAM und uebertraegst 
den kompletten RAM Inhalt zum Display. Dazu musst Du Dir nur noch eine 
passende Routine fuer 4 Stellen schreiben.

Viel Spass mit dem Display, ist ein nettes Teil.

juergen

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.