Changing TLC5940 library to facilitate higher frequency PWM

Status
Not open for further replies.

josechow

Well-known member
Hello,

So. I have been doing some digging in the TLC5940 library and I wanted to pop the hood on the library and get faster pwm frequencies.

I have modified the configuration to accept a 16mhz crystal on the GSCLK input pin (30mhz) without modifying the library. From the datasheet, this will give me a 16mhz counting frequency of the grayscale pwm.

To get the corresponding 2^10 precision out of the grayscale pwm I wanted (max of 1024), I have modified the TLC_PWM_PERIOD attribute to be 512, which corresponds to a 15khz. I verified this with a scope as the BLANK pin transitions high for a single pulse width. This should reset the grayscale pwm counter to 0 when it reaches 1024, because the BLANK pin goes high and performs its function.


Code:
/** Determines how long each PWM period should be, in clocks.
    \f$\displaystyle f_{PWM} = \frac{f_{osc}}{2 * TLC\_PWM\_PERIOD} Hz \f$
    \f$\displaystyle TLC\_PWM\_PERIOD = \frac{f_{osc}}{2 * f_{PWM}} \f$
    This is related to TLC_GSCLK_PERIOD:
    \f$\displaystyle TLC\_PWM\_PERIOD =
       \frac{(TLC\_GSCLK\_PERIOD + 1) * 4096}{2} \f$
    \note The default of 8192 means the PWM frequency is 976.5625Hz */
#define TLC_PWM_PERIOD    512

/** Determines how long each period GSCLK is.
    This is related to TLC_PWM_PERIOD:
    \f$\displaystyle TLC\_GSCLK\_PERIOD =
       \frac{2 * TLC\_PWM\_PERIOD}{4096} - 1 \f$
    \note Default is 3 */
#define TLC_GSCLK_PERIOD    3

So, from what I know, the serial data is coming in correctly, so I wont analyze that. That leaves the following process:

Start with BLANK Pulse HIGH => All outputs go blank, grayscale counter resets to zero
BLANK goes low => grayscale starts counting, ALL leds turn on
on COMPARE of grayscale and GS Mode Data (serial data) => specific output turns off
BLANK Pulse comes in after 1024 counts of GSCLK => repeat cycle

I did some tests and I was able to write some values to the leds on all outputs. Since I didn't affect the serial bus, this works as expected. However, any values I write to the leds that are higher than 340, make the led's go to maximum brightness. Its as if the BLANK pin is being set a third of the way through the expected counting cycle. Anyone have any ideas?
 
So I figured out that the random transition was due to the DC, or "dot correction" constant current sink looking up values in accordance with the DC register that wasn't already coded (this is because DCPRG is hardwired to Vcc on the breakout board, and forces the dot correction to look at the DC register instead of the EEPROM which has all default values written to it.)

From this, I know now that I would need to place VPRG high which puts the TLC5940 into DC register programming mode and I can shift in the expected (16) 6 bit values for the channels. Transition VPRG back to ground then I will be able to send grayscale data like normal.

So... I need help because I dont understand a pin setting.

Code:
/** VPRG (Arduino digital pin 8) -> VPRG (TLC pin 27) */
#define DEFAULT_VPRG_PIN    PB0
#define DEFAULT_VPRG_PORT   PORTB
#define DEFAULT_VPRG_DDR    DDRB

PB0 is being used for clockout of the 16mhz source on the atmega328p. I understand I can change PB0 and PORTB to any other pin, but I dont know what DDRB does.

After I've got this up and running, I will post the full code example with the modified "basic use" sketch if someone needs higher frequency out of the TLC5940 working with an atmega328.
 
Hi,

Did you manage to solve this?
Also how did you modify the configuration to accept a 16mhz crystal on the GSCLK input pin?
 
Hi,

Did you manage to solve this?
Also how did you modify the configuration to accept a 16mhz crystal on the GSCLK input pin?

I ended up burning up a couple of the outputs somehow, and I gave up on it. I moved over to the PCA9685 which is more of what I was looking for (voltage control vs. current control)
 
Status
Not open for further replies.
Back
Top