Electronic Projects, forums and more.

Go Back   Electronic Circuits Projects Diagrams Free > Electronics Categories > Micro Controllers


Micro Controllers Discuss all aspects of micro controllers - building them, coding them, etc. All controllers are welcome - PIC, BASIC, Z8 Encore!, etc.

Reply
 
Tools
Old 4th September 2008, 11:33 PM   #1
Default Working with Shift Registers and a PIC help

Hey everyone im back once again needing some assistance school started and I brought the Idea of the LED cube to him and he liked it but he asked me to find out the theory or I guess the way it works we will be using shift registers instead of directly driving the LED's so it allows me 12 output pins instead of the 5 that the 12F509 has but im wondering how I would go about doing the pulses to the shift register ive seen a little code out there about it but not too much any help I know the shift register takes 4 inputs data,clock,latch,enable output and I will be using the 74HC595 as my shift register to start with just to see how it works right just using 8 LED's first and my PIC controlling them in a fashion that I want it doesn't have to be perfect and its just some quick testing I don't want to hear just get a better PIC bc im just starting out with them and the PIC 12F509 is good for right now maby later I will get some better ones but Thanks for all the help guys its much needed and once its in there its never going to come out haha

Last edited by Darkstar64; 4th September 2008 at 11:50 PM.
Darkstar64 is offline  
Old 5th September 2008, 12:17 AM   #2
Default

You need to get the datasheet from a source like the following:

http://focus.ti.com/lit/ds/symlink/sn74hc595.pdf

Pay particular attention to the table on page 2. Now make the pins of the PIC do the things that are required by the table.
__________________
We never have time to do it right; but we always have time to do it over.
Papabravo is offline  
Old 5th September 2008, 12:20 AM   #3
Default

Here's some dead simple C demo code for 18F1320 (Junebug) and 74HC595. Being C, it's trivial to change it for any PIC.

The code simply alternately flashes the even and odd LEDS of a row of eight LEDs driven by a single 74HC595.

Code:
#include <system.h>
#include <boostc.h>

#pragma	CLOCK_FREQ	8000000
#pragma DATA    _CONFIG1H, _INTIO2_OSC_1H
#pragma DATA    _CONFIG2H, _WDT_OFF_2H
#pragma DATA    _CONFIG3H, _MCLRE_ON_3H
#pragma DATA    _CONFIG4L, _LVP_OFF_4L

#define data	latb.1
#define clock	latb.4
#define latch	lata.3

void main(void){
	unsigned char x;
	osccon=0x72;				//8MHz osc
	trisa=trisb=0;
	while(1){
		data=1;				//shift in alternating 1's & 0's
		for(x=0;x<8;x++){
			clock=1;clock=0;
			if(data==0)
				data=1;
			else
				data=0;
		}
		latch=1;latch=0;		//latch the data
		delay_ms(170);			//delay so we can see LEDs

		data=0;				//shift in alternating 0's & 1's
		for(x=0;x<8;x++){
			clock=1;clock=0;
			if(data==0)
				data=1;
			else
				data=0;
		}
		latch=1;latch=0;		//latch the data
		delay_ms(170);			//delay so we can see LEDs
	}
}

Here's a different main() for the above that blinks the eight LEDs as a binary byte counter:
Code:
void main(void){
	unsigned char x,y,temp1,temp2;
	osccon=0x72;					//8MHz osc
	trisa=trisb=0;
	while(1){
		for(x=0;x<255;x++){
			for(y=0;y<8;y++){
				temp1=x;
				temp2=temp1>>y;
				temp2=temp2&0b00000001;
				data=temp2;
				clock=1;clock=0;
			}
			latch=1;latch=0;
			delay_ms(170);
		}
	}
}
__________________
=========================
Futz's Microcontrollers & Robotics
=========================
futz is offline  
Old 5th September 2008, 12:31 AM   #4
Default

ok thanks for the info but anything in assembler thats the only thing I know at the moment and understand but thanks for the quick responses also is there a way to have more then one pin on at the same time say I have 1 shiftregister that has 12 outputs and 4 inputs once again ? I'm going to be trying 64 LED's matrix that I saw and it shows me how to do it using just 4 I/0 pins but it doesn't state the assembly or any code ?
Darkstar64 is offline  
Old 5th September 2008, 12:55 AM   #5
Default

Quote:
Originally Posted by Darkstar64 View Post
ok thanks for the info but anything in assembler thats the only thing I know at the moment and understand but thanks for the quick responses also is there a way to have more then one pin on at the same time say I have 1 shiftregister that has 12 outputs and 4 inputs once again ?
That C code is super easy to port to assembly. Pretty simple stuff. It's not like C is some kind of ultra cryptic language or anything. Just go through it a section at a time. If you want, I can explain what each section/line does.

You can have any shift reg outputs on or off that you want. You have 12 outputs? Simply shift in 12 bits and toggle the latch so it appears on the outputs. Then do another 12 bits.

Shift registers can be cascaded, so for instance on your 12 bit unit, as soon as you exceed 12 bits shifted in, it starts to shift into the second shift register. If you have another or six more (or 20! or whatever you want), when each one is filled, the bits just start moving into the next one in the chain. When you're done shifting bits in, toggle the latch and it appears on the output pins.

Breadboard one up with a PIC and some LEDs and tinker with it. Have the datasheet handy. You'll have it figured out in no time. They're very simple to use.
__________________
=========================
Futz's Microcontrollers & Robotics
=========================

Last edited by futz; 5th September 2008 at 01:02 AM.
futz is offline  
Old 5th September 2008, 01:19 AM   #6
Default

ty thats helped alot I also have a concern though about how the Multiplexing of a 3D LED cube works me and my teacher have spent a few days on trying to figure out how it works and stuff any help on this one as well all get converting the C or at least try too it looks soooo confusing haha it might help if you explain it like you said thanks once again and if I get it right its basically just putting lets say GP2 high, low, high, low so many times in a certain amount of time or do you have to send a string of bits bc im not sure how to do that

Last edited by Darkstar64; 5th September 2008 at 01:23 AM.
Darkstar64 is offline  
Old 5th September 2008, 01:39 AM   #7
Default

Quote:
Originally Posted by Darkstar64 View Post
ty thats helped alot I also have a concern though about how the Multiplexing of a 3D LED cube works me and my teacher have spent a few days on trying to figure out how it works and stuff any help on this one as well all get converting the C or at least try too it looks soooo confusing haha it might help if you explain it like you said thanks once again and if I get it right its basically just putting lets say GP2 high, low, high, low so many times in a certain amount of time or do you have to send a string of bits bc im not sure how to do that
Hehehe! You did that all in one sentence. Makes it very difficult to read. Ever hear of punctuation?

And what the hell does "ty" stand for?

Quote:
I also have a concern though about how the Multiplexing of a 3D LED cube works
On my small 3x3x3 LED cube I just treated it like three stacked 9-bit digits. I was driving it directly - no shift registers - but that doesn't change anything. I simply set the bits I wanted lit on each "digit" and every time the timer interrupted it would light up the next "digit", or level. Writing this piece of code for the first time is pretty brain-grinding, but really it's not terribly complex. You have to buzz through them fairly quickly to prevent flicker, but a PIC can easily handle that. Shift registers are also very quick.

Once you figure this out, it's the same thing to do a seven-segment LED display, only they're only 8-bits per digit (7-segs and decimal-point).

Quote:
if I get it right its basically just putting lets say GP2 high, low, high, low so many times in a certain amount of time or do you have to send a string of bits bc im not sure how to do that
There's no amount of time involved. You can shift bits in as fast or as slow as you like. What you do is put the bit value you want (0 or 1) on the data pin. Then toggle the clock high and low quickly (or slowly if you like ) to shift that bit in (maybe low and high for some shift registers? see your datasheet). Then shift in the next bit and the next and so on. When you've finished shifting bits in just toggle the latch pin high/low (or low/high) and the bits you've just shifted in appear on the outputs of the shift register.
__________________
=========================
Futz's Microcontrollers & Robotics
=========================

Last edited by futz; 5th September 2008 at 01:49 AM.
futz is offline  
Old 5th September 2008, 02:01 AM   #8
Default

I'm also making the 3x3x3 cube first before I work on the bigger version im working on but I can't drive it directly as you did. Thats why I have to use shift registers bc there easyer to work with then the other options now about the 3x3x3 cube im going to have all the grounds common for each layer so there will be 3 layers each having 9 LEDs on each layer so thats why im going to be using the 12 output shift register. Doesn't even matter how fast I do it so I won't need a delay in between each one ? But toggle the clock in between each bit then after thats all done I just toggle the latch pin high and it should do what I want o and ty is thank you by the way o also here is the data sheet but im not sure what im supose to be looking at there is a timer diagram but im not sure what it is getting at http://www.nxp.com/acrobat_download/...C_HCT595_4.pdf

I just thought you just outputed 8 bits from the pic like lets say I wanted just LED1 on I would output '100000000' PIC and make the clock pin high in between each bit of course. Then just make the Latch pin high like this code I just finished its not complete yet but its close too being done I might put in a call for a loop that just repeats a Low output so that I don't have to write out the whole 7 bits as low I can call a loop if I have too im not sure if there is a better way to write it ?

Code:
;    Pin assignments:												  *
;																	  *
;			GP0 - Data input									      *
;			GP1 - Clock input								          *
;			GP2 - Latch	input								          *
;			GP3 - Used as a switch for Cycle of LED's				  *
;			GP4 - Forth set of LEDS									  *
;			GP5 - Switch for Random effect					          *
;										  							  *
;																	  *
;																	  *
;**********************************************************************

    list      p=12F509            ; list directive to define processor
    #include <p12F509.inc>        ; processor specific variable definitions

    __CONFIG   _MCLRE_ON & _CP_OFF & _WDT_OFF & _IntRC_OSC

; '__CONFIG' directive is used to embed configuration word within .asm file.
; The lables following the directive are located in the respective .inc file. 
; See respective data sheet for additional information on configuration word.



	cblock	0x07
;***** VARIABLE DEFINITIONS
clock
data1
data0
latch
	endc



;**********************************************************************
RESET_VECTOR    CODE   0x3FF      ; processor reset vector

; Internal RC calibration value is placed at location 0x3FF by Microchip
; as a movlw k, where the k is a literal value.
    
MAIN    CODE    0x000
    movwf   OSCCAL            ; update register with factory cal value 


start   
;******** Main Code

start
		movlw   b'001000'       ; Configure only GP3 as a input
        tris    GPIO
        
loop

		call	data1			; 1st bit High
		call	clock
		call	data0			; 2nd bit Low
		call	clock
		call	data0			; 3rd bit Low
		call	clock
		call	data0			; 4th bit Low
		call	clock
		call	data0			; 5th bit Low
		call	clock	
		call	data0			; 6th bit Low
		call	clock
		call	data0			; 7th bit Low
		call	clock
		call	data0			; 8th bit Low
		call	latch


;******** Subroutines

clock
		movlw	b'000010'		; Clock set
		movwf	GPIO
		retlw	0
		
data1	movlw	b'000001'		; Data pin high 
		movwf	GPIO
		retlw	0
		
data0	movlw	b'000000'		; Data pin low
		movwf	GPIO
		retlw	0
		
latch	movlw	b'000000'
		movwf	GPIO
		retlw	0
	
	END					; End of Program !

Last edited by Darkstar64; 5th September 2008 at 02:31 AM.
Darkstar64 is offline  
Old 5th September 2008, 03:08 AM   #9
Default

Quote:
Originally Posted by Darkstar64 View Post
Doesn't even matter how fast I do it so I won't need a delay in between each one?
The shift register should be able to keep up with almost anything you throw at it (unless you're running some kind of huge clock rate). No delays necessary. You may have to put a nop in to avoid RMW (read-modify-write) problems, but definitely try it without first.

Quote:
But toggle the clock in between each bit then after thats all done I just toggle the latch pin high and it should do what I want
High and back low again. Just blip it to latch the data, same as you just blip the clock to clock in bits.

Quote:
I might put in a call for a loop that just repeats a Low output so that I don't have to write out the whole 7 bits as low. I can call a loop if I have to. I'm not sure if there is a better way to write it ?
What you'll usually do for a thing like this is build sequences of patterns that each level steps through. Put them in tables and just step through them at a steady rate. So writing all 9 bits each time is simple and automated. Once you write the engine (the hard part) it's just a matter feeding it different sequences of patterns (the fun and easy part).

For instance, here's a few of the patterns I used to make my cube do stuff:
Code:
downtb	db	0x00,0x00,0x00,0x00,0xff,0x01
	db	0x00,0x00,0xff,0x01,0x00,0x00
	db	0xff,0x01,0x00,0x00,0x00,0x00

rolltb	db	0x24,0x01,0x00,0x00,0x00,0x00
	db	0x49,0x00,0x00,0x00,0x00,0x00
	db	0x92,0x00,0x00,0x00,0x00,0x00
	db	0x00,0x00,0x92,0x00,0x00,0x00
	db	0x00,0x00,0x00,0x00,0x92,0x00
	db	0x00,0x00,0x00,0x00,0x49,0x00
	db	0x00,0x00,0x00,0x00,0x24,0x01
	db	0x00,0x00,0x24,0x01,0x00,0x00

floptb	db	0xe0,0x00,0xe0,0x00,0xe0,0x00
	db	0x03,0x01,0x1c,0x00,0xe0,0x00
	db	0x00,0x00,0x00,0x00,0xff,0x01
	db	0xe0,0x00,0x1c,0x00,0x03,0x01
	db	0x03,0x01,0x03,0x01,0x03,0x01
	db	0x03,0x01,0x1c,0x00,0xe0,0x00
	db	0xff,0x01,0x00,0x00,0x00,0x00
	db	0xe0,0x00,0x1c,0x00,0x03,0x01

flshtb1	db	0x10,0x00,0x10,0x00,0x10,0x00
	db	0x02,0x00,0x10,0x00,0x80,0x00
	db	0x00,0x00,0x92,0x00,0x00,0x00
	db	0x80,0x00,0x10,0x00,0x02,0x00

	db	0x08,0x00,0x08,0x00,0x08,0x00
	db	0x01,0x00,0x08,0x00,0x40,0x00
	db	0x00,0x00,0x49,0x00,0x00,0x00
	db	0x40,0x00,0x08,0x00,0x01,0x00

	db	0x04,0x00,0x04,0x00,0x04,0x00
	db	0x00,0x01,0x04,0x00,0x20,0x00
	db	0x00,0x00,0x24,0x01,0x00,0x00
	db	0x20,0x00,0x04,0x00,0x00,0x01
__________________
=========================
Futz's Microcontrollers & Robotics
=========================

Last edited by futz; 5th September 2008 at 03:20 AM.
futz is offline  
Old 5th September 2008, 03:25 AM   #10
Default

Not too sure what your getting at with the whole engine thing but everything ealse makes sense If im correct you mean to make it so instead of calling like data1 data0 etc its just one call and it makes it all so like if I wanted LED1 on I would do something like this instead of what I have and im wondering is there a way to lets say just write it like this "10000000" then the pic then takes that and outputs it like that but adding the clock call in between each bite ? it might be easyer when making the cube then I won't have this long list of LED's and just be able to write it as one number and then the PIC takes it from there seperates it and then the Shift Register outputs it ? Just because its going to take alot of code and I don't think the PIC will be able to hold that much


Code:
;**********************************************************************                                                                     
;    Pin assignments:												  *
;																	  *
;			GP0 - Data input									      *
;			GP1 - Clock input								          *
;			GP2 - Latch	input								          *
;			GP3 - Used as a switch for Cycle of LED's				  *
;			GP4 - Forth set of LEDS									  *
;			GP5 - Switch for Random effect					          *
;										  							  *
;																	  *
;																	  *
;**********************************************************************

    list      p=12F509            ; list directive to define processor
    #include <p12F509.inc>        ; processor specific variable definitions

    __CONFIG   _MCLRE_ON & _CP_OFF & _WDT_OFF & _IntRC_OSC

; '__CONFIG' directive is used to embed configuration word within .asm file.
; The lables following the directive are located in the respective .inc file. 
; See respective data sheet for additional information on configuration word.



	cblock	0x07
;***** VARIABLE DEFINITIONS
clock
data1
data0
latch
	endc



;**********************************************************************
RESET_VECTOR    CODE   0x3FF      ; processor reset vector

; Internal RC calibration value is placed at location 0x3FF by Microchip
; as a movlw k, where the k is a literal value.
    
MAIN    CODE    0x000
    movwf   OSCCAL            ; update register with factory cal value 


start   
;******** Main Code

start
		movlw   b'001000'       ; Configure only GP3 as a input
        tris    GPIO
        
loop

		call	LED1
		goto	loop


;******** Subroutines

clock
		movlw	b'000010'		; Clock set 1
		movwf	GPIO
		movlw	b'000000'		; Clock set 0
		movwf	GPIO
		retlw	0
		
data1	movlw	b'000001'		; Data pin high 
		movwf	GPIO
		retlw	0
		
data0	movlw	b'000000'		; Data pin low
		movwf	GPIO
		retlw	0
		
latch	movlw	b'000100'
		movwf	GPIO
		movlw	b'000000'
		movwf	GPIO
		retlw	0
		
LED1	call	data1
		call	clock
		call	data0
		call	clock
		call	data0
		call	clock
		call	data0
		call	clock
		call	data0
		call	clock
		call	data0
		call	clock
		call	data0
		call	clock
		call	data0
		call	clock
		call	latch
		retlw	0
		
	
	END					; End of Program !
Darkstar64 is offline  
Old 5th September 2008, 03:37 AM   #11
Default

Quote:
Originally Posted by Darkstar64 View Post
Not too sure what your getting at with the whole engine thing
What I mean by that is I built a piece of code (an engine) that takes whatever sequence of patterns that I build (that meet the requirements of the engine) and displays them. I don't have to mess with it - it just works. Feed it sequences of patterns and it makes it happen.

If I want just one LED on, I just feed it a single step pattern with that one LED bit set.

Quote:
If im correct you mean to make it so instead of calling like data1 data0 etc its just one call and it makes it all so like if I wanted LED1 on I would do something like this instead of what I have and im wondering is there a way to lets say just write it like this "10000000" then the pic then takes that and outputs it like that but adding the clock call in between each bite ? it might be easyer when making the cube then I won't have this long list of LED's and just be able to write it as one number and then the PIC takes it from there seperates it and then the Shift Register outputs it?
That's incredibly difficult to understand (ever heard of punctuation? try using some!), but I think I get the gist of what you're saying. Yes, that's an "engine". I just feed it a pointer to the pattern I want and it takes care of the rest.

Quote:
Just because its going to take alot of code and I don't think the PIC will be able to hold that much
It is a fair bit of code. My asm program to run my cube, with seven patterns, was around 954 bytes. Your 12F509 has 1024, so even if your code isn't as tight it should fit. You might have to lose a couple patterns. So what?

I could give you my code, but then you wouldn't learn anything. Also you'd probably have to almost completely rewrite to suit the 12F. My code is for 18F. It's an interesting and challenging piece of code for an intermediate newb to write. Makes you very happy when you finally get it to work.
__________________
=========================
Futz's Microcontrollers & Robotics
=========================

Last edited by futz; 5th September 2008 at 03:44 AM.
futz is offline  
Old 5th September 2008, 03:42 AM   #12
Default

k makes sense how would I then go about writing a engine to allow me to just give it a 8 bit sequence and it will take that and display it ? I'm srry im new to PIC's and just know some of the basic commands like changing bits to high,low and loops not too much of the other stuff srry like I can say it but I don't know how to write it thats the problem. Here is what im talking about for what I would like to do. Variable D is the 8 bit sequence that I want displayed

Move '100000000' into D
Take first bit, Change GPO to what first bit is
Clock it
Take second bit, Change GP0 to what second bit is
Clock it

etc...

Latch

Goto next sequence

Last edited by Darkstar64; 5th September 2008 at 03:47 AM.
Darkstar64 is offline  
Old 5th September 2008, 03:51 AM   #13
Default

Quote:
Originally Posted by Darkstar64 View Post
how would I then go about writing a engine to allow me to just give it a 8 bit sequence and it will take that and display it?
Umm... Put your brain in gear, get some scribble paper and calculator ready and start coding! Start small. Every time you get some section working, save that version of the source code with a different name so you can come back to it and start over if the next thing you do breaks things totally.

Quote:
I'm sorry. I'm new to PIC's and just know some of the basic commands like changing bits to high,low and loops not too much of the other stuff. Sorry.
This might be a bit much for you if you're still at the beginner stage. You'll need to be able to use and understand timers and interrupts to get this to work right.

EDIT
Quote:
Move '100000000' into D
Take first bit, Change GPO to what first bit is
Clock it
Take second bit, Change GP0 to what second bit is
Clock it

etc...

Latch

Goto next sequence
That's a start! Keep going!
__________________
=========================
Futz's Microcontrollers & Robotics
=========================

Last edited by futz; 5th September 2008 at 03:54 AM.
futz is offline  
Old 5th September 2008, 03:59 AM   #14
Default

haha can you atleast tell me how to take a single bit from a sequence after that everything should be simple thats the thing im stuck on
Darkstar64 is offline  
Old 5th September 2008, 04:05 AM   #15
Default

Quote:
Originally Posted by Darkstar64 View Post
haha can you atleast tell me how to take a single bit from a sequence after that everything should be simple thats the thing im stuck on
Use RLF or RRF to rotate the high or low bit (your choice) into the carry. Then do a check of the carry flag to see if it's 1 or 0 to determine what to put on the data pin to be shifted next.

There are other ways to do it too. Use your imagination.
__________________
=========================
Futz's Microcontrollers & Robotics
=========================
futz is offline  
Reply

Tags
pic, registers, shift, working

Thread Tools
Display Modes


Similar
Title Starter Forum Replies Latest
16 bit serial in parallel out shift registers forder Electronic Projects Design/Ideas/Reviews 14 2nd March 2009 09:17 AM
Cascading Shift Registers Help Suraj143 Electronic Projects Design/Ideas/Reviews 13 5th June 2008 08:33 AM
Load shift-registers via SPI? Mike, K8LH Micro Controllers 14 14th February 2008 03:00 AM
Help loading shift registers... jrz126 Micro Controllers 0 14th November 2005 01:13 PM
shift registers jrz126 Electronic Projects Design/Ideas/Reviews 8 25th September 2004 02:35 AM



All times are GMT. The time now is 08:29 PM.


Electronic Circuits  |  Learning Electronics
eXTReMe Tracker