Hey Leute, ich hoffe ich bin hier richtig gelandet, mit dem Thema. Ich habe folgendes vor. Ich habe mehrere Schieberegister (CMOS 4049) hintereinander kaskadiert. Möchte nun diese Bitweise füllen. Also beim ersten übertragen der Daten wird 1 Bit übertragen, beim zweiten übertragen von Daten wird 1 Bit nach geschoben. Also Bit 1 und 2 bildet ein High. Kann mir jemand helfen wie ich das machen kann? Habe folgendes versucht zum einen mit Addieren von Binärzahlen also &B00000001 + &B00000001 und dann übertragen, klappte nicht. Danach hab ichs versucht einfach immer wieder &B00000001 zu übertragen, klappte auch nicht. Dann versuchte ich Dezimal 1 zu übertragen, klappte auch nicht. Nun bin ich so langsam leicht am verzweifeln. Vielleicht kann mir einer von euch helfen. Das wichtigste ist auch, dass kein zweites Schieberegister nach und nach gefüllt werden soll, solange Register 1 nicht an ist. Falls es wen interessiert es sind 8 Register hintereinander und es sollen 60 LEDs angezeigt werden. Und nach dem die 60te LED angezeigt wurde soll nach nem Timer die Anzeigen wieder gelöscht werden. Ich hoffe mir sagt nun niemand, ich muss ein Array erzeugen mit 60 einzellnen Bitzahlen. Hoffe da gibt es eine einfachere Möglichkeit. Michael
Die kann man nicht bitweise füllen.Das geht nur mit I2C porterweiterung. Ausserdem hat der 4049 keine Latch, das bedeutet wenn du die bits schiebst ändern sich auch die pinzustände sofort.Das würde dazu füren das die Leds der Reihe nach kurz aufleuchten würden bei jedem Schiebevorgang.
Da kann ich leicht wiedersprechen. Wenn ich den Strobe auf 0 setze vor dem Schreiben und dann wieder auf 1 Setze aktiviert er erst dann alle übertragenen Bits. Habe das schon mit 2 Stck. 7 Segmentanzeigen schon gemacht. Also er zählte mir so dann die von 0 bis auf 99 Hoch. Und das ohne Flackern oder so wärend der übertragung. Alles lief einwandfrei rüber. Nur wenn es nicht Bit weise geht, wie kann man sowas am besten machen? Also das man Bit 1 bis 60 nach und nach füllt. Also erst Bit 1, dann Bit 2, dann Bit 3, usw. Michael
Ganz einfach, ein byte sind 8 bits.Also nehmen wir an, du wilst bit 3 setzen.Du schiebs dann 00010000 und dann die Strobe high.
Ich habe jetzt nachgesehen und 4049 ist überhaupt kein Schieberegister, sondern ein hex buffer.
Wenn du doch noch ein richtiges Schieberegister findest, dann kannst du dir 8 Byte im SRAM reservieren. Das sind 64Bit. Falls dass eine Uhr werden soll, dann musst du bei jeder Änderung der Zeit immer wieder alle 64Bit ändern und durch alle Register schieben. Hab auch schon eimal eine Uhr mit 7-Segment Anzeigen aus LED für Minute und Stunde gebaut mit einem Sekundenring drumherum. (Studiouhr) Steffen
hey, ich wollte mal nachharken wieso man hier äußert dass es keines wäre. Wird doch im dem Onlineshop vom Großen C z.B. Als "speicher und schiebebus" definiert. Und für mich hört es sich nach schieberegister an. Bzw in der fachliteratur wird der Baustein 4094 auch als schieberegister tituliert. Wenn das keiner wäre. Was wäre den dann einer? Und wegen dem Bitmuster oben für die 3 muss ich wiedersprechen. Der wert würde wie folgt aussehen in Bascom &B00000100 für 3ten bit gesetzt und sonst im Binärsystem wäre 00000011 eine 3. stefan
Stefan schrieb: > Bzw in der fachliteratur wird der Baustein 4094 auch als > schieberegister tituliert. Der 4094 schon, oben war aber von einem 4049 die Rede. > Und wegen dem Bitmuster oben für die 3 muss ich wiedersprechen. Der wert > würde wie folgt aussehen in Bascom &B00000100 für 3ten bit gesetzt und Ich habe keine Ahnung von Bascom, aber in der restlichen Welt werden die Bits ab 0 gezählt -> b00001000 Thomas
Die Verwechslung 4094 und 4049 ist ja schon geklärt. Ich hab aber Probleme Deine Frage zu verstehen, wo war die eigentlich: >Möchte nun diese Bitweise füllen. Also beim >ersten übertragen der Daten wird 1 Bit übertragen, beim zweiten >übertragen von Daten wird 1 Bit nach geschoben. Also Bit 1 und 2 bildet >ein High. Warum bilden Bit 1 und Bit 2 ein High?
chick schrieb: > Die Verwechslung 4094 und 4049 ist ja schon geklärt. > > Ich hab aber Probleme Deine Frage zu verstehen, wo war die eigentlich: > >>Möchte nun diese Bitweise füllen. Also beim >>ersten übertragen der Daten wird 1 Bit übertragen, beim zweiten >>übertragen von Daten wird 1 Bit nach geschoben. Das versteh ich jetzt auch nicht ganz. Aber egal was du an Bitkombinationen übertragen/ändern willst, du musst immer die ganzen 60Bit (64Bit) in die Register schieben. Also Bit 1 und 2 bildet >>ein High. > > Warum bilden Bit 1 und Bit 2 ein High? Er meint dass es jeweils eine '1' ist.
Ohne jetzt Dein Schieberegister genau zu kennen.... In Bascom könnte man in etwa so etwas programmieren (ohne Hardware-SPI): 3 Ports: SER, SCK und RCK siehe: http://www.mikrocontroller.net/articles/AVR-Tutorial:_Schieberegister
1 | ... |
2 | Shiftout SER, SCK, Byte_x, 0 'evtl. auch 1 oder 2, siehe BASCOM_Hilfe |
3 | Shiftout SER, SCK, Byte_x-1 |
4 | ... |
5 | Shiftout SER, SCK, Byte_0, 0 |
6 | |
7 | RCK = 0 |
8 | RCK = 1 |
9 | RCK = 0 |
10 | .... |
Danke bis hier hin.
Habe eine Lösung, die ich bei 2 Scheiberegister getestet habe und nur
diesmal nun zumindest im Code auf 8 Register erweitert.
Und danke Stefan, joa hab mich da irgendwie vertippt, also wegen der
Chipbezeichnung.
Den Code packe ich gleich unten dran. Den an sich gibt es leider ein
Problem, dass meine Lösung ein wenig sehr Speicher verbraucht und dabei
erstmal nur 1 Ring mit Sekunden anzeigt. Also wenn Minuten und Stunden
noch hinzu kommen müsste ich bei meiner Lösung mindestens ein ATMega16
nehmen.
Vielleicht kann mir jemand eine Lösung verraten bzw.
Verbesserungsvorschlag für meine Lösung.
Michael
Und hier der code:
==================
$regfile = "m8def.dat"
$crystal = 9600000
$hwstack = 32
$swstack = 4
$framesize = 4
Config Portb.2 = Output
Config Portb.1 = Output
Config Portb.0 = Output
Strobe Alias Portb.2
Daten Alias Portb.1
Clock Alias Portb.0
Strobe = 0
Daten = 0
Clock = 0
Dim Dis(9) As Byte
Dim Isec As Integer
Dim Imin As Integer
Dim Ihou As Integer
Dim Csec As Integer
Dim Cmin As Integer
Dim Chou As Integer
'Bit-Muster Array
Dis(1) = &B00000001
Dis(2) = &B00000011
Dis(3) = &B00000111
Dis(4) = &B00001111
Dis(5) = &B00011111
Dis(6) = &B00111111
Dis(7) = &B01111111
Dis(8) = &B11111111
Dis(9) = &B00000000
'Schieberegister leeren beim Start
Shiftout Daten , Clock , Dis(9) , 1
Shiftout Daten , Clock , Dis(9) , 1
Shiftout Daten , Clock , Dis(9) , 1
Shiftout Daten , Clock , Dis(9) , 1
Shiftout Daten , Clock , Dis(9) , 1
Shiftout Daten , Clock , Dis(9) , 1
Shiftout Daten , Clock , Dis(9) , 1
Shiftout Daten , Clock , Dis(9) , 1
Strobe = 1
Do
Isec = 1
For Isec = 1 To 16
Strobe = 0
Select Case Isec
Case 1 To 8: 'Sekundenanzeige von 1-8
Shiftout Daten , Clock , Dis(9) , 1
Shiftout Daten , Clock , Dis(9) , 1
Shiftout Daten , Clock , Dis(9) , 1
Shiftout Daten , Clock , Dis(9) , 1
Shiftout Daten , Clock , Dis(9) , 1
Shiftout Daten , Clock , Dis(9) , 1
Shiftout Daten , Clock , Dis(9) , 1
Shiftout Daten , Clock , Dis(isec) , 1
Case 9 To 16: 'Sekundenanzeige von 9-16
Csec = Isec - 8
Shiftout Daten , Clock , Dis(9) , 1
Shiftout Daten , Clock , Dis(9) , 1
Shiftout Daten , Clock , Dis(9) , 1
Shiftout Daten , Clock , Dis(9) , 1
Shiftout Daten , Clock , Dis(9) , 1
Shiftout Daten , Clock , Dis(9) , 1
Shiftout Daten , Clock , Dis(csec) , 1
Shiftout Daten , Clock , Dis(8) , 1
Case 17 To 24: 'Sekundenanzeige von 17-24
Csec = Isec - 16
Shiftout Daten , Clock , Dis(9) , 1
Shiftout Daten , Clock , Dis(9) , 1
Shiftout Daten , Clock , Dis(9) , 1
Shiftout Daten , Clock , Dis(9) , 1
Shiftout Daten , Clock , Dis(9) , 1
Shiftout Daten , Clock , Dis(csec) , 1
Shiftout Daten , Clock , Dis(8) , 1
Shiftout Daten , Clock , Dis(8) , 1
Case 25 To 32: 'Sekundenanzeige von 25-32
Csec = Isec - 24
Shiftout Daten , Clock , Dis(9) , 1
Shiftout Daten , Clock , Dis(9) , 1
Shiftout Daten , Clock , Dis(9) , 1
Shiftout Daten , Clock , Dis(9) , 1
Shiftout Daten , Clock , Dis(csec) , 1
Shiftout Daten , Clock , Dis(8) , 1
Shiftout Daten , Clock , Dis(8) , 1
Shiftout Daten , Clock , Dis(8) , 1
Case 33 To 40: 'Sekundenanzeige von 33-40
Csec = Isec - 32
Shiftout Daten , Clock , Dis(9) , 1
Shiftout Daten , Clock , Dis(9) , 1
Shiftout Daten , Clock , Dis(9) , 1
Shiftout Daten , Clock , Dis(csec) , 1
Shiftout Daten , Clock , Dis(8) , 1
Shiftout Daten , Clock , Dis(8) , 1
Shiftout Daten , Clock , Dis(8) , 1
Shiftout Daten , Clock , Dis(8) , 1
Case 41 To 48: 'Sekundenanzeige von 41-48
Csec = Isec - 40
Shiftout Daten , Clock , Dis(9) , 1
Shiftout Daten , Clock , Dis(9) , 1
Shiftout Daten , Clock , Dis(csec) , 1
Shiftout Daten , Clock , Dis(8) , 1
Shiftout Daten , Clock , Dis(8) , 1
Shiftout Daten , Clock , Dis(8) , 1
Shiftout Daten , Clock , Dis(8) , 1
Shiftout Daten , Clock , Dis(8) , 1
Case 49 To 56: 'Sekundenanzeige von 49-56
Csec = Isec - 48
Shiftout Daten , Clock , Dis(9) , 1
Shiftout Daten , Clock , Dis(csec) , 1
Shiftout Daten , Clock , Dis(8) , 1
Shiftout Daten , Clock , Dis(8) , 1
Shiftout Daten , Clock , Dis(8) , 1
Shiftout Daten , Clock , Dis(8) , 1
Shiftout Daten , Clock , Dis(8) , 1
Shiftout Daten , Clock , Dis(8) , 1
Case 57 To 60: 'Sekundenanzeige von 57-60
Csec = Isec - 56
Shiftout Daten , Clock , Dis(csec) , 1
Shiftout Daten , Clock , Dis(8) , 1
Shiftout Daten , Clock , Dis(8) , 1
Shiftout Daten , Clock , Dis(8) , 1
Shiftout Daten , Clock , Dis(8) , 1
Shiftout Daten , Clock , Dis(8) , 1
Shiftout Daten , Clock , Dis(8) , 1
Shiftout Daten , Clock , Dis(8) , 1
End Select
Strobe = 1
Waitms 100
Next
Loop
Michael schrieb: > bei meiner Lösung mindestens ein ATMega16 > nehmen. Bei einem ATmega8 wäre doch ein ATmega328 angebrachter. Im Guloshop für 2 Euro zu haben. Da Du sehr oft einfach Nullen durchschiebst, kannst Du ein paar Shiftout-Befehle wegrationalisieren. Z.B.:
1 | ... |
2 | Dim N as DWORD |
3 | ... |
4 | Shiftout Daten , Clock , N , 1, 16 'wie 2x Shiftout |
5 | ... |
6 | Shiftout Daten , Clock , N , 1, 32 'wie 4x Shiftout |
Funktioniert der oben angegeben Code? CASE ist bis 60 aber Isec nur maximal 16.
PS. Bei Dis(8) sollte das auch funktionieren, dann wäre N=&HFFFFFFFF
> Den an sich gibt es leider ein > Problem, dass meine Lösung ein wenig sehr Speicher verbraucht# Das wundert mich bei dem Ansatz nicht wirklich > und dabei > erstmal nur 1 Ring mit Sekunden anzeigt. Also wenn Minuten und > Stunden noch hinzu kommen müsste ich bei meiner Lösung mindestens > ein ATMega16 nehmen. Aber geh. Du musst das nur ein wenig intelligenter angehen! Du wirst dir doch wohl noch Formeln ausdenken können, wieviele LED im jeweiligen Scheberegister leuchten müssen, wenn du bsp-weise bei Sekunde 38 stehst. Ja! Das kann man berechnen. Und das ist noch nicht einmal schwer. Jeder Grundschüler im 2.ten Schuljahr kann das. Ausser Dividieren und Rest bei einer Division braucht man dazu nichts: 8 Kinder stehen in einer Reihe. Eine Mutter hat 38 Torten. Wieviele Torten kriegt jedes Kind, wenn die Mutter vorne in der Reihe anfängt und jedem Kind erst mal 8 Torten gibt, ehe sie zum nächsten Kind weitergeht. Wieviele Kinder bekommen 8 Torten (also die volle Anzahl)? 38 / 8 -> 4 die ersten 4 Kinder bekommen 8 Torten Wieviele Torten bleiben dann noch zur Verteilung? 38 - ( 4 * 8 ) -> 38 - 32 -> 6 das 5. Kind bekommt 6 Torten Wieviele Torten kriegen die anderen Kinder? keine. Die Kinder 6 bis 8 gehen leer aus. Und schon sind deine 3 Bildschirmseiten Code auf 3 Berechnungen, 2 FOR-Schleifen (mit einer Anweisung innerhalb der Schleife) und noch einer Anweisung geschrumpft. Alles in allem weniger als 15 Zeilen Code.
Es sollte sogar noch einfacher gehen. Wenn ich das richtig interpretiere und wenn mein Hirn nicht noch unter akutem Kopffeinmangel leidet, so müsste man doch immer nur pro Sekunde 1 Bit von 60 ändern.
1 | Dim Dis as Dword |
2 | ... |
3 | Do |
4 | |
5 | Dis=0 |
6 | |
7 | For x = 0 to 59 |
8 | Strobe = 0 |
9 | Toggle Dis.x |
10 | Shiftout Daten , Clock , Dis , 1 |
11 | Strobe = 1 |
12 | Waitms 100 |
13 | Next |
14 | |
15 | Loop |
Karl schrieb: > Es sollte sogar noch einfacher gehen. Wenn ich das richtig interpretiere > und wenn mein Hirn nicht noch unter akutem Kopffeinmangel leidet, so > müsste man doch immer nur pro Sekunde 1 Bit von 60 ändern. Du hast im Prinzip schon recht. Ich wollte nur den Helfern von weiter oben nicht ins Handwerk pfuschen, die ihn auf "du musst immer alle SR neu beschreiben und dazu teilst du dir ..." gebracht haben. Ausserdem schadet es nicht, wenn man sieht das Mathe dann doch zu etwas nütze ist. Es gibt auch noch andere einfache Lösungen, wie man alle 60 LED auf den gewünschten Wert stellt, wenn man weiß, das LED 1 bis n leuchten sollen und man jeweils einen Komplettupdate machen will. Zb 2 For-Schleifen hintereinander: die erste gibt 60-n mal ein 0 Bit aus, die 2.te gibt n mal ein 1 Bit aus.
Karl schrieb: > Es sollte sogar noch einfacher gehen. Wenn ich das richtig interpretiere > und wenn mein Hirn nicht noch unter akutem Kopffeinmangel leidet, so > müsste man doch immer nur pro Sekunde 1 Bit von 60 ändern. Also kommt drauf an, was er anzeigen will. Die aktuelle Sekunde als leuchtenden Punkt im Sekundenkreis? -> dann bei der 1.Sekunde einmal eine '1' raus schieben und dann mit jeder Sekunde eimal eine '0' schieben Die Sekunden als Leuchtband im Sekundenkreis? -> dann ab der 1.Sekunde je Sekunde eine '1' raus schieben und beim zurücksetzen des Sekundencounters (von 60 auf 0) den Sekundenkreis durch 60x eine '0' raus schieben löschen. Wie das jetzt in BASCOM gelöst wird kann ich nicht beantworten.
Karl Heinz Buchegger schrieb: > Zb 2 For-Schleifen > hintereinander: die erste gibt 60-n mal ein 0 Bit aus, die 2.te gibt n > mal ein 1 Bit aus. Ne, das wäre zu einfach. Da braucht man ja nur ein Byte SRAM und ganz wenig Code. Peter
Peter Dannegger schrieb: > Karl Heinz Buchegger schrieb: >> Zb 2 For-Schleifen >> hintereinander: die erste gibt 60-n mal ein 0 Bit aus, die 2.te gibt n >> mal ein 1 Bit aus. > > Ne, das wäre zu einfach. > Da braucht man ja nur ein Byte SRAM und ganz wenig Code. Auch wieder wahr. Irgendwie muss man den 16-er ja schliesslich auch voll kriegen.
Steffen H. schrieb: > Also kommt drauf an, was er anzeigen will. > Die Sekunden als Leuchtband im Sekundenkreis? Wenn ich mir den Code so ansehe, dann genau das. In der letzten Case Anweisung werden die restlichen 4 Bits zur 1 (alle anderen sind es schon).
Karl Heinz Buchegger schrieb: > Zb 2 For-Schleifen > hintereinander: die erste gibt 60-n mal ein 0 Bit aus, die 2.te gibt n > mal ein 1 Bit aus. In C könnte das so aussehen:
1 | #include "sbit.h" |
2 | |
3 | #define DOUT PORT_B0
|
4 | #define CLOCK PORT_B1
|
5 | #define STROBE PORT_B2
|
6 | |
7 | |
8 | static void shift( uint8_t n ) |
9 | {
|
10 | while( n-- ){ |
11 | CLOCK = 0; |
12 | CLOCK = 1; |
13 | }
|
14 | }
|
15 | |
16 | |
17 | void display_seconds( uint8_t n ) |
18 | {
|
19 | DOUT = 0; |
20 | shift( 60 ); |
21 | DOUT = 1; |
22 | shift( n ); |
23 | STROBE = 1; |
24 | STROBE = 0; |
25 | }
|
Peter
So hier einmal dann eine Verkleinerte Version. Karl Heinz gab den Anstoß
dafür und nun ist der Code nach Compilieren sogar schon unter 1kb groß.
Wenn ich mir weiter so mühe gebe könnte ich meine ganze Uhr sogar per
ATTiny13 gestalten, zumindest vom Speicher aus.
$regfile = "attiny13.dat"
$crystal = 9600000
$hwstack = 32
$swstack = 4
$framesize = 4
Config Portb.2 = Output
Config Portb.1 = Output
Config Portb.0 = Output
Strobe Alias Portb.2
Daten Alias Portb.1
Clock Alias Portb.0
Strobe = 0
Daten = 0
Clock = 0
Dim Dis(9) As Byte
Dim Sek_1 As Integer
Dim Sek_2 As Integer
Dim Sek_3 As Integer
Dim Sek_4 As Integer
Dim Sek_a As Integer
Dim Sek_b As Integer
Dim Sek_c As Integer
Dis(1) = &B00000001
Dis(2) = &B00000011
Dis(3) = &B00000111
Dis(4) = &B00001111
Dis(5) = &B00011111
Dis(6) = &B00111111
Dis(7) = &B01111111
Dis(8) = &B11111111
Dis(9) = &B00000000
Do
'Sekundenschleife
For Sek_1 = 1 To 60 'Allgemeine
Sekundenschleife
'Beispiel
Sekundenangabe = Sek = 38
Strobe = 0
Sek_a = Sek_1 / 8 'Teilt die
Sekunden / 8 -> Ergebnis in -> Sec_a
Sek_b = 8 * Sek_a
'Multipliziert Sec_a mit 8 -> Ergebnis in -> Sec_b
Sek_c = Sek_1 - Sek_b 'Zieht Sec_b
von Sec ab -> Ergebnis in -> Sec_c
For Sek_2 = 0 To Sek_a 'Füllt die
vollen Bits auf solange bis I2 = Sec_a
Shiftout Daten , Clock , Dis(8) , 1 'Schiebt
Dis(8) (8-Bits) ins Schieberegister
Next
Shiftout Daten , Clock , Dis(sek_c) , 1 'Schiebt den
Unvollständigen Byte in den Schieberegister nach
Sek_4 = Sek_a + 1 'Errechnet
die Fehlenden Bytes um die 8 Schieberegister zu füllen
For Sek_3 = Sek_4 To 8 'Füllt
solange leere Bytes nach bis 8 Byts (ergibt 8 Schieberegister)
erreicht sind
Shiftout Daten , Clock , Dis(9) , 1 'Schiebt mit
0-Bit gefüllte Bytes in die letzten Register
Next
Strobe = 1
Waitms 100
Next
Loop
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.