Hallo Leute, bin blutiger Anfänger und habe hier ein Schieberegister TLC5916 rumliegen,dass ich gerne ansteuern möchte: Datasheet: http://www.ti.com/lit/ds/symlink/tlc5916.pdf Ich habe das Gefühl,dass ich etwas sehr grundlegendes nicht verstanden habe und es deshalb nicht geht.. Kurze Beschreibung zur Beschaltung: Die Pins:GND, R-Ext und OE(ED2) sind jeweils an GND verbunden. Nun habe ich am Pin OUT0 eine LED angeschlossen. Als nächstes habe ich die folgenden Pins des Schieberegisters einfach an die Pins meines Atmega8 angeschlossen: PB0 ->SDI PB1 ->CLK PB2 ->LE(ED1 Dann der Code: #define F_CPU 1000000UL #include <avr/io.h> #include <avr/delay.h> int main(void) { DDRB |= (1<<DDB0) | (1<<DDB1) | (1<<DDB2); PORTB |= (1<<PB1) | (1<<PB2); PORTB &= ~(1<<PB0); _delay_ms(10); PORTB |= (1<<PB0); PORTB &= ~(1<<PB1); _delay_ms(10); PORTB |= (1<<PB1); PORTB &= ~(1<<PB2); _delay_ms(10); PORTB |= (1<<PB2); while(1) { } } Erwartung: LED sollte leuchten. Was mache ich falsch?
> Ich habe das Gefühl,dass ich etwas sehr grundlegendes nicht verstanden > habe und es deshalb nicht geht.. Das glauben wir auch. Du weisst nicht was ein Schieberegister ist, du kannst noch nicht C-Programmieren und du glaubst ein IC verwenden zu koennen ohne dessen Datenblatt zu lesen (Rext). Mit anderen Worten die Aufgabe ist du komplex fuer dich. Schliesse erstmal eine LED, natuerlich mit Vorwiderstand, direkt an dem Port an den du fuer SCK vorgesehen hast und lasse die achtmal blinken. Danach reden wir mal weiter... Olaf
Haha nein,ich kann schon einiges grundlegendes.. 7-Segmente Multiplexen und so habe ich bereits hingekriegt.. ich wollt das nun eben mit Schieberegistern versuchen..davor noch nie mit einem IC gearbeitet. Nur bin ich total unsicher wie das gehen soll.. normalerweise würde ich den 74HC595 verwenden,da es dafür gute Tutorials mit Beispielen gibt,aber hab nun mal den gerade nicht zur Verfügung... Die Frage ist eigentlich.. verstehe ich das Datenblatt nicht richtig oder aber die Software nicht? Oder beides?
Bzw kann sich einer bitte kurz die Mühe machen (hoffe es ist nicht zu viel verlangt) und mir zeigen wie es sein müsste,damit die LED an OUT0 leuchten muss? Nur Code und evtl richtige Beschaltung der Pins wären sehr hilfreich.. dann könnte ich mir das auf jedenfall alles irgendwie klar machen.
@ Juergen (Gast) >Nur bin ich total unsicher wie das gehen soll.. normalerweise würde ich >den 74HC595 verwenden,da es dafür gute Tutorials mit Beispielen >gibt,aber hab nun mal den gerade nicht zur Verfügung... Beispiele sind wichitg. Aber man muss sie auch VERSTEHEN, nicht einfach kopieren! Wenn du das Beispiel für den 74HC595 verstanden hast, ist der TLC5916 ein Kinderspiel. >Die Pins:GND, R-Ext und OE(ED2) sind jeweils an GND verbunden. Solche Lyrik kannst du dir sparen. Poste einen VOLLSTÄNDIGEN Schaltplan unter Beachtung der Bildformate. R-EXT auf GND ist keine gute Idee. "R-EXT External Resistor - Connect an external resistor to ground to set the current for all outputs" >Nun habe ich am Pin OUT0 eine LED angeschlossen. WIE? Siehst du, so geht das Problem weiter, siehe Netiquette. >Als nächstes habe ich die folgenden Pins des Schieberegisters einfach an >die Pins meines Atmega8 angeschlossen: >PB0 ->SDI >PB1 ->CLK >PB2 ->LE(ED1 Schön. >Erwartung: LED sollte leuchten. >Was mache ich falsch? Datenblatt gelesen? Datenblatt ansatzweise verstanden? Die Daten werden mit Bit0 beginnend reingeschoben, man muss aber 8 Bits reinschieben, damit Bit 0 auch ankommt. Sonst belibt es auf der Position von Bit7 hängen. Du erzeugst drei SCK Takte. Das haut hinten und vorn nicht hin. Ausserdem bin ich nicht sicher, obe man OE einfach auf GND klemmen kann oder ob man es takten muss, so wie im Datenblatt. Für die ersten Test sollte man einfach mal alle acht LEDs anklemmen, irgendeine wird schon leuchten. Das erleichtert die Fehlersuche.
Lesen & einarbeiten. Dann erst wieder fragen und nicht 5 Minuten später... Alternativ, jemand dafür bezahlen, dass er deine Aufgabe löst...
@ Juergen (Gast) >Muss ich das per SPI machen ? Nein. >Geht das auch nicht auch mit Software? Ja, einfach so wie du es angefangen hast, aber mit der richtigen logischen Abfolge. SDI = HIGH 8 Takte an SCK erzeugen LE = HIGH
Ok erstmal danke für die ganzen Antworten! Aber was soll man dann sonst mit R-Ext machen? Auf dem Datenblatt gleich auf der ersten Seite wurde es auch an GND verbunden mit einem Widerstand davor in Reihe geschaltet.
@ Juergen (Gast) >Aber was soll man dann sonst mit R-Ext machen? Einen Widerstand anschließen? So wie im Datenblatt? > Auf dem Datenblatt gleich >auf der ersten Seite wurde es auch an GND verbunden mit einem Widerstand >davor in Reihe geschaltet. EBEN! Wenn du aber schreibst "R-Ext und OE(ED2) sind jeweils an GND verbunden." dann bedeutet dass, das eben KEIN Widerstand dazwischen ist und dur das DIREKT verbunden hast! Großer Unterschied!
@ Juergen (Gast)
>Nur Code und evtl richtige Beschaltung der Pins wären sehr hilfreich..
Wie wäre es mit der Schaltung auf der 1. Seite im Datenblatt?
Ok alles klar. An R-Ext ist ein Widerstand dran. Ich hab jetzt für OE ebenfalls ein Pin am Mikrokontroller vorgesehen. (PB3) Ich bin jetzt ganz stupide nach dem Timing Diagram vorgegangen auf Seite 5 im Datenblatt: Aber es geht immernoch nicht,wobei diesmal an jedem OUT eine LED angeschlossen ist: #define F_CPU 1000000UL #include <avr/io.h> #include <avr/delay.h> int main(void) { DDRB |= (1<<DDB0) | (1<<DDB1) | (1<<DDB2) | (1<<DDB3); PORTB |= (1<<PB3); // OE PORTB |= (1<<PB0); // SDI clock(); // CLK clock(); clock(); clock(); clock(); clock(); clock(); clock(); PORTB |= (1<<PB2); //LE PORTB &= ~(1<<PB2); PORTB &= ~(1<<PB3); while(1) { } } void clock() { PORTB |=(1<<PB1);PORTB &= ~(1<<PB1); }
@Juergen (Gast) >Ok alles klar. An R-Ext ist ein Widerstand dran. Gut. >Ich bin jetzt ganz stupide nach dem Timing Diagram vorgegangen auf Seite >5 im Datenblatt: Auch gut. Kleiner Tip. Mit defines macht man sich das Leben leicht und den Quelltext kinderleich lesbar.
1 | #define F_CPU 1000000UL
|
2 | #include <avr/io.h> |
3 | #include <avr/delay.h> |
4 | |
5 | #define CLOCK PORTB |=(1<<PB1); PORTB &= ~(1<<PB1);
|
6 | #define SDI_LOW PORTB &= ~(1<<PB0);
|
7 | #define SDI_HIGH PORTB |= (1<<PB0);
|
8 | #define LE_LOW PORTB &= ~(1<<PB2);
|
9 | #define LE_HIGH PORTB |= (1<<PB2);
|
10 | #define OE_LOW PORTB &= ~(1<<PB3);
|
11 | #define OE_HIGH PORTB |= (1<<PB3);
|
12 | |
13 | int main(void) |
14 | {
|
15 | DDRB |= (1<<DDB0) | (1<<DDB1) | (1<<DDB2) | (1<<DDB3); |
16 | |
17 | OE_HIGH
|
18 | SDI_HIGH
|
19 | LE_LOW
|
20 | |
21 | CLOCK
|
22 | CLOCK
|
23 | CLOCK
|
24 | CLOCK
|
25 | CLOCK
|
26 | CLOCK
|
27 | CLOCK
|
28 | CLOCK
|
29 | |
30 | LE_HIGH
|
31 | LE_LOW
|
32 | |
33 | while(1); |
34 | }
|
>Ok es geht.. mein VCC kabel am TLC5916 hatte nen Wackelkontakt :D Steckbretter sind schon ne tolle Sache . . . Wenn es dann mal um richtige Muster für die LEDs geht, siehe http://www.mikrocontroller.net/articles/Bitmanipulation#Siehe_auch
Ok habe ein kleines Hardware problem... Irgendwie gehen alle LEDS von OUT0-OUT7 aus,wenn ich den GND Pin an GND anstecke..also sind die LED's nur an,wenn ich mit dem GND-PIN gar nichts mache.. Wenn ich R-Ext rausnehme passiert übrigens nichts.. Lampen leuchten mit der selben stärke.. Wie lässt sich das erklären? Vor allem wie läuft das überhaupt ohne GND-PIN? Da kann doch etwas nicht stimmen..
Hab noch eine zusätzliche Frage zur oberen. Ich hab einen zeiten Schieberegister hinzuaddiert (kaskadiert). Jetzt muss ich doch einfach nur noch 16 mal CLOCK benutzen statt 8 mal.. da ja beim 9.CLOCK der letzte Wert vom 1. Schieberegister von SDO im SDI vom 2. landet.. ..leider funktioniert das irgendwie nicht.
@ Juergen (Gast) >Ok habe ein kleines Hardware problem... Hmmm. >Wie lässt sich das erklären? Vor allem wie läuft das überhaupt ohne >GND-PIN? NEIN! Schließe alles ordentlich an. Punkt! Die Geistereffekte sind nicht das, was du haben willst. >..leider funktioniert das irgendwie nicht. Bring die Schaltung erstmal mit EINEM Schieberegister SOLIDE zum laufen.
Ok irgendwie hatte ich echt irgendein Geistereffekt. Leider geht es nicht..obwohl ich mich genau an den Timing Diagram halte. Hardwaremäßig hab ich alles 10 mal überprüft.Ich kann mir nur vorstellen,dass ich eine bestimmte Taktfrequenz beachten muss...ist das wirklich streng zu beachten,oder müsste es auch ohne einigermaßen klappen? Code:
1 | #define F_CPU 1000000UL
|
2 | #include <avr/io.h> |
3 | #include <avr/delay.h> |
4 | |
5 | int main(void) |
6 | {
|
7 | DDRB |= (1<<DDB0); //SDI |
8 | DDRD |= (1<<DDD7) ; //CLK |
9 | DDRD |= (1<<DDD6) ; //LE |
10 | DDRD |= (1<<DDD5); //OE |
11 | |
12 | PORTD &= ~(1<<PD7); //CLK low |
13 | PORTB |= (1<<PB0); // SDI high |
14 | PORTD &= ~(1<<PD6); //LE low |
15 | PORTD |= (1<<PD5); // OE high |
16 | |
17 | clock(); // CLK |
18 | clock(); |
19 | clock(); |
20 | clock(); |
21 | clock(); |
22 | clock(); |
23 | clock(); |
24 | clock(); |
25 | |
26 | |
27 | PORTD |= (1<<PD6); //LE high |
28 | _delay_us(10); |
29 | PORTD &= ~(1<<PD6); //LE low |
30 | _delay_us(10); |
31 | |
32 | PORTD &= ~(1<<PD5); //OE low |
33 | |
34 | |
35 | |
36 | while(1) |
37 | {
|
38 | |
39 | }
|
40 | |
41 | |
42 | }
|
43 | |
44 | void clock() |
45 | {
|
46 | PORTD |=(1<<PD7); //CLK high |
47 | _delay_us(1); |
48 | PORTD &= ~(1<<PD7); //CLK low |
49 | _delay_us(1); |
50 | }
|
Juergen schrieb: > Hardwaremäßig hab ich alles 10 mal überprüft.Ich kann mir nur > vorstellen,dass ich eine bestimmte Taktfrequenz beachten muss... Wenn du mal ins Datenblatt schaust, dann steht da, dass die Frequenz auf dem Clock-Signal bis zu 25MHz betragen darf. Das schafft dein mit popeligen 1MHz getakteter µC garantiert nicht. ABer Hinweis: Man darf so langsam takten wie man will :-) Mit ein paar LED+Vorwiderstand direkt an den TLC Pins, kann man bei genügend langsamer Ansteuerung wunderbar verfolgen, was denn vom Programm tatsächlich an den TLC Pins für Sequenzen ausgegeben werden, bzw. was davon beim TLC ankommt. Und wenn dein Steckbrett sowieso nicht das Allerbeste ist ....
PS: Warum hast du eigentlich die Leitung über 2 Ports verstreut? Wenn du die Ansteuerung sowieso in Software machst, ohne das Hardware SPI Modul zu benutzen, dann kannst du die Pins benutzen, die dir genehem sind. Zum Beispiel die Pins, die alle am selben Port liegen. Gut, es muss natürlich auch so gehen, schon klar. Aber es ist eine Fehlerquelle mehr, weil man jetzt bei jedem Pinwackler auch zusätzlich auch noch überprüfen muss, ob er am richtigen Port stattfindet und nicht nur am richtigen Pin. Man kann sich als Programmierer auch selbst das Leben schwer machen, indem man * möglichst inkonsistent die Pins verteilt * möglichst die Möglichkeiten von C ignoriert. Ist ja auch viel einfacher, wenn es im Programm nur so von PORTB, PB6, etc. wimmelt, die man alle einzeln überprüfen muss, anstatt dass man sich gleich mal per #define ein paar Namen für die Dinge vergibt und dann im Programm diese Namen verwendet, anstatt darauf zu vertrauen, dass die Kommentare schon stimmen werden.
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.