Hallo, ich versuche (mittlerweile schon) verzweifelt, 2x TLC5916 (das sind Schieberegister mit Konstantstromsenken ) in "Special Mode" zu versetzen, um den Strom an den Ausgängen einzustellen. Die beiden sind nacheinander an den USART0 eines ATmega1284P angeschlossen und der wird im Master SPI Modus betrieben. Das An- und Ausschalten der LEDs geht, also müssten die ICs noch funktionstüchtig sein. Zum versetzen in "Special Mode" muss anscheinend SPI bzw. USART abgeschaltet werden und die Ansteuerung "manuell" erfolgen. Das macht bei mir die Funktion void tlc5916_mode_switch(uint8_t newmode). Um dann den "Configuration Code" in die Register zu schieben, kann die USART hardware wieder eingeschaltet werden (basierend auf dieser Quelle http://softsolder.com/2009/12/22/), ich habe es zuerst gemacht und es hat nicht funktioniert (die reingeschobenen Daten wurden wohl als Werte für die Ausgangspins übernommen und nicht als Werte für den Strom -> die LEDs haben im Testprogramm geblinkt), dann habe ich die Stromwerte auch "manuell" reingeschoben und es funktioniert auch nicht... :-( Hat jemand schon Erfahrungen mit diesen Chips oder vielleicht sogar den Code für die Ansteuerung? Würde mich sehr freuen, weil ich sonst bei google außer der oben genannten Quelle kaum was zu dem Problem finden konnte. Im Anhang mein nicht funktionierender C-Code :-) MfG Newbie
Ach ja, fast vergessen, hier das Datenblatt http://www.ti.com/lit/gpn/tlc5916-q1 und vom uC hier http://www.atmel.com/dyn/resources/prod_documents/doc8272.pdf
Newbie schrieb: > Im Anhang mein nicht funktionierender C-Code :-) Funktioniert dein Code nicht, oder wird er nicht compiliert? Bei mir kommt als erstes eine Compilerwarnung, weil usart_mspim_init nicht in der usart.h auftaucht.
Hallo, Martin, tut mir leid, habe wohl die Warnungen übersehen... hier ist die korrigierte Version mit Makefile dazu. Der Code funktioniert aber trotzdem nicht :-( Die angeschlossenen LEDs müssten eigentlich im Sekundentakt abwechselnd dunkler und heller werden. Bei mir leuchten sie immer mit voller Stärke :-(
Hallo, schau Dir mal den Code für die spezielle Initialisierung an. Der Code an Position 3 und 4 ist identisch. Laut der Seite die Du an gehangen hast, müsste LE erst High werden und dann wieder LOW, Du hast ihn aber in beiden Fällen auf LOW stehen. Gruß Frank
LE habe ich nur beim Versetzen in NORMAL MODE in beiden Fällen auf LOW, so wie es in der Quelle auch gemacht wird. Hat denn sonst keiner eine Lösung fürs Problem? Sonst muss ich wohl die mit PWM dimmen, was nicht so optimal wäre, weil es nur 1 gemeinsame OE Leitung in meiner Schaltung gibt und ich somit nur alle ICs zusammen dimmen kann.
Hallo, bei mir ist das ein Weilchen her - aber für die Nacht poste ich dir hier mal meinen Code-Schnippsel, der den Modus-Wechsel vollführt. Auch im Special-Mode kann SPI verwendet werden, nur für den Wechsel muss man manuel vorgehen. Der Code ist für MSP430 gemacht, und ich habe einige viele Makros verwendet. Vielleicht hilft er dir ja so schonmal auf die Sprünge - ansonsten müssen wir da morgen (abend) nochmal nachhelfen ;-). Grüße Janosch
1 | /**
|
2 | * MODE SWITCHING PROCEDURE:
|
3 | * After !OE goes low for 1 clock cycle, a 1-clock
|
4 | * wide pulse in clock cycle #4 switches to SPECIAL
|
5 | * MODE (*). Missing this pulse in clock cycle #4
|
6 | * switches to NORMAL MODE (**).
|
7 | * ===============================================
|
8 | * #1 #2 #3 #4 #5
|
9 | * -- -- -- -- --
|
10 | * CLK | | | | | | | | | |
|
11 | * -- -- -- -- -- --
|
12 | * ===============|=====|=====|=====|=====|=======
|
13 | * ----- --------------------
|
14 | * !OE(ED2) 1 | 0 | 1 1 1
|
15 | * -----
|
16 | * ===============|=====|=====|=====|=====|=======
|
17 | * -----
|
18 | * LE(ED1) (*) 0 0 0 | 1 | 0
|
19 | * (->Special) ----------------- --------
|
20 | *
|
21 | * LE(ED1) (**) 0 0 0 0 0
|
22 | * (->Normal) --------------------------------
|
23 | * ===============|=====|=====|=====|=====|=======
|
24 | * Phase: |Actual Mode| Switching | New Mode->
|
25 | * ===============|=====|=====|=====|=====|=======
|
26 | *
|
27 | * If the driver is operated in SPI mode, then this
|
28 | * mode has to be exited (left) before mode switching
|
29 | * can be performed. After mode switching, SPI mode
|
30 | * has to be re-entered.
|
31 | */
|
32 | void switchMode(mode_e mode) { |
33 | #ifdef SPI_MODE
|
34 | // Exit SPI mode
|
35 | CBI(driver_pSEL, driver_SDI + driver_CLK); |
36 | SBI(driver_pDIR, driver_SDI + driver_CLK); |
37 | #endif
|
38 | |
39 | hi(driver_nOE); |
40 | lo(driver_LE); |
41 | hilo(driver_CLK); // CLK-1 |
42 | |
43 | lo(driver_nOE); |
44 | hilo(driver_CLK); // CLK-2 |
45 | |
46 | hi(driver_nOE); |
47 | hilo(driver_CLK); // CLK-3 |
48 | |
49 | if (mode == MODE_SPECIAL) { |
50 | hi(driver_LE); |
51 | hilo(driver_CLK); // CLK-4 |
52 | lo(driver_LE); |
53 | hilo(driver_CLK); // CLK-5 |
54 | }
|
55 | else { |
56 | hilo(driver_CLK); // CLK-4 |
57 | hilo(driver_CLK); // CLK-5 |
58 | }
|
59 | |
60 | #ifdef SPI_MODE
|
61 | // Switch back to SPI Mode
|
62 | SBI(driver_pSEL, driver_SDI + driver_CLK); |
63 | #endif
|
64 | }
|
Edit: Die Makros sehen so aus:
1 | #define hi(pin) SBI(driver_pOUT, (pin)) // pin: _|^
|
2 | #define lo(pin) CBI(driver_pOUT, (pin)) // pin: ^|_
|
3 | #define hilo(pin) hi((pin)); lo((pin))
|
Jetzt habe ich doch nochmal in deinen Code reingeschaut. Das Betreten des Special-Modes ist zumindest gleich. Beim Verlassen ziehst du nach dem 5. SCK-Puls noch OE runter - ich glaube aber nicht, dass das das Verlassen des Special-Modes verhindert. Vielleicht macht deine "current_adjust" Methode nicht was sie soll? Sieht mir nach Software-SPI aus, aber wie oben gesagt, spricht nichts dagegen, den Konfigurations-Code (8 bit) ebenfalls per SPI zu übermitteln. Hier mal als Vorlage meine Methode:
1 | void matrix_driver_config(unsigned char configRed, unsigned char configGreen) { |
2 | /**
|
3 | * TODO: Make sure that the timer/driver has stopped interrupting.
|
4 | * This method call has to be somehow synchronized with the timer interrupt.
|
5 | */
|
6 | bool isDriver_nOE = TBI(driver_pOUT, driver_nOE); // Remember DRIVER:nOE state |
7 | |
8 | switchMode(MODE_SPECIAL); |
9 | send16(configRed, configGreen); |
10 | switchMode(MODE_NORMAL); |
11 | |
12 | /**
|
13 | * Restore DRIVER:nOE state
|
14 | */
|
15 | if (isDriver_nOE) { |
16 | SBI(driver_pOUT, driver_nOE); |
17 | }
|
18 | else { |
19 | CBI(driver_pOUT, driver_nOE); |
20 | }
|
21 | }
|
(Ich habe zwei TLCs in Reihe). Die Konfigurations-Codes erzeuge ich so:
1 | /**
|
2 | * Value between 0 and 63
|
3 | */
|
4 | #define CONFIG_CODE(value) (((value) << 2) + 0x03)
|
(0 war vermutlich kein oder wenig Strom, 63 maximal) So, vielleicht hilft dir das durch die Nacht - ich muss jetzt aber ins Bette.
Hallo, Janosch, vielen Dank für die Antwort und den Code! Ich habe meine Funktionen jetzt komplett überarbeitet und benutze die SPI/USART Hardware zwischen dem Moduswechsel. Aber irgendwie kommt es dazu, dass die reingetakteten Daten in die OUTputs übernommen werden und nicht in die Stromkonfiguration... also blinken die LEDs vom Backlight abwechselnd... :-( verstehe nicht, wo da das Problem steckt... habe nochmal die USART-Routinen durchgeschaut, die Wartezeit nach dem Deaktivieren des Transmitters/Receivers eingefügt (zusätzlich zur while()-Warteschleife, die eigtl ausreichen sollte)...
Hallo, vom Ablauf sieht das vollkommen in Ordnung aus - und war es vorher bestimmt auch schon. Bist du denn sicher, dass du die control-Eingabe als Ausgang siehst? Mich irritiert Zeile 41 in tlc5961.c:
1 | void tlc5916_out (uint8_t data, uint8_t device) { |
2 | /*41*/ static uint8_t out[TLC5916_QTY] = OUT_ARRAY_INIT; |
3 | uint8_t i; |
4 | out[device] = data; |
5 | for (i = 0; i < TLC5916_QTY; i++) { |
6 | usart_mspim_transceive (out[i]); |
7 | }
|
8 | LE_HILO
|
9 | }
|
Dieses Array muss doch raus aus der Methode, da es sonst bei jeder Konfiguration neu (leer) angelegt wird. (?) Lässt sich so das abwechselnde Blinken erklären? Gruß Janosch
Hm... wenn ich die arrays global deklariere ändert sich nichts... außerdem sind die ja dann auch "statisch" und statisch heißt dabei, dass sie nur 1x deklariert werden... oder irre ich mich?
Mich wundert auch irgendwie, dass das manuelle Reintakten bei mir überhaupt nicht funktioniert... ich habe jetzt alles in einer Datei zusammengefasst und so klein wie möglich gemacht, um den Fehler zu finden... aber auch wenn ich den Teil mit Stromanpassung auskommentiere, bleiben die LEDs die ganze Zeit dunkel :-( Das brint mich auf den Gedanken, dass irgendwas mit dem Timing nicht stimmt... (Der ATmega läuft bei mir mit dem internen Oszi mit 8 MHz...) oder es liegt an mangelnden C und AVR-Kenntnissen :-(
Newbie schrieb: > Hm... wenn ich die arrays global deklariere ändert sich nichts... > außerdem sind die ja dann auch "statisch" und statisch heißt dabei, dass > sie nur 1x deklariert werden... oder irre ich mich? Nein völlig richtig - Test bestanden :-p, an mangelnden C-Kenntnissen liegt's wohl nicht. Also dein Code sieht absolut in Ordnung aus. Irritieren tun mich lediglich noch die Delays - wozu sind die?. Mein MSP läuft mit 8 oder 16 MHz und vollem SPI speed (keine Ahnung was das ist), und ich brauche mich um Timings nicht zu scheren. Ich kann leider nicht aktiv mit debuggen, weil mein wilder Aufbau mit 100 Kabeln hier auf dem Schreibtisch unter einer Staubdecke verschwunden ist, d.h. ich traue mich zurzeit nicht ihm auch nur ein Kabel zu krümen :-(. Doch wie sieht es denn jetzt aus: 1. Der TLC schaltet den Output im Hardware-SPI Betrieb -> Aber der Config-Code wird an den Ausgang gelegt -> Auch wenn zur Übertragung des Config-Codes Soft-SPI verwendet wird? 2. Der TLC macht gar nichts im Soft-SPI Betrieb? -> Richtig? Wenn 2. korrekt ist, dann ist sollte der Fehler dort gesucht werden. Denn um zwischen den Modes zu wechseln, muss "soft" getaktet werden, und wenn das nicht funktioniert, kann auch nichts weiter gehen. Also: Soft-SPI muss gehen, würde ich mal fast sagen. (Deine Soft-SPI Routine sieht auch völlig ok aus). Ansonsten: Kann es am Schaltplan liegen? Welchen Widerstand hast du an R-Ext? Ich hänge mal ein Bild von meiner Schaltung an. Nicht aufgeben, der TLC5916 ist ein starkes Bauteil! :-)
Also ich habe es jetzt irgendwie hinbekommen :-) Ich habe meine softSPI Routine nochmal überarbeitet und nun läuft es! Das mit dem USART Master SPI Modus funktioniert aber immer noch nicht, ich will mich auch nicht weiter damit auseinandersetzen, weil Software SPI für mich schon schnell genug ist. Vielen Dank nochmal, Janosch, für deine Hilfe! Ich hänge mal den (endlich) funktionierenden Code an, vielleicht kann es ja jemand gebrauchen ;) MfG Newbie
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.