An Interface with a STP16C596 16-bit Constant Current LED Sink Driver

copyright, Peter H Anderson, Baltimore, MD, Jan ,'08


Introduction.

This discussion deals with interfacing the STMicro STP16C596 16-bit constant current sink driver with an Arduino. This discussion may be expanded to other processors such as the PICAXE in the future.

The STP16C596 includes a 16-bit shift register and corresonding D flipflops and driver output stages which are capable of sinking 10 or more mA. One important feature is that each output is a constant current source with the current being determined by a single external resistor eliminating the need for the series nominal 330 Ohm resistor for each LED.

It is priced at Digikey at a bit over $2.00.

Three control outputs from the processor are required, clock (CLK), Serial Data In (SDI) and latch enable LE. The serial data output (SDO) from one device may be input to a second device so as realize a 32 LED driver and this might be extended indefinitely.

Detailed Discussion


     Arduino						  STP16C596

      DOUT ---------------------------- SDI (2)
      CLK ----------------------------- CLK (3)
      NOT_LE -------------------------- NOT_LE (4)

                      GRD ------------- /OE

The 16-bit shift register is loaded by bringing output MOSI (Digital Pin 2) to the appropriate state and then bringing CLK (Digital Pin 3) high and then low. This is repeated for each of the sixteeen bits. During this time NOT_LE is high which isolates the shift register from the output latch. Once all 16 bits have been loaded in the shift register, the NOT_LE output is momentarily brought low, which connects the shift register to the latches, and then back high to again isolate the shift register from the latches.

void shift_out_16(unsigned int v)
{
   int n;
   O_LOW(CLK);   // be sure CLK is idle at zero
   O_HIGH(NOT_LE);
   for (n=0; n<16; n++)
   {
       if ((v >> (15 - n) & 0x01) // most significant bit first
       {
           O_HIGH(DOUT);
       }
       else
       {
           O_LOW(DOUT);
       }

       delay(1);
       O_HIGH(CLK);
       delay(1);
       O_LOW(CLK);
   }
   O_LOW(NOT_LE);   // wink NOT_LE low
   O_HIGH(NOT_LE);
}

The D flipflops are directly connected to the output drivers when input /OE is at GRD. In my application, I tied /OE to hard ground. Note that the data is inverted in the output stage. That is, if the D flipflop is at a logic one, this turns on the output FET and the output voltage is near zero. With the LEDs configured with the anode at +5 VDC, current flows through the LED and the LED lights. When the D flipflop is at a logic zero, the corresponding driver output is off or open, and no current flows through the LED.

    OUT --------|<------ +5 VDC

The current in each LED is determined by the value of R_EXT on STP16C596 terminal 23. I used 1K to provide a constant current of nominally 20 mA.


Program STP16C596_1 causes a linear bar array of sixteen LEDs to rise and then to fall. That is, no LEDs, then one, then two, etc to 16 and then to 15, 14 and down to zero. One obvious application is to dynamically display a quantity in a bar graph fashion. However, function shift_out_16 may be used to display any LED configuration.

Note that in the following program, I used macros DIR_OUT and DIR_IN to configure the direction of a digital pin, O_HIGH and O_LOW to bring an output pin high or low and IN to read a digital pin. In my mind, this cuts out some of the frustration of forever typing digitalWrite or similar while not sacrifing any understanding in the code.


// STP16C596_1.pde (Arduino, ATMega168)
//
// Peter H Anderson, Jan, '08

#define DIR_OUT(pin) pinMode(pin, OUTPUT)
#define DIR_IN(pin)   pinMode(pin, INPUT)
#define O_HIGH(pin) digitalWrite(pin, HIGH)
#define O_LOW(pin) digitalWrite(pin, LOW)
#define IN(pin) digitalRead(pin)

#define DOUT 2
#define CLK 3
#define NOT_LE 4


void setup()
{
  DIR_OUT(DOUT);
  DIR_OUT(CLK);
  DIR_OUT(NOT_LE);
  O_HIGH(NOT_LE);
  Serial.begin(9600);
  delay(5000);
}

void loop()
{
    int n;
    unsigned int val = 0;

    val = 0x0000;  // start with all off
    for (n=0; n<16; n++)
    {
        shift_out_16(val);
        val = (val << 1) | 0x01; // walk the LEDs up
        delay(25);
    }

    val = 0xffff; // start with all ones
    for (n=0; n<16; n++)
    {
        val = val & ~(0x01 << (15 - n)); // walk a zero down
        shift_out_16(val);
        delay(25);
    }
 }

void shift_out_16(unsigned int v)
{
   int n;
   O_LOW(CLK);   // be sure CLK is idle at zero
   O_HIGH(NOT_LE);
   for (n=0; n<16; n++)
   {
       if (v >> (15 - n))  // most sig bit first
       {
           O_HIGH(DOUT);
       }
       else
       {
           O_LOW(DOUT);
       }

       delay(1);
       O_HIGH(CLK);
       delay(1);
       O_LOW(CLK);
   }
   O_LOW(NOT_LE);
   O_HIGH(NOT_LE);
}


Recommend: Forex Market learn how to trade forex. Learn more info for your trading success! . A demo forex trading account is simply the perfect way for beginner traders.