Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

cascading shift register problem, 2 work but not 3.

Status
Not open for further replies.

gabeNC

Member
Howdy gents,

Have two 595's working good but when I add the third one, the entire line of 24 leds light up and the animation stops. Scope doesn't show much ripple on the rails but I added another bypass cap close to the 595's just for good measure. Already had two caps on either side of the 7805 and of course on the power pins of the pic. Total current through the regulator is .3 amps.

Seems to be when I solder on the SCK pin is when the problems start. Switched to a different 595 and same result, triple checked connections. Any ideas? Thanks!

Code:
#include <p18f4620.h>
#include <delays.h>
#include <timers.h>
#include <pwm.h>

#pragma config  OSC = INTIO67      // Internal oscillator, OSC1 & OSC2 are IO
#pragma config  FCMEN = OFF        // Fail-safe clock monitor off
#pragma config  IESO = OFF         // Int-Ext Osc switchover disabled
#pragma config  PWRT = OFF         // Power-up timer disabled
#pragma config  BOREN = OFF        // Brown-out reset disabled
#pragma config  BORV = 0           // Brown-out voltage maximum
#pragma config  WDT = OFF          // Disable hardware watch-dog timer control
#pragma config  MCLRE = ON         // MCLR enabled
#pragma config  LPT1OSC = ON       // T1 Oscillator enabled
#pragma config  PBADEN = OFF       // Port B A/D disabled digital on reset
#pragma config  CCP2MX = PORTBE    // CCP2 MUX
#pragma config  STVREN = ON        // Stack overflow reset enabled
#pragma config  LVP = OFF          // Low voltage ICSP disabled
#pragma config  XINST = OFF        // Enable extended instruction set
#pragma config  DEBUG = OFF         // Background debugger disabled

// shift register model: ST74HC595B1
#define DataPin                   PORTAbits.RA0   // SI Serial Data Input
#define ClockPin                 PORTAbits.RA1   // SCK Clock Input
#define OutputEnable        PORTAbits.RA2   // G  (output enable)
#define LatchPin                 PORTAbits.RA3   // RCK Latch

void ShiftOut(unsigned long dat){
	unsigned char i;
    LatchPin=0;
    for(i=0;i<24;i++){ 
        DataPin=dat & 1;
	//Nop();
	ClockPin = 1;
        dat>>=1;
	ClockPin = 0;
    	}
    LatchPin=1;
	//Nop();
	LatchPin=0;
	}

// a debug indicator
// should move this from RA4 since 18f can sink and source
void FlashRA4(char time){
	LATAbits.LATA4 = 1;
	Delay10KTCYx(time); 
	LATAbits.LATA4 = 0;
	Delay10KTCYx(time); 
	}	

void main (void)
{
  OSCCON = 0x62;              // Int Osc, 4Mhz
  while(!OSCCONbits.IOFS);    // Wait for osc to be stable
  TRISA = 0;
  LatchPin = 1;
  OutputEnable =1;
  FlashRA4(5);FlashRA4(5);FlashRA4(5);
  while(1)
	{
	ShiftOut(0b111111110000000011111111);
	Delay10KTCYx(100);
	ShiftOut(0b000000001111111100000000);
	Delay10KTCYx(100);
	ShiftOut(0b111111111111111111111111);
	Delay10KTCYx(100);
	FlashRA4(10);
	}
}
 
Schematic would be useful.
 
This is what i don't get
Code:
 DataPin=dat & 1; //the left side is a bit and you anded a 1 in
	//Nop();
	ClockPin = 1;
        dat>>=1;  // then here you shift 1 but where

wouldn't it be this
Code:
 DataPin=dat & 1;
	//Nop();
	ClockPin = 1;
        dat=dat>>=1;
 
Last edited:
I simulated it last night it didn't work and it looks like C18 handles it best if you shift byte 1 then byte 2 so on. It can shift 16 bits but that's as big as it goes with out breaking it down in smaller bytes

I didn't think you could shift 32 bits at once, use a byte array.

Or maybe 3v0 has time to post a better way to handle this.
 
Last edited:
Thanks Burt, I was suspecting there was something wrong in the way I was trying to shift the data. I eventually want to hook up four of them, driving three 10-segment led arrays, that is why I set the shift variable to a long.

I'll research using byte arrays now. Thanks for the nudge in the proper direction.
 
Something like this may help you get started I found it over at microchips site
Code:
void shift_left( byte *BufferName, unsigned char no_of_bytes, BOOL bit_val)
 {
     unsigned char i;
     unsigned char overflow;  // indicates if last byte shift overflows
 
     overflow=0x00;
     for(i=0; i<no_of_bytes; i++)
     {
         unsigned char temp;  // since we check for overflow befor shift
         temp=overflow;        //     save overflow in temp register
 
         //check to see if this byte will overflow
         if (BufferName[i] & 0x80)
             overflow=0x01;
         else
             overflow=0x00;
 
         //do shift
         BufferName[i]=BufferName[i] << 1;
 
         //handle last overflow
         BufferName[i]=BufferName[i] | temp;
      }
      //optionally you may want to handle the last overflow
 }
 
Something like this may help you get started I found it over at microchips site **broken link removed**
 
Something like this may help you get started I found it over at microchips site
Code:
         //check to see if this byte will overflow
         if (BufferName[i] & 0x80)
             overflow=0x01;
         else
             overflow=0x00;

I understand what is going on here (i think) but I don't know why. If I cycle 8 times through an entire byte will it overflow?

thanks.
 
Your sending more then one byte you want to see if they all where sent.
 
Um try this out:
Code:
unsigned char MyBytes[3];

void ShiftOut(char qob)//qob = Quantity of Bytes
{
    unsigned char i,x;

    LatchPin=0;

    for(x=0;x<qob;x++)           //Loop quatity of bytes
    {
        for(i=0;i<8;i++){        //loop 8 bits per byte
            if(MyBytes[i] & 0x80)//test bit 7
                DataPin= 1;      //if 1 set datapin high
            else
                DataPin= 0;      //if 0 set datapin low
            //Nop();
            ClockPin = 1;        //clock the new data out
            dat>>=1;
            ClockPin = 0;
            MyBytes[i]<<=1;      //shift data over 1 bit
        }//end of bits loop
    }//end of bytes loop

    LatchPin=1; //latch the data to the output pins.
    //Nop();
    LatchPin=0;
}

Using the above you can use it like:

ShiftOut(3);

This will send out the MSb to LSb from MyArray[0], then MSb to LSb from MyArray[1], then MSb to LSb from MyArray[2]
 
Last edited:
Atom your code is missing one thing a { on the first "for statement". Looks great just need that one thing.
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top