74HC595 wie steuert man das latch an?

Gast #338398
Lesenswert?

Hallo erstmal!

Ich möchte mich mit dem 74HC595 beschäftigen. Leider hab ich noch nie
zuvor was mit schieberegistern gemacht. Nun zu miener frage, das latch
ist ja so etwas wie ein datenvorbereiter - wie steuer ich das ein? ist
das einlesen wie beim normalen schieberegister oder anders?

gruss Andreas
Gast #338399
Lesenswert?

>datenvorbereiter

was soll das sein?

Sobald man eine positive Flanke auf ST_CP sorgt dafür, dass die Daten
an die Ausgänge "durchgereicht" werden.
Sonst funktioniert das Ding wie ein "normales" Schieberegister.
Gast #338400
Lesenswert?

Hallo

mit jedem Clock wird das serielle Eingangssignal intern ein Register
weitergeschoben. Nach 8 Takten ist ein Byte im Register.
Durch den Übernahmetakt werden die Daten in das Ausgangsregister
übernommen und stehen an den Ausgängen zur Verfügung.
Gast #338401
Lesenswert?

ah okay. also schreibe ich in das register rein, setze den clock, dann
geht das in den latch. ich schreib weiter ins register, setze wieder n
clock, dann wird das vom latch ausgegeben und die daten wieder ins
latch. Richtig so?
Gast #338402
Lesenswert?

ja, wobei man natürlich zwei Clocks braucht: die eine um die Bits ins
Register zu schieben und die andere um die Daten dann auszugeben.
Für solche Sachen ist die (Hard-)SPI wunderbar zu gebrauchen...
Gast #338404
Lesenswert?

SH_CP (Pin 11): Shift Clock (Schiebetakt)
ST_CP (Pin 12): Store Clock (Speichertakt)
Beide reagieren auf positive Flanke. Der Output Enable (/OE, Pin 13)
muss auf GND liegen, damit die Werte im Latch an die Ausgänge
ausgegeben werden. Master Reset (Pin 10) muss HIGH-Pegel haben.
Gast #338405
Lesenswert?

okay, damit ich das nun richtig versteh (kleine zeichnung ;-) )

ds -----|---------|   Also zum daten einzuspeisen schieb ich diese
SH_CP---| state   |   durch 'ds' ins schiebe r4egister. in diesem
MR------| register|   Moment muss MR high sein. nachdem ich meine
        |---------|   Daten ins Regiter geschrieben hab, geb ich SH_CP
          ||||||||    einen highimpuls und nun ist alles im storage-
        |---------|   register. ich screibe weiter ins state register
        | storage |   und geb nun SH_CP und ST_CP einen highimpuls.
ST_CP---| register|   state register wird zu storage register.
        |---------|
          ||||||||    wenn ich nun oe auf low setzte, gibt es den wert
        |---------|   vom storage register aus, oder? muss der OE bis
        |         |   auf den moment der ausgabe immer auf high sein?
OE------|         |
        |---------|
          ||||||||
         (Ausgänge)
Gast #338406
Lesenswert?

/OE muss für die Ausgabe immer low sein (zeigt auch der "/"
davor/darüber an [lowactive]).

Um die Daten überhaupt erst ins Register zu bekommen, musst du für
jedes Bit eine Taktflanke an SH_CP legen (8Bit ==> 8 Takte)
Wenn dann alle 8 Bits übertragen wurden, gibts du noch eine Taktflanke
auf ST_CP und die Daten werden auch ausgegeben.
Um die Daten im Register zu löschen, zieht man /MR auf low.
Gast #338407
Lesenswert?

Der /MR ist leider vollkommen sinnlos, das er nicht auf das
Ausgaberegister wirkt. Das Ausgaberegister hat nach dem Einschalten
irgendeinen zufälligen Wert.

Daher mache ich es so, daß der MC den /OE auf high hält, bis ein
gültiges Datenbyte reingeschoben und übernommen wurde. Dadurch kann es
nicht passieren, daß Verbraucher am Ausgang versehentlich an gehen und
Schaden anrichten.


Peter
Gast #338408
Lesenswert?

/MR low und eine positive Flanke an ST_CP, und die Ausgänge sind aus.
Ein RC-Glied an /OE könnte helfen, wenn man sich den Pin sparen will.
(Prinzipielle könnte man das doch auch mit 3 RC-Gliedern machen, die
unterschiedliche tau haben...)
Gast #338409
Lesenswert?

also so?

Daten: --1---2---3---4---5---6---7---8---1---2---3---4---5---6---7
            _   _   _   _   _   _   _   _   _   _   _   _   _   
SH_CP: _|1|_|2|_|3|_|4|_|5|_|6|_|7|_|8|_|1|_|2|_|3|_|4|_|5|_|6|_|7|_
                                     _
ST_CP:______________________________| |_____________________________
      _______________________________   __________________________
/MR  :                                |_|

Den master Reset sollte ich doch 1/2 takt später erst auslösen oder?
Gast #338411
Lesenswert?

Im angehängten Datenblatt von Philips auf Seite 3 ist die Tabelle, die
keine Fragen offen lässt. Wenn Du das Storage Register zurücksetzen
willst, musst Du zuerst den /MR auf LOW (Masse) ziehen und DANN eine
positive Flanke an ST_CP erzeugen. Der /MR löscht nämlich das
Schieberegister und die positive Flanke auf ST_CP lädt das leere
Schieberegister ins Storage Register...
Angehängte Dateien:
Gast #338412
Lesenswert?

@Rahul,

"(Prinzipielle könnte man das doch auch mit 3 RC-Gliedern machen, die
unterschiedliche tau haben...)"

RC-Glieder haben den Nachteil der Unzuverlässigkeit, da sie genügend
lange Entladepausen benötigen, also wäre es sicherer einen ATTiny13
dafür abzustellen.

Man kann den Aufwand natürlich beliebig hoch treiben

Nur einen Ausgangspin mit Pullup am /OE finde ich am zuverlässigsten
und ökonomischten.


Peter
Gast #338413
Lesenswert?

Die Daten sollten vor der positiven Flanke anliegen. Ansonsten sieht es
sinnvoll aus.

@Johnny: Das Datenblatt wollte ich auch irgendwann anhängen...

Das Storage-Register muß man ja nur einmal ganz zu Beginn des Programms
löschen.
Alle weiteren resets vereinfachen den Ablauf...
Gast #338416
Lesenswert?

@johnny.m
wenn ich aber gleich das speicherregister mit den neuen daten
überschreibe brauch ich doch das garnicht zu löschen, odeR? ich gab ja
erst dann den neuen wert aus, wenn ich auch die daten dafür im
state-register komplett geladen hab.

hab ich bis jetzt n denk fehler gemacht oder stmmt das was ich sag?
Gast #338419
Lesenswert?

ich hab in meiem programm die Variable "test" sie zeigt wieviel LEDs
leuchten sollen. PortA gibt diese anzahl in binärwerten raus. Ich
benötige dafür 5 bit. Wie bekomme ich nun diesen wert richtig in mein
schieberegister. Wie es aussieht benötige ich hier 3 register.
Gast #338421
Lesenswert?

Das mit dem Einschaltverhalten spielt für Hobbyanwendungen oft keine
Rolle.

Aber wenn ein Kranführer den Hauptschalter umdreht und der
Auslösemagnet kriegt für 10ms Strom, dann fällt Dir das Betonelement
auf den Kopf und Du bist Matsch.

Die CPU macht derweil gemütich ihren Reset, und schaltet irgendwann den
Magneten wieder ab. Bloß davon wird aus dem Matsch nicht wieder ein
Mensch.


Peter
#338422
Lesenswert?

Indem du genau das was du bisher rausgefunden hast
anwendest.

Dein Schieberegister ist wie breit? Sagen wir mal 16 Bits.
Wenn du 4 Leds einschalten willst, musst du daher 12 Leds
ausschalten, damit du in Summe immer 16 Leds bedienst.

Also muessen zunaechst mal 12 0-en rausgeschoben werden

  0 an die Datenleitung zum Schieberegister
  12 mal ein Taktsignal an SH_CP

  dann eine 1 an die Datenleitung zum Schieberegister
  4 mal ein Taktsignal an SH_CP

  jetzt sind alle 16 Bits im State-Register richtig
  gesetzt und daher kann das State-Register in das
  Storage-Register übernommen werden. Ein Taktsignal
  an ST_CP macht genau das.

  Zu guter letzt: da das Storage-Register gültige
  Werte enthält, können die auch ausgegeben werden.
  Das OE-Signal auf low ziehen macht genau das: Es gibt
  die Ausgänge des Chips frei. Zum Testen kannst du auch
  OE einfach ständig auf low liegen lassen.

Ich empfehle dir auch: Mach ein eigenes Testprogram dafür
und vergiss zunächst mal das Pgm an dem du arbeitest. Mit
dem Testprogramm klärst du nur ab, wie so ein Schieberegister
arbeitet und kannst damit rumspielen. Das ganze ist einfacher
als du denkst, wenn du das Testprogram so gestaltest, dass die
Aktionen nicht allzu schnell ablaufen und du mit einem Multi-
meter die einzelnen Pegel messen kannst, dann hast du das
in weniger als 10 Minuten am laufen.
#338426
Lesenswert?

switch - case  dürften deine Lieblinge sein :-)

Im Ernst: Ich kann BASCOM nicht, aber das ding kann auch
Schleifen

  Reset Porta.0                                             '0
    Set Porta.5
    Reset Porta.5
  Reset Porta.0                                             '0
    Set Porta.5
    Reset Porta.5
  Reset Porta.0                                             '0
    Set Porta.5
    Reset Porta.5
  Reset Porta.0                                             '0
    Set Porta.5
    Reset Porta.5
  Reset Porta.0                                             '0
    Set Porta.5
    Reset Porta.5
  Reset Porta.0                                             '0
    Set Porta.5
    Reset Porta.5
  Reset Porta.0                                             '0
    Set Porta.5
    Reset Porta.5
  Set Porta.0

das ist mächtig kompliziert für:

  for i = 1 to 7
    Reset PortA.0
    Set PortA.5
    Reset PortA.5
  next

  for i = 1 to 1
    Set PortA.0
    Set PortA.5
    ResetPortA.5
  next


(Beachte auch: erst das Datenbit setzen, dann mit
dem Clock Signal wackeln. Wo bitte wackelt dein Code
mit dem Clock Signal nachdem er PortA.0 auf 1
gesetzt hat?)


der Grund warum ich den Fall 1 setzen ebenfalls in
eine Schleife gepackt habe, ist, dass du dann hoffentlich
fuer die anderen Faelle verallgemeinerst. Wenn du 3 leds
einschalten musst, wie muss dann die erste Schleife laufen?
wie muss die 2-te Schleife laufen?

Hmm. Du hast 8 Bits insgesammt, 3 davon sollen leuchten,
also sollen 8 - 3 -> 5 leds nicht leuchten

Also ist die Verallgemeinerung

Sub Led_anzeigen
  for i = 1 to 8 - Led
    Reset PortA.0
    Set PortA.5
    Reset PortA.5
  next

  for i = 1 to Led
    Set PortA.0
    Set PortA.5
    ResetPortA.5
  next
end Sub

Wow. Nicht schlecht. Deine 187 Zeilen kompremiert auf 10.
Du solltest dir auch gleich Literatur zum Thema Bascom beschaffen.

Übrigens gibt es da noch eine naheliegende Vereinfachung, die
Laufzeit einspart. Aber die sollst du selbst suchen.  Hinweis:
Ist es wirklich notwendig innerhalb der Schleife PortA.0 immer
wieder neu zu besetzen?
Gast #338427
Lesenswert?

also über deine genialität muss ich erst mal staunen - ich denk
irgendwie noch zu linear, nehm ich an.

Wenn ich das programm so schreb:

Do
Incr Led
If Led = 9 then
  Led = 0
  Porta.0 = 255
end if
Call Led_anzeige
  Set PortA.6
  Reset PortA.6
  Set PortA.4
  Reset PortA.4

Sub Led_anzeige
  For I = 1 to 8 - Led
    Reset PortA.0
    Set PortA.5
    Reset PortA.5
  Next
End Sub

...dann setz ich ja bei jedem durchlauf, wo ich ide Variable Led zurück
setzt auch PortA wieder auf high.
oder dachtest du dir das anders?

Oh man, ich glaub so n Bscom buch wär mal garnicht so schelcht

Grüsse Andy
#338428
Lesenswert?

> ...dann setz ich ja bei jedem durchlauf, wo ich ide Variable Led
> zurück setzt auch PortA wieder auf high.

Schon. Aber wozu?

Du musst anfangen, die Dinge zu trennen.
Die Sub Led_anzeigen hat das Recht sich an den Pins
für das Schieberegister zu vergreifen. Ausser der Sub
Led_anzeigen haben gefälligst alle anderen Programmteile
die Finger davon zu lassen (von der Initialisierung
die den Port in einen definierten Zustand bringt mal abgesehen).

Das ist eines der wichtigsten Konzepte in der ganzen
Programmierung: Funktionalität dorthin bringen wo sie
hingehört und alle anderen Programmteile lassen die Finger
davon. In Deinem Fall: Kein anderer Programmteil als Led_anzeigen
hat das Recht an den Port Pins A0 und A5 (und irgendeiner wird
noch für die Übernahme im SR verantwortlich sein) rumzupfuschen.
Zuwiderhandlung wird mit Strafe bedroht.
Also hat der Teil da oben, gar nicht das Recht den kompletten
Port A auf 255 zu setzen. Er hat es einfach nicht. Der Basic
Compiler kann das nicht durchsetzen, dazu fehlt es BASCOM an
Sprachmitteln. In anderen Programmiersprachen könnte man das.
Da das in BASCOM nicht durchsetzbar ist, musst du als Programmierer
dich an diese Konvention halten.
Gast #338429
Lesenswert?

Ja, wenn ich drüber nach denke (und das hab ich gestern nochmal nach der
arbeit) war das n fataler fehler! Ich hab gestern noch ein programm
entworfen (mit LCD unterstützung zur kontrolle) Ich weiss aber nicht
wie es kürzer geht... naja ich hängs mal an und es funktioniert sogar!

Andreas
Angehängte Dateien:
Gast #338430
Lesenswert?

"und es funktioniert sogar!"

Das würde mich stark wundern.
Du benutzt verschiedene Dateneingänge, was unnötig ist. Einfach die
74HC595 hintereinander schalten.

Aber Du benutzt den selben Takt, d.h. sobald Du in eins was
reinschiebst, schiebst Du aus den anderen wieder alles raus.


Mache es doch so, wie ich vorgeschlagen hatte, einfach 32-mal schieben
mit Abwärtszaähler und dann den Datenpin auf 1 setzen, wenn der Zähler
mit der gewünschten Anzahl Einsen übereinstimmt. Und das Latchen nicht
vergessen (fehlt bei Dir).


Kann man in Basic nicht auch Namen für Pins vergeben ?

Woher soll man immer wissen, was Pina.4 usw. ist.


Peter
#338431
Lesenswert?

@Andreas

Sag mal: Wie alt bist du eigentlich?

Was soll der Riesen-case da wieder im Pgm?
Du wirst doch wohl noch einen mathematischen Zusammenhang
in Form einer Formel in der Tabelle

Drehzahl  |  Aa     Ab
----------+-------------
  0       |   0      8
  1       |   1      7
  2       |   2      6
  3       |   3      5
  4       |   4      4
  5       |   5      3
  6       |   6      2
  7       |   7      1
  8       |   8      0

finden. Also 'Drehzahl' vorgegeben, wie gross
ist Aa? Wie gross ist Ab?
Jeder Volksschüler findet den in unter 2 Minuten

Ansonsten gilt natürlich alles das was peter schon
angemerkt hat: Warum schaltest du die Schieberegister
nicht einfach hintereinander, so wie das vom Chip-
Hersteller vorgesehen ist und kriegst damit ein 32
Bit breites Schieberegister. Das ist ja gerade einer
der Clou's von Schieberegistern, dass man sie auch
im Nachhinein noch kaskadieren kann und somit breiter
machen kann, ohne dass man am µC mehr Portpins
benötigt.
Gast #338432
Lesenswert?

wie mach ich das dann mir dem latch? ich möchte die schieberegister so
lassen, denn so ist es für mich übersichtlich und das mit dem
kaskadieren hab ich nicht verstanden!
das fazit von dir ist also das latch nicht verwendet und nicht
kaskadiert.
ich wüsste nicht, dass man pins zu vatiablen umbnennen kann. und oben
ist auch angegeben welcher pin für was steht ;-) hab zwar nicht an
alles gedacht doch an einiges.

Andreas
Gast #338433
Lesenswert?

ich weiss schon wie das funktioniert, deswegen hab ich das auch so
geschrieben! doch ich bin noch nicht so geübt in sachen schleifen und
so was! wenn ich mal was programmieren muss, was jetzt in meine 3jahren
der ausbildung leider nicht so oft der fall war, musste ich mir selbst
beibringen wie was funktioniert. dass ich da eben nicht so tricks kann
ist ja wohl klar!

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