Forum: Mikrocontroller und Digitale Elektronik 8x7Seg Display mit zwei 595 ser./par. Register ansteuern.


von Markus W. (dl8mby)


Angehängte Dateien:

Lesenswert?

Hallo Forum,

habe folgendes Problem:

Ich versuche, das im Anhang abgebildete LED Display via AVR
anzusteuern.
Dabei verwende ich die neue Release der LunaAVR IDE.

Das Display (China/Ebay) besitzt neben VCC/GND nur noch
drei weitere PINs Namens DIO, SCK und RCK.

Ich kann das Display ansteuern, wobei ich nur in der Lage bin,
an einzelnen Positionen (1-8) die Digits anzuzeigen oder alle
auf einmal, aber alle gleich.

Mir ist es noch nicht gelungen, z.B. das Muster 01234567 anzuzeigen.

Mach meinem Verständnis ist der eine 595 für die Segmente einer 
einzelnen 7-Seg. Anzeige zuständig, während der andere die Position der 
jeweiligen
Anzeige selektiert.

Mein Code verwendet z.B. eine Funktion

send16bits(DIG0,POS1)

die an die erste Position (rechts) die Ziffer 0 schreibt.

Der relevante Code sieht wie folgt aus:


avr.device = atmega32
avr.clock  = 16000000
avr.stack  = 64

#define SCL as portA.0
#define DIO as portA.1
#define LOD as portA.2

#define POS1 as 0x01
#define POS2 as 0x02
#define POS3 as 0x04
#define POS4 as 0x08
#define POS5 as 0x10
#define POS6 as 0x20
#define POS7 as 0x40
#define POS8 as 0x80

#define DIG0 as 0x03
#define DIG1 as 0x9F
#define DIG2 as 0x25
#define DIG3 as 0x0D
#define DIG4 as 0x99
#define DIG5 as 0x49
#define DIG6 as 0x41
#define DIG7 as 0x1F
#define DIG8 as 0x01
#define DIG9 as 0x09

SCL.mode = output,high   ' SCL PA.0
DIO.mode = output,high   ' DIO PA.1
LOD.mode = output,high   ' LOD PA.2

procedure main()
  send16bits(DIG0,POS1)
  waitms delay
  send16bits(DIG1,POS2)
  waitms delay
  send16bits(DIG2,POS3)
  waitms delay
  ...
endproc


procedure clkoutbyte(dat as byte)
  dim i as byte
  for i=0 to 7
    DIO=dat.i
    waitus 1
    SCL=0
    waitus 1
    SCL=1
    waitus 1
    SCL=0
  next
endproc

procedure ackbuf()
  LOD=0
  waitus 1
  LOD=1
  waitus 1
  LOD=0
endproc

procedure send16bits(num as byte, pos as byte)
  clkoutbyte(pos)
  clkoutbyte(num)
  ackbuf()
endproc

Wie schaffe ich es nun an eine Position was zu schreiben,
ohne eine vorhergehende Position zu löschen, wenn ich nur
16 bits in die beiden Register reinschieben kann?

Besitzen die beiden verwendeten 4x7-Seg Displays (3461BS)
auch interne Register, die Werte zwischenpuffern?

Oder sind die herausgeführten Anschlüsse nicht ausreichend
für diesen Zweck und es fehlen weitere Steuer-Eingänge wie
-OE ud/oder -MR.

Irgendwie stehe ich auf dem Schlauch und komme nicht hinter das
Geheimnis.

Die Ansteuerung eines Displays mit MAX7219 oder TM1638 ist mir
hinreichend gut gelungen, aber bei dem 595 will es einfach nicht
klappen.

Danke für Eure Anmerkungen und Hinweise.

Markus

: Bearbeitet durch User
von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Markus W. schrieb:
> Besitzen die beiden verwendeten 4x7-Seg Displays (3461BS)
> auch interne Rigister, die Werte zwischenpuffern?

Nö. Das sind dumme 4-fach 7 Segmenter mit gemeinsamer Kathode.
Siehe http://forum.arduino.cc/index.php?topic=139675.0

Für deine ebay Platine musst du zwingend multiplexen, um verschiedene 
Ziffern darstellen zu können. Das heist, du schiebst ins Digit Register 
eine (vermutlich) null durch (sowas wie 0x7F) und setzt den anderen 595 
(den für die Segmente) auf das Muster der Ziffer.
Das ganze muss so schnell wiederholt werden, das da nichts flimmert.

Markus W. schrieb:
> Das Display (China/Ebay) besitzt neben VCC/GND nur noch
> drei weitere PINs Namens DIO,SCK und RCK.

Das könnte so gemeint sein, das das eine Clock für den Segment '595 ist 
und das andere für den Digit-595, ist aber Raterei. Musst du mal 
durchmessen, wenn da keine Beschreibung bei ist.

: Bearbeitet durch User
von Axel S. (a-za-z0-9)


Lesenswert?

Markus W. schrieb:

> Ich versuche das im Anhang abgebildete LED Display via AVR
> anzusteuern.
> Das Display (China/Ebay) besitzt neben VCC/GND nur noch
> drei weitere PINs Namens DIO,SCK und RCK.
...
> Wie schaffe ich es nun an eine Position was zu schreiben,
> ohne eine vorhergehende Position zu löschen, wenn ich nur
> 16 bits in die beiden Rigister reinschieben kann?
> Besitzen die beiden verwendeten 4x7-Seg Displays (3461BS)
> auch interne Rigister, die Werte zwischenpuffern?

Nichts dergleichen. Die Displays sind für Multiplex-Ansteuerung 
verdrahtet. Wie du ganz richtig vermutest, schaltet ein Schieberegister 
ganze Stellen an und aus, während das andere für einzelne Segmente 
zuständig ist.

Siehe: AVR-Tutorial: 7-Segment-Anzeige (dort dann Punkt 3: Mehrere 
7-Segment Anzeigen (Multiplexen))

Als zusätzliche Komplikation kommt bei dir noch hinzu, daß die Anzeigen 
nicht direkt an µC-Ports hängen, sondern an zwei Schieberegistern als 
klassische Porterweiterung.

Den ganzen Kokolores mit waitms vergißt du am besten sofort. Korrekt 
steuert man so etwas mit einem Timer-Interrupt.

von Axel S. (a-za-z0-9)


Lesenswert?

Matthias S. schrieb:
> Das könnte so gemeint sein, das das eine Clock für den Segment '595 ist
> und das andere für den Digit-595, ist aber Raterei.

Und sehr wahrscheinlich falsch geraten. Sehr viel wahrscheinlicher sind 
die beiden '595 kaskadiert. Und der RCK Anschluß ist für das Latch der 
'595, damit die die reingeschobenen Daten auch gleichzeitig übernehmen.

von Markus W. (dl8mby)


Lesenswert?

Hallo Matthias,

danke für Deine schnelle Antwort.

Ich habe es mir fast schon gedacht, dass ich wohl sehr schnell
hintereinander reinschieben muss, um das Nachleuchten im Auge
auszunützen ;-)

Ist leider für meine Anwendung nicht sehr praktikabel, weil zu viel
Störungen durch die Impulse auf den Leitungen erzeugt werden.

Ich dachte das es ein statische Anzeige ist, wenn die Werte einmal
gesetzt sind.

Gruß
Markus

von Markus W. (dl8mby)


Lesenswert?

Hallo Axel,

die waitus waren gedacht um am Oszi besser zs sehen,
on meine Übernahme der Daten mit dem Ser. Clock passt.

Die waitms sind dazu da zm die Ziffern an der Position
eine Weile einzufrieren, sonst sehe ich ja nur Flimmern ;-)

Danke für Eure Antworten.

Markus

von Uwe (de0508)


Lesenswert?

Hallo Markus,

wie viele LED-Stellen benötigst Du ?

von Peter D. (peda)


Lesenswert?

Markus W. schrieb:
> Ich dachte das es ein statische Anzeige ist

Nicht denken, sondern die Beschreibung lesen.
Ist keine Beschreibung dabei, einfach nicht kaufen.

Mit etwas Erfahrung kann man es auch an der Bestückung erkennen:
Statisch: 8 * 595
Multiplex: 2 * 595

Blöd ist, wenn keine Treibertransistoren und Stromeinstellwiderstände 
drauf sind.
Dann schwankt die Helligkeit je nach Anzahl der Segmente und die 595 
können leicht hops gehen.
Solche Sparschaltungen sieht man oft bei Anfängern.

von Markus W. (dl8mby)


Lesenswert?

Hallo Uwe,

das Display hat ja acht davon - ist ja eine fertige Platine.
Wollte eigentlich nur das Ansteuern üben.

Habe Varianten mit 595, 7219 und 1638 Chips zur Ansteuerung
der 8 Digits in meinem Vorrat und wollte testen, welche am
besten geeignet für Spielereien sind und mir davon einige
besorgen.
Wenn man den Code dazu geschrieben hat, und alles wie gewünscht
funktioniert, will man den ja weiter benutzen.

Markus

von Karl H. (kbuchegg)


Lesenswert?

Markus W. schrieb:
> Hallo Axel,
>
> die waitus waren gedacht um am Oszi besser zs sehen,
> on meine Übernahme der Daten mit dem Ser. Clock passt.
>
> Die waitms sind dazu da zm die Ziffern an der Position
> eine Weile einzufrieren, sonst sehe ich ja nur Flimmern ;-)
>

Nicht wirklich.
Je schneller du umschaltest, desto 'stabiler' steht die Anzeige - wenn 
man es richtig macht.

Nichts desto trotz macht man das nicht mit delay oder wait sondern mit 
einem Timerinterrupt.
Man hat ein globales Array, in dem die Muster fuer die einzelnen 
Positionen stehen und im Timerinterrupt wird reihum jeweils die naechste 
Position rausgeschoben und angezeigt. Diese Stelle leuchtet dann, 
waehrend das Programm ausserhalb des Timerinterrupts seiner eigentlichen 
Arbeit nachgeht. Bis dann beim naechsten Timerinterrupt das Muster aus 
dem Array fuer die naechste Stelle rausgetaktet wird.

Wenn man das richtig macht, dann brauchst du dich im Programm nicht mehr 
weiter um die Anzeige kuemmern. Fuer das restliche Programm IST dieses 
Array die Anzeige. Was immer es auszugeben gilt, wird in das Array 
geschrieben und der Timer(interrupt) sorgt im Hintergrund dafuer, dass 
es auf die Anzeige kommt.

von Karl H. (kbuchegg)


Lesenswert?

Markus W. schrieb:
> Hallo Uwe,
>
> das Display hat ja acht davon - ist ja eine fertige Platine.
> Wollte eigentlich nur das Ansteuern üben.
>
Wo siehst du 8?
Ich seh am Photo nur 2 IC vom Typ 595.
Und damit ist alles klar. Denn mit 2 Stueck 595 hab ich nur 16 
Ausgaenge. Damit ist es aber nicht moeglich 8 Stueck 7 Segment statisch 
anzusteuern. Viel zu wenige Pins. 64 wuerde man brauchen, 16 hat man. 
Passt hinten und vorne nicht

: Bearbeitet durch User
von m.n. (Gast)


Lesenswert?

Markus W. schrieb:
> Ist leider für meine Anwendung nicht sehr praktikabel, weil zu viel
> Störungen durch die Impulse auf den Leitungen erzeugt werden.

Ein Beispiel für eine statische Ansteuerung, die kaskadierbar ist:
Beitrag "7-Segm.-LED-Anzeige, 6-stellig, statische Ansteuerung mit (74HC)4094"

von Markus W. (dl8mby)


Lesenswert?

Hallo Karl-Heinz,
hallo Forum,

danke für Deine/Eure Anregungen und Hinweise.
Die Technik des Buffer füllen und das Transferieren
im Hintergrund zur Anzeigeeinheit aka Overlay der
Bildschirmspeicher ist mir schon lange bekannt.
Da uC Programmierung nicht mein Metier ist und ich
das nur zu Hobby-Zwecken betreibe, kann ich nicht
sofort einen super optimierten Code aus dem Ärmel
schütteln ;-)
Da ich mich sowohl mit der IDE aus auch mit dem
Ansteuerprotokoll auseinandersetzen musste, wollte
ich die Sache nicht sofort noch mit Timern und ISR
verkomplizieren.
Es ging mir nur darum zu verstehen, wie das Display
angesteuert wird und da ist meineserachtens sinnvoll
jedes Bit selber zu bedienen um zu verstehen wie das
Interface funktioniert.
Zu der durchdachten und sauberen Lösung bin ich ja noch
gar nicht gekommen, da ich ja bereits bei den banalen
Dingen hängen geblieben bin.

Zudem habe ich einige Zeit aufgewendet um Überhaupt die
Steuersequenzen für die Displayansteuerung zu ermitteln.

Leider bietet die LunaAVR IDE nicht für alle 7-Segment
Möglichkeiten die Bitmuster-Generierung via Editor an, so
dass ich sie für meinen Fall selber aufskizieren musste.

Bei meinem Display sind die Segment bei Low-Pegel aktiv und der
DP steht an erster und nicht an letzter Stelle.

So sehen meine Bitmuster für die Anzeige wie folgt aus:

#define DIG0 as 0x03
#define DIG1 as 0x9F
#define DIG2 as 0x25
#define DIG3 as 0x0D
#define DIG4 as 0x99
#define DIG5 as 0x49
#define DIG6 as 0x41
#define DIG7 as 0x1F
#define DIG8 as 0x01
#define DIG9 as 0x09
#define DIGA as 0x11
#define DIGb as 0xC1
#define DIGC as 0x63
#define DIGd as 0x85
#define DIGE as 0x61
#define DIGF as 0x71
#define DIGH as 0x91
#define DIGL as 0xE3
#define DIGP as 0x31
#define DIGU as 0x83
#define DIG_c as 0xE5
#define DIG_n as 0xD5
#define DIG_o as 0xC5
#define DIG_u as 0xC7

Weder der LunarAVR 7-Segment-Editor noch dei Beispiele im
MC-Forum waren kompatibel.

Kennt Ihr andere Programme, die diese Arbeit vereinfachn
und mehrere Variationen unterstützen, wie die drei genannten.


Gruß
Markus

von Karl H. (kbuchegg)


Lesenswert?

Markus W. schrieb:

> Zudem habe ich einige Zeit aufgewendet um Überhaupt die
> Steuersequenzen für die Displayansteuerung zu ermitteln.
>
> Leider bietet die LunaAVR IDE nicht für alle 7-Segment
> Möglichkeiten die Bitmuster-Generierung via Editor an, so
> dass ich sie für meinen Fall selber aufskizieren musste.

Du bist so arm.
Schon interessant, welche Trivialitaeten heutzutage als Problem 
angesehen werden, fuer die man ein Spezialprogramm braucht, fuer die die 
Profis einfach Papier und Bleistift hernehmen.
Wie soll das Zeichen aussehen? Welches der 7 Segmente soll daher 
leuchten? Bits addieren und schon ist das Steuerbyte fertig. Dauert 
keine 20 Sekunden pro Zeichen.

von Markus W. (dl8mby)


Lesenswert?

Hallo Karl-Heinz,

arm ist ein relativer Begriff.

Wenn Du meine Posting aufmerksam gelesen hättest
und nicht nur überflogen, so wäre Dir doch aufgefallen,
das ich es mit Papier und Bleistift gemacht habe ;-)

>"dass ich sie für meinen Fall selber aufskizieren musste."


Mich hat es mit kleinen Unterbrechungen etwa zwei Stunden gekostet.
Aber auch Zeit ist etwas relatives.

Gruß
Marksu

von Route_66 H. (route_66)


Lesenswert?

Karl H. schrieb:
> Wie soll das Zeichen aussehen? Welches der 7 Segmente soll daher
> leuchten? Bits addieren und schon ist das Steuerbyte fertig.

Wenn man das Steuerbyte binär notiert, gibt es weniger Fehler und man 
muß nicht addieren. Die Segmentbelegungstabelle ist direkt sichtbar.

von Karl H. (kbuchegg)


Lesenswert?

Route 6. schrieb:
> Karl H. schrieb:
>> Wie soll das Zeichen aussehen? Welches der 7 Segmente soll daher
>> leuchten? Bits addieren und schon ist das Steuerbyte fertig.
>
> Wenn man das Steuerbyte binär notiert, gibt es weniger Fehler und man
> muß nicht addieren. Die Segmentbelegungstabelle ist direkt sichtbar.

Da kann ich mich in LunaAVR zu wenig aus, um zu wissen welche 
Möglichkeiten es gibt.
Fakt ist: Habe sowas im Frühjahr mit meinem Neffen gemacht, als wir 7 
Segment Anzeigen besprochen haben. Die ersten 2 hab ich ihm gezeigt, die 
nächsten 3 hat er mit Papier und Bleistift niedergeschrieben, die 
restlichen hat er im Kopf als Hex-Zahl zusammengesetzt. Alles in allem 
keine 10 Minuten. Und da ist das praktische bestimmen welches Bit zu 
welchem Segment gehört schon mit drinn. Nach 2 Stunden war die Uhrzeit 
vom DCF Modul auf der nach den Regeln der Kunst gemultiplexten 4 
stelligen Anzeige zu lesen.

: Bearbeitet durch User
von Route_66 H. (route_66)


Lesenswert?

Karl H. schrieb:
> Da kann ich mich in LunaAVR zu wenig aus, um zu wissen welche
> Möglichkeiten es gibt.

z.B. so: (LunaAVR)


data tab7seg
  '7 segment table common anode
  '****** Siebensegmenttabelle
  'Bits    7 6 5 4 3 2 1 0
  'Segment A B C D E F G dP
  'Segment leuchtet bei Low

  .db 0b00000011  '0
  .db 0b10011111  '1
  .db 0b00100101  '2
  .db 0b00001101  '3
  .db 0b10011001  '4
  .db 0b01001001  '5
  .db 0b01000001  '6
  .db 0b00011111  '7
  .db 0b00000001  '8
  .db 0b00000101  '9
  .db 0b00010001  'A
  .db 0b11000001  'b
  .db 0b01100011  'C
  .db 0b10000101  'd
  .db 0b01100001  'E
  .db 0b01110001  'F
enddata

von Peter D. (peda)


Lesenswert?

Ich ordne die Segmente fürs Layout passend an:
1
#define _A      0x40
2
#define _B      0x20
3
#define _C      0x10
4
#define _D      0x08
5
#define _E      0x04
6
#define _F      0x02
7
#define _G      0x01
8
#define _DP     0x80
9
10
#define _0      _A+_B+_C+_D+_E+_F
11
#define _1         _B+_C
12
#define _2      _A+_B+   _D+_E+   _G
13
#define _3      _A+_B+_C+_D+      _G
14
#define _4         _B+_C+      _F+_G
15
#define _5      _A+   _C+_D+   _F+_G
16
#define _6      _A+   _C+_D+_E+_F+_G
17
#define _7      _A+_B+_C
18
#define _8      _A+_B+_C+_D+_E+_F+_G
19
#define _9      _A+_B+_C+_D   +_F+_G
20
#define CHAR_E  _A+      _D+_E+_F+_G
21
#define CHAR_r              _E+   _G
22
#define MINUS                     _G
23
#define SPACE   0

von Route_66 H. (route_66)


Lesenswert?

@peda
Viele Wege führen nach ROM. Für Siebensegment it Deine Lösung sicher 
auch nicht schlecht, aber für sowas ist binär einleuchtender:

;----------------------------------------------------------------------- 
-
;
;  Zeichengenerator-Tabelle 5 mal 7 Matrix
;
;----------------------------------------------------------------------- 
-
zg_5x7:
  .DB  00000000B  ;20H => Space
  .DB  00000000B
  .DB  00000000B
  .DB  00000000B
  .DB  00000000B


  .DB  00000000B  ;21H => !
  .DB  00000000B
  .DB  01011111B
  .DB  00000000B
  .DB  00000000B

  .DB  00000000B  ;22H => "
  .DB  00000111B
  .DB  00000000B
  .DB  00000111B
  .DB  00000000B

  .DB  00010100B  ;23H => #
  .DB  01111111B
  .DB  00010100B
  .DB  01111111B
  .DB  00010100B

  .DB  00100100B  ;24H => $
  .DB  00101010B
  .DB  01111111B
  .DB  00101010B
  .DB  00010010B

  .DB  00100011B  ;25H => %
  .DB  00010011B
  .DB  00001000B
  .DB  01100100B
  .DB  01100010B

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.