Go Down

Topic: Parsimony, ShiftOut and Bleedthrough (Read 752 times) previous topic - next topic

zekekoch

Jan 04, 2012, 03:24 pm Last Edit: Jan 04, 2012, 08:32 pm by zekekoch Reason: 1
I'm currently working on a project with a bunch of 74HC595 shift registers and ULN2003AN darlington arrays.  I'm PWMing the light and like many people have been searching for ways to improve the performance of manual bit banging.

Since I've started the project I've learned about SPI, but my current board is using other pins and more importantly, I feel like I'm really starting to understand shift registers (after using them for a few years mostly with blind copy and paste).

The first thing I discovered was writing to PORTB directly instead of using digitalWrite.  Wow, that's so much faster it's really quite nice.  The deeper I get into microcontrollers the more I appreciate the hard work the arduino folks have put into making this stuff so much easier.  That said, there are times to get closer to the metal and I'm there now.

Now, what most of the sample code on the net does is something like this:

1. set latch to low (disable the outputs while shifting bits)
2. clear data pin
3. set clock to low
4. loop over the bits in a byte and for each bit
 4a. set the clock to low
 4b. set the data pin high or low
 4c set the clock high (triggers a read from the shift register)
 4d. set the data pin low
5. set the clock to low
6. set the latch to high (enable the outputs

What I don't understand is why we would need to do 2, 3 and 4d.  If I'm going to set the clock to low at 4a then 3 seems redundant and if I'm setting the value of the data pin at step 4b then step 2 seems redundant.

The only theory I have is that some folks are worried that if there's data on the data bit when I hit step 4a then that will get shifted onto the registers but of course I'm sending 32 bits down the pipe anyway and so that bit will 'fall out the end' of the shift register before I enable the latch.

What am I missing?

Thanks,

-Zeke

Here's my current shiftOut if my pseudocode is too pseudo.


void shiftOut(byte outputData) {
 // This shifts 8 bits out MSB first, on the rising edge of the clock, clock idles low

 //clear everything out just in case to prepare shift register for bit shifting  
 bitClear(PORTB, dataPinPortB);
 bitClear(PORTB, clockPinPortB);

 // loop over the bits in outputData and send them to the shift register
 for (int i=7; i>=0; i--)  
 {
   bitClear(PORTB, clockPinPortB);

   //Sets the pin to HIGH or LOW depending on pinState
   if (bitRead(outputData,i))
   {
     bitSet(PORTB, dataPinPortB);
   }
   else
   {
     bitClear(PORTB, dataPinPortB);
   }

   //register shifts bits on upstroke of clock pin  
   bitSet(PORTB, clockPinPortB);
   //zero the data pin after shift to prevent bleed through
   bitClear(PORTB, dataPinPortB);
 }

 // the clock pin likes to idle at LOW
 bitWrite(PORTB, clockPinPortB, 0);
}

Grumpy_Mike

Quote
What I don't understand is why we would need to do 2, 3 and 4d.

Like you said you don't.

Quote
If I'm going to set the clock to low at 4a then 3 seems redundant and if I'm setting the value of the data pin at step 4b then step 2 seems redundant.

Yes it is.

Quote
Now, what most of the sample code on the net does is something like this:

That is because most people who post sample code don't know what they are doing.
I also hope you have removed any capacitor on the latch pin, like the arduino tutorial tells you to do and also add decoupling capacitors across the supply of each chip you use.

zekekoch

Thanks Mike.  That clarification helps a lot.  I did remove the capacitor from the latch pin, but I haven't added decoupling capacitors on the supply of all of my chips.  I did put one on each side of my voltage regulator.

Decoupling capacitors is one of those things that I understand in theory, but not in practice.  I'm using 9 ICs in my design (4 shift registers, 4 darlington arrays, one atmega).  Does that mean that I need 11 caps (two for the 7805 plus one for every IC) or does only the atmega need a decoupling cap?  Also does it go on the power pin or the data pin?  I assume power pin.  Does it need to cross the power and GND pins directly or can it go to a common ground?  Can you point me to a good discussion of decoupling caps for beginners?

-Zeke


corrected code:


void shiftOut(byte outputData) {
  // This shifts 8 bits out MSB first, on the rising edge of the clock, clock idles low

  // loop over the bits in outputData and send them to the shift register
  for (int i=7; i>=0; i--) 
  {
    bitClear(PORTB, clockPinPortB);

    //Sets the pin to HIGH or LOW depending on pinState
    if (bitRead(outputData,i))
    {
      bitSet(PORTB, dataPinPortB);
    }
    else
    {
      bitClear(PORTB, dataPinPortB);
    }

    //register shifts bits on upstroke of clock pin 
    bitSet(PORTB, clockPinPortB);
  }

  // the clock pin likes to idle at LOW
  bitWrite(PORTB, clockPinPortB, 0);
}


-Zeke

Grumpy_Mike

Quote
Does that mean that I need 11 caps (two for the 7805 plus one for every IC)

I wouldn't use one on the arrays because these are only transistors, but on every other chip in a system.
Quote
Does it need to cross the power and GND pins directly

Yes as close to the chip as you can get.

Quote
Can you point me to a good discussion of decoupling caps for beginners?

I wrote this:-
http://www.thebox.myzen.co.uk/Tutorial/De-coupling.html

Go Up