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.

18f4620 c18 shift register problem

Status
Not open for further replies.

gabeNC

Member
Howdy gents,

Had some time off during Christmas and thought I would *finally* use some shift registers. I have the 595 wired to a LED bar graph and it flashes faintly, I can just barely see it, even when passing all zero's or 0b10101010 it seems to be all the segments. I'm sure the solution is something easy (and stupid) but the it has eluded me of late.

Using a 18f4620 and ST M74HC595B1.

thanks!

Code:
#include <p18f4620.h>
#include <delays.h>
#include <timers.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 enabled

#define ClockPin            PORTAbits.RA0  // SCK Clock Input
#define DataPin                PORTAbits.RA1  // SI Serial Data Input
#define LatchPin            PORTAbits.RA2  // RCK Latch
#define OutputEnable        PORTAbits.RA3  // G  

/*
PIC Pin                595 Data sheet pin / desc
===============================================
RA0        SCK        Shift Register Clock Input
RA1        SI        Serial Data Input
RA2        RCK        Storage Register Clock (latch)  
RA3        G        Output Enable
*/

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

// a debug indicator
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;
  FlashRA4(50);
  while(1)
    {
    FlashRA4(25);
    ShiftOut(0b00000000);
    Delay10KTCYx(100); 
    
    ShiftOut(0b01010101);
    Delay10KTCYx(100);     

    ShiftOut(0b11111111);
    Delay10KTCYx(100);     
    }
}
Here's a Saleae screen shot of the 595 IC.

shift_register_saleae_screenshot.png
 
The clock pin on the 595 should not be strobed until the data bit is present on pin D0 of the 595. Also, the 595 uses an SPI interface so it shifts in/out MSB first.

Try this code instead for your ShiftOut function -

Code:
void ShiftOut(unsigned char data)
{
	ClockPin = 0;						//default clock low
	DataPin = 0;						//default data low
	LatchPin = 0;						//default latch low
	unsigned char bitcount = 0;				//init bit counter
	for(bitcount = 0; bitcount < 8; bitcount++)		//send 8 bits
	{
		DataPin = 0;					//assume MSB = 0
		if(data & 0b10000000)				//if MSB = 1
		{
			DataPin = 1;				//send 1
		}
		ClockPin = 1;					//strobe clock
		ClockPin = 0;
		data = data << 1;				//left shift data bits
	}
	LatchPin = 1;						//strobe latch
	LatchPin = 0;
}
 
Last edited:
Question, as I don't use C, but can...

Code:
DataPin = 0;					//assume MSB = 0
if(data & 0b10000000)				//if MSB = 1
{
	DataPin = 1;				//send 1
}
...be replaced with just...

Code:
DataPin = (data & 0b10000000)
...or not?
 
Last edited:
Question, as I don't use C, but can...

Code:
DataPin = 0;					//assume MSB = 0
if(data & 0b10000000)				//if MSB = 1
{
	DataPin = 1;				//send 1
}
...be replaced with just...

Code:
DataPin = (data & 0b10000000)
...or not?

Short answer is no.... Pommie showed this in another thread as DataPin is a bit and (data & 0b1000000) evaluates to 0x80 or 0 the pin is never set..
 
Ah, yes... that makes sense. That's why I probably wrote my JAL procedure so that it ANDs with 1 and shifts the byte the other way.

Code:
-- Procedure to communicate a byte value to the connected 74HC595 and
-- have it set its pins accordingly.

procedure ShiftOutByte ( byte in pByte
                       ) is
  -- Helps visualise our mask, variable not really required as it would
  -- be just as easy to logical AND the InByte with 1 each time around.
  var byte Mask = 0b_0000_0001
  -- Hold the InByte in this variable.
  var byte InByte = pByte
  
  -- Set all pins to be low.
  LatchPin = 0
  ClockPin = 0
  DataPin = 0

  -- Each time we analyse a byte, we will decipher 8 bits.
  for 8 loop
    -- Decide on what the Data pin should be for this bit.
    DataPin = InByte & Mask
    -- Toggle the Clock pin.
    ClockPin = 1
    ClockPin = 0
    -- Look at the next bit of the InByte.
    InByte = InByte >> 1
  end loop

  -- We have completed shifting out our byte, inform the 74HC595.
  LatchPin = 1
end procedure
Not that I write efficient code myself, but I do pretend to try and, at least, appreciate it. ;)
 
Last edited:
Thanks Jon for the example. I borrowed Pommie's code originally but ended up thrashing around making changes thinking it was a code issue when in fact (rookie mistake) it was my breadboard. :mad:
Nothing like chasing ghosts for two days. Fired up the soldering gun and made a proper dev board.
 
Question, as I don't use C, but can...

Code:
DataPin = 0;					//assume MSB = 0
if(data & 0b10000000)				//if MSB = 1
{
	DataPin = 1;				//send 1
}
...be replaced with just...

Code:
DataPin = (data & 0b10000000)
...or not?

you could do this tho...

Code:
DataPin = 0;	//assume MSB = 0
DataPin = ((data>>bitcount)&0x01);

Or something like that :)

Not sure if its faster or anything but heh its available :D
 
Last edited:
Status
Not open for further replies.

Latest threads

Back
Top