+ Reply to Thread
Page 1 of 7
1 2 3 4 5 ... Last
Results 1 to 15 of 101

Thread: Working with Shift Registers and a PIC help

  1. #1
    Darkstar64 Newbie
    Join Date
    Apr 2008
    Posts
    111

    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.


  2. #2
    Papabravo Excellent Papabravo Excellent Papabravo Excellent Papabravo Excellent Papabravo Excellent Papabravo Excellent Papabravo Excellent
    Join Date
    Mar 2006
    Location
    Michigan, USA (GMT-5)
    Posts
    2,892

    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.

  3. #3
    futz Excellent futz Excellent futz Excellent futz Excellent futz Excellent futz Excellent futz Excellent
    Join Date
    Sep 2007
    Location
    Vancouver, B.C.
    Posts
    1,980

    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
    =========================

  4. #4
    Darkstar64 Newbie
    Join Date
    Apr 2008
    Posts
    111

    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 ?

  5. #5
    futz Excellent futz Excellent futz Excellent futz Excellent futz Excellent futz Excellent futz Excellent
    Join Date
    Sep 2007
    Location
    Vancouver, B.C.
    Posts
    1,980

    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.
    Last edited by futz; 5th September 2008 at 01:02 AM.
    =========================
    Futz's Microcontrollers & Robotics
    =========================

  6. #6
    Darkstar64 Newbie
    Join Date
    Apr 2008
    Posts
    111

    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.

  7. #7
    futz Excellent futz Excellent futz Excellent futz Excellent futz Excellent futz Excellent futz Excellent
    Join Date
    Sep 2007
    Location
    Vancouver, B.C.
    Posts
    1,980

    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?

    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).

    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.
    Last edited by futz; 5th September 2008 at 01:49 AM.
    =========================
    Futz's Microcontrollers & Robotics
    =========================

  8. #8
    Darkstar64 Newbie
    Join Date
    Apr 2008
    Posts
    111

    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.

  9. #9
    futz Excellent futz Excellent futz Excellent futz Excellent futz Excellent futz Excellent futz Excellent
    Join Date
    Sep 2007
    Location
    Vancouver, B.C.
    Posts
    1,980

    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.

    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.

    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
    
    Last edited by futz; 5th September 2008 at 03:20 AM.
    =========================
    Futz's Microcontrollers & Robotics
    =========================

  10. #10
    Darkstar64 Newbie
    Join Date
    Apr 2008
    Posts
    111

    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 !
    

  11. #11
    futz Excellent futz Excellent futz Excellent futz Excellent futz Excellent futz Excellent futz Excellent
    Join Date
    Sep 2007
    Location
    Vancouver, B.C.
    Posts
    1,980

    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.

    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.

    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.
    Last edited by futz; 5th September 2008 at 03:44 AM.
    =========================
    Futz's Microcontrollers & Robotics
    =========================

  12. #12
    Darkstar64 Newbie
    Join Date
    Apr 2008
    Posts
    111

    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.

  13. #13
    futz Excellent futz Excellent futz Excellent futz Excellent futz Excellent futz Excellent futz Excellent
    Join Date
    Sep 2007
    Location
    Vancouver, B.C.
    Posts
    1,980

    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.

    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
    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!
    Last edited by futz; 5th September 2008 at 03:54 AM.
    =========================
    Futz's Microcontrollers & Robotics
    =========================

  14. #14
    Darkstar64 Newbie
    Join Date
    Apr 2008
    Posts
    111

    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

  15. #15
    futz Excellent futz Excellent futz Excellent futz Excellent futz Excellent futz Excellent futz Excellent
    Join Date
    Sep 2007
    Location
    Vancouver, B.C.
    Posts
    1,980

    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
    =========================

+ Reply to Thread
Page 1 of 7
1 2 3 4 5 ... Last

Similar Threads

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

Tags for this Thread