tlc5920 16x8 led driver/controller

Pavel Hudecek edizon na seznam.cz
Úterý Srpen 28 11:12:57 CEST 2018


Tady ovšem vůbec nejde o posuvný registr (samozřejmě bez LATCH by to bylo
mnohem horší). Tenhle problém nastává i třeba u displeje připojeného přímo
na port AVR. Prostě buď můžu napřed přepnout multiplex a pak změnit data,
nebo naopak, ale v obou případech je tam doba, po kterou se buď na předchozí
pozici zobrazují nová data, nebo na nové pozici zobrazují data stará. Ten
přesah trvá třeba 70 ns, ale přesto je při slabším osvětlení dobře vidět.
Problém zmizí teprve až přesahu zabráníte zhasnutím.

Je fakt, že na 32b MCU vlastně nutně nastávat nemusí, protože data i druhé
konce se můžou ovládat společným portem, takže to proběhne opravdu ve
stejném okamžiku. Tady máme ovšem na obou stranách nějakou složitější
logiku, takže předpokládám, že ani když zajistíte, že se LATCH aktivuje
přesně v okamžiku změny COMx, nebudou tyto okamžiky shodné i na výstupech.

Jen teda nutně nemusíte použít BLANK, koukám, že stejnou funkci má i /DSEL.

PH

-----Původní zpráva----- 
From: David Belohrad
A to je prave vec, ktera mi neni jasna. Proc by tomu tak melo byt, kdyz
TLC5920 obsahuje posuvny registr a latch. Takze do posuvneho to posouvam, a
pak pulsem na LATCH zapisu ta data z registru do latche a muzu vesele dal
pouzivat posuvny registr bez omezeni, protoze data, ktera 'vidi' led jsou ta
z latche. Nebo ne?


Pavel Hudecek <edizon na seznam.cz> writes:
> Jo a ten BLANK tady samozřejmě bude potřeba, protože jinak bude docházet k
> prosvítání při přepínání multiplexu. Zhasnout, změnit data, přepnout COM a
> rozsvítit.
>
>
> -----Původní zpráva----- 
> From: Pavel Hudecek
> Zkusil bych se buď podívat osciloskopem, jak to na těch COM vypadá, nebo
> to
> pustit tak pomalu, aby bylo vidět co to dělá.
>
> Pokud by nebyl problém s polaritou COM, tak před pár lety jsem se
> ochomejtnul okolo něčeho s jiným TLC59.. (neměl COM, jen 16 výstupů) a tam
> měli problém, že na velké desce SCLK vesele clockoval i na odrazy hran. A
> měl taky BLANK a ten vypínal výstupy, ale už si nepamatuju, zda ho bylo
> potřeba používat.
>
>
> -----Původní zpráva----- 
> From: David Belohrad
> A cim vice se divam na ten datasheet, tim mene tomu rozumim.
>
> Na strane 3 je uvedeno ze jak S[15:0] tak COM[7:0] jsou VYSTUPY, ovsem na
> nasledujici strane je napsano ze low-level output current na COM0-7 je
> 640mA, a high-level output current na S[15:0] je -30mA. Pro me to znamena,
> ze S[15:0] je v podstate current sink, a tudiz moje diody ve schematu jsou
> zapojeny obracene (doufam, ze neurazim prilozenym schematem). Za
> predpokladu, ze 'cathode common' je to co si myslim, tak bych mel schema
> mit
> dobre. Diody sviti, takze predpokladam, ze by mely byt zapojene spravne.
>
> Jsem zmaten a ocenim jakekoliv komentare. Pro uplnost prikladam
> systemverilog implementaci toho kontroleru. (pozn: data_ib indexy nejsou
> jeste ve spravnem poradi, ale na implementaci to nic nemeni)
>
>
> import CKRSPkg::*;
>
>
> module tlc5920
>   #(
>     // clock divider. Set to zero when ClkRs_ix provides 40MHz
>     // stream. For all faster clocks give division ratio to get to
>     // lower speeds
>     parameter   g_divider  = 4
>     )
>   (
>    // 40 MHz clock reset stream
>    input   ckrs_t ClkRs_ix,
>    // data input. Logic '1' turns the particular led on (= emits
>    // light). The vector data are as follows:
>    // [row][column][red/green]
>    input logic [1:0][15:0][3:0] data_ib,
>    // interface to the chip
>    display_x display
>    );
>
>    // clock enable
>    logic enable, latchdly1, latchdly2, latch;
>    logic sclk = 0;
>
>    // counting 32bits to be shifted in one go into both registers
>    localparam CBITS = 7;
>    logic [CBITS-1:0] counter_b = '0;
>    logic frame, subframe;
>    logic [63:0] hipart_b, lopart_b;
>
>    // column selector
>    logic [2:0] csel_b3 = '0;
>
>    // first we get clock enable out of division, get maximum speed,
>    // which is 10MHz. This is clock into serial register
>    clock_divider
>      #(.g_divider(g_divider))
>    i_clock_divider
>       (.enable_o(enable),
>        .*);
>
>    // simple counter to count the states
>    always_ff @(posedge ClkRs_ix.clk)
>      if (enable)
>        counter_b <= counter_b + (CBITS)'(1);
>
>    // always present clock
>    always_ff @(posedge ClkRs_ix.clk)
>      if (enable) sclk <= ~sclk;
>
>    // latching is every 16bits, extend
>    // pulse into SCLK domain, which is twice slower
>    always_ff @(posedge ClkRs_ix.clk)
>      if (enable) begin
> if (~(|counter_b[4:0]))
>   latchdly1 <= 1;
> else
>   latchdly1 <= 0;
> latchdly2 <= latchdly1;
> latch <= latchdly1 | latchdly2;
>      end
>
>    // frame is 4 16-bit cycles, two independent data outputs
>    // for each driver separately
>    always_ff @(posedge ClkRs_ix.clk)
>      if (enable) begin
> if (~(|counter_b))
>   frame <= 1;
> else
>   frame <= 0;
>
> if (~(|counter_b[3:0]))
>   subframe <= 1;
> else
>   subframe <= 0;
>      end // if (enable)
>
>    // chip-selects (resp driver selects). The driver is set such, that
>    // 16bits correspond to two-chip data (odd bits on com0,2,4... even
>    // bits on com1,3,5,7)
>    always_ff @(posedge ClkRs_ix.clk)
>      if (enable)
>        if (subframe && frame)
> // with frame coming in we start to load the data into col0
> // and 1, hence csel has to be two behind such, that on next
> // latch we get values for csel 0 and 1
> csel_b3 <= 3'd6;
>        else if (subframe)
> csel_b3 <= csel_b3 + 3'd1;
>
>
>    // every frame we have to load the input data into shift register:
>    logic [1:0][63:0] data_b = '0;
>    always_ff @(posedge ClkRs_ix.clk)
>      if (frame && enable)
>        data_b <= data_ib;
>      else if (sclk && enable) begin
> data_b[0] <= {1'b0, data_b[0][63:1]};
> data_b[1] <= {1'b0, data_b[1][63:1]};
>      end
>
> // assignments:
>    assign display.blank_o = '0;
>
>    always_ff @(posedge sclk)
>      display.latch_o <= latch;
>
>    // separate two data in streams. all other signals are common for
>    // both chips
>    always_ff @(posedge ClkRs_ix.clk)
>      if (enable) begin
> display.data1_o <= data_b[0][0];
> display.data2_o <= data_b[1][0];
> display.csel_ob3 <= csel_b3;
>      end
>
>    // invert clock to position data transitions wrt negative
>    // edges. this makes timing margin and should work even with crappy
>    // lines
>    assign display.sclk_o = ~sclk;
>
>
>    initial begin
>       $display("Size of input vector: %d", $bits(data_ib));
>
>    end
>
>
> endmodule // tlc5920
>
>
> David Belohrad <david na belohrad.ch> writes:
>> ma prosim nekdo zkusenosti s tl5920?
>>
>> www.ti.com/lit/ds/symlink/tlc5920.pdf
>>
>>
>> nevim jak spravne formulovat muj dotaz. ... nefunguje to a asi nerozumim,
>> jak to ma fungovat. Datasheet je velice skoupy na informace. a at delam
>> co
>> delam, led matrix zobrazuje hovadiny. Vyrobil jsem kus systemverilog
>> kodu,
>> ktery dava 'blank' signal trvale na log. L. Necham vzdy do 16 bitoveho
>> registru nacist pro dany radek tu 16-bitovou informaci, po kazdych 16
>> bitech vytvorim puls na LATCH (transision L->H->L), a na kazdych
>> 16-bitech
>> cykluji csel vzdy dvakrat (tedy mezi dvema latch impulzy ma csel hodnotu
>> 0,1 pak 2,3 pak 4,5), a tedy jeden 'frame' vyzaduje 4x latch - celkove 64
>> bitu poslanych na kazdy frame, ktery cykluje csel od nuly do sedmi.
>>
>> Kdyz to spustim a divam se na data na SIN/SOUT, vsechno vypada perfektne,
>> logicky. Ovsem diody si delaji co chteji. nektere z nich slabe sviti,
>> nektere silne, skoro to vypada, jako kdyby nebyl dostatecny proud tema
>> diodama, nebo dochazelo k nejakemu mixu mezi logikou CSEL pinu a seriove
>> linky. Napada me jenom, ze signal BLANK proste z nejakeho neznameho
>> duvodu
>> musi byt take pouzivan. Ja jej mam trvale na nule, protoze chci mit ty
>> diody neustale zapnute.
>>
>> Tak me napadlo, nema k tomuto driveru nekdo kod napsany pro ... cokoliv?
>> arduino/jakykoliv mikrokontroler, abych si mohl proverit jestli casuji
>> jak
>> mam? K cemu je BLANK?
>>
>> ztratil jsem s tou hovadinou cely den 



Další informace o konferenci Hw-list