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.