1. 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.
    Dismiss Notice

Working with Shift Registers and a PIC help

Discussion in 'Microcontrollers' started by Darkstar64, Sep 4, 2008.

  1. Darkstar64

    Darkstar64 New Member

    Joined:
    Apr 3, 2008
    Messages:
    112
    Likes:
    0
    Ok I got it working im so happy haha now I finally can move on to the overall project thanks alot guys for your help and patience. Also can you explain INDF and FSR a little and how I go about setting things to the FSR and reading it from the INDF. Im sure I will be using it later as my code gets longer and I need to simplify things a little and as you said I will need it to go above basic's.
     
  2. futz

    futz Active Member

    Joined:
    Sep 15, 2007
    Messages:
    2,043
    Likes:
    24
    Location:
    Vancouver, B.C.
    Here's the super simple explanation: Load FSR with the address of the value you want to read/write. Then when you read/write INDF you're actually reading what's stored at the byte pointed to by FSR. It's called indirect addressing. With it you can step through bunches of variables by incrementing (or decrementing) the FSR each time you read/write. In my 4x4x4 program I use it to point to the correct set of cathode variables. They're in pairs, so I just add 2 to FSR each time the "ISR" routine hits (of course resetting to the beginning every 4 times).

    Note how I load a variable's address into W (not what's stored there, but the address of the variable) and then move W into the FSR reg.
    Code (text):
        movlw   cath1a      ;cathode pointer storage
        movwf   FSR
     
    Then I can use INDF to read that variable, and by simply incrementing FSR I can access successive variables.
    Code (text):
    mloop   movf    offset,w    ;get a byte of new pattern
        call    patt3
        movwf   INDF
        incf    offset,f    ;increment pointers
        incf    FSR,f
     
     
    Last edited: Oct 4, 2008
  3. Darkstar64

    Darkstar64 New Member

    Joined:
    Apr 3, 2008
    Messages:
    112
    Likes:
    0
    ok thanks alot thanks alot one problem though is FSR only shows up as a variable when typed in like movwf FSR all have to fiddle around anyways its getting late thanks alot once again for the help everything is working now with no problems
     
  4. dave

    Dave New Member

    Joined:
    Jan 12, 1997
    Messages:
    -
    Likes:
    0


     
  5. Darkstar64

    Darkstar64 New Member

    Joined:
    Apr 3, 2008
    Messages:
    112
    Likes:
    0

    Quick simple question since I have everything working now I'm trying to use rrf to move the 1 over to the right '10000000' with this string now basically I wanted the LED's to go around the outside once then go down to the next layer then do it again here is my code will this work at all ? I just don't know if the rrf is moving what it does into temp ?

    Code (text):

        #include <P12F509.inc>
        __CONFIG _MCLRE_ON & _WDT_OFF & _IntRC_OSC

        cblock  0x07
        count,temp
        dc1
        dc2
        dc3
        count1
        rot
        endc

            org 0x000
    main            movlw   b'11001000' ;clear T0CS for output on GPIO2
            option
            movlw   b'00001000' ;set pins to all outs
            tris    GPIO
            movlw   .08
            movwf   count1
    upperla movlw   b'10000000' ; Shifts out all 8 bits to second shift register for the layer's
            movwf   temp
            call    shift5
            movlw   b'1000000'
            movwf   rot
            rlf     rot,f ; Shifts out 8 bits to the first shift register lighing one led every loop
            movwf   temp
            call    shift5
            movlw   .05
            call    delay10
            decfsz  count1,f
            goto    upperla
            call    latch
    midla           movlw   b'01000000'
            movwf   temp
            movlw   b'1000000'
            movwf   rot
            rlf     rot,f ; Shifts out 8 bits to the first shift register lighing one led every loop
            movwf   temp
            call    shift5
            movlw   .05
            call    delay10
            decfsz  count1,f
            goto    midla
            call    latch
    lowerla movlw   b'01000000'
            movwf   temp
            movlw   b'1000000'
            movwf   rot
            rlf     rot,f ; Shifts out 8 bits to the first shift register lighing one led every loop
            movwf   temp
            call    shift5
            movlw   .05
            call    delay10
            decfsz  count1,f
            goto    lowerla
            call    latch
           
            goto    main

     
     
    Last edited: Oct 6, 2008
  6. futz

    futz Active Member

    Joined:
    Sep 15, 2007
    Messages:
    2,043
    Likes:
    24
    Location:
    Vancouver, B.C.
    Huh? You have no RRF's in that piece of code. Nope, not a single one. :p Neither RLF in that code puts anything in temp. Both of them rotate the high bit of rot into the Carry.

    I see more problems too. Here you're loading rot each time thru the loop and then rotating one bit into the carry. Then you load it again and shift the high bit again. What is that supposed to accomplish?

    Also, you're loading a 7-bit value on the red line. Did you mean to load '01000000'? Because that's what you're doing. You probably missed a zero.
    Code (text):
    midla           movlw   b'01000000'
            movwf   temp
    [COLOR="Red"]       movlw   b'1000000'[/COLOR]
            movwf   rot
            rlf     rot,f
     
    Last edited: Oct 6, 2008
  7. Darkstar64

    Darkstar64 New Member

    Joined:
    Apr 3, 2008
    Messages:
    112
    Likes:
    0
    I did I just didn't update the code here I forgot to im trying to just cycle it though so I don't have to type all the lines of code I was just thinking I could use rrf to rotate the high bit 8 times to the right and each time it moves it moves it back into temp and runs the shift5 so it basically cycles though all 8 LED's on each layer one layer at a time so it does what you have on yours but with less lines allowing me to make more patterns ? can you help me come up with the code ? im using 2 shift registers so here is the updated code I don't know what to put after the rlf line and the first string is what layer is on

    Code (text):

        #include <P12F509.inc>
        __CONFIG _MCLRE_ON & _WDT_OFF & _IntRC_OSC

        cblock  0x07
        count,temp
        dc1
        dc2
        dc3
        count1
        rot
        endc

            org 0x000
    main    movlw   b'11001000' ;clear T0CS for output on GPIO2
            option
            movlw   b'00001000' ;set pins to all outs
            tris    GPIO
            movlw   .08
            movwf   count1
            movlw   b'10000000'
            movwf   rot
    upperla movlw   b'10000000' ; Shifts out all 8 bits to second shift register for the layer's
            movwf   temp
            call    shift5
            rlf     rot,f ; Shifts out 8 bits to the first shift register lighing one led every loop
            ?
            call    shift5
            movlw   .05
            call    delay10
            decfsz  count1,f
            goto    upperla
            call    latch
    midla   movlw   b'01000000'
            movwf   temp
            rlf     rot,f ; Shifts out 8 bits to the first shift register lighing one led every loop
            ?
            call    shift5
            movlw   .05
            call    delay10
            decfsz  count1,f
            goto    midla
            call    latch
    lowerla movlw   b'00100000'
            movwf   temp
            rlf     rot,f ; Shifts out 8 bits to the first shift register lighing one led every loop
            ?
            call    shift5
            movlw   .05
            call    delay10
            decfsz  count1,f
            goto    lowerla
            call    latch
           
            goto    main
     
    Last edited: Oct 6, 2008
  8. futz

    futz Active Member

    Joined:
    Sep 15, 2007
    Messages:
    2,043
    Likes:
    24
    Location:
    Vancouver, B.C.
    I don't know what you're talking about. You'll have to explain what you mean more clearly. What does shift5 do?

    It sounds like you want to "multiplex" each LED individually. You might get that to work on a very small display, but more likely it'll either be very dim or it'll flicker badly.

    How do you build a LED cube with 8 LEDs per layer? Is it rectangular?


    No. Write your own code. :D:D:D You sound like those guys that PM me all the time trying to get me to do their homework for them. :p
     
    Last edited: Oct 6, 2008
  9. Darkstar64

    Darkstar64 New Member

    Joined:
    Apr 3, 2008
    Messages:
    112
    Likes:
    0
    No haha I didn't mean it that way im just not sure how to write the value that the rlf spits out to temp shift5 is the start of the engine that takes the 8 bits and sends each bit to the shift register haha you wrote some of the code I just changed it to my needs basically I want to do what you did with your 4x44 cube starting on the top layer lighting each LED one at a time hence the rlf to move the high bit over one to the right then go to the next layer and do the same and so on for the three layers I have a 3x3x3 cube make any sense ?
     
  10. futz

    futz Active Member

    Joined:
    Sep 15, 2007
    Messages:
    2,043
    Likes:
    24
    Location:
    Vancouver, B.C.
    An RLF command doesn't spit out any value. It rotates the bits in the target byte (rot?) through the carry. So after an RLF, rot is still rot, only one of its bits is in the carry and the rest have shifted over by one bit.

    I think I kind of see what you're trying to do (maybe). You want to "multiplex" each LED individually. You might get that to work on a very small display, but more likely it'll either be very dim or it'll flicker badly.

    But even that won't work, as you'd need 28 control lines. Common anode and one cathode per LED. That's a lot of wires! The reason for multiplexing is to reduce complexity (way fewer control wires).

    Hmm... After thinking about it some more... I still don't get what you're trying to do there. You don't care about doing patterns? You just want to rotate bits and display them? Huh? And how are you handling your 9th bit (it's a 3x3 cube. 3x3 = 9)?

    No. How do you build a LED cube with 8 LEDs per layer? Is it rectangular? :p
     
    Last edited: Oct 6, 2008
  11. futz

    futz Active Member

    Joined:
    Sep 15, 2007
    Messages:
    2,043
    Likes:
    24
    Location:
    Vancouver, B.C.
    Or do you mean you want to enable one layer at a time (common anode or cathode) and then multiplex through all 9 LEDs one at a time before switching to the next layer?

    That's crazy! Too much work. And the cube will be dim and/or flickery. You won't save any time or code size.

    Do it right. Set up all bits for each level. Cycle through the levels quickly (multiplexing), setting the correct individual 9-bits of LED control lines for each level as they get enabled.
     
  12. Darkstar64

    Darkstar64 New Member

    Joined:
    Apr 3, 2008
    Messages:
    112
    Likes:
    0
    There's only 8 bits for this pattern because the inside/center Led is never on basically im just trying to cycle though the outside LED's one at a time on each layer so let me try to explain it better hence the rotation of the string of bits so I only need to have 4-10 lines of code per layer instead of writing the lines for each led to be turned on does this make any sense at all ? I need the rrf to move it so its like this as well there is too examples I used to try to explain it below only one led is on at all times but the rrf is used to move the high bit to the right and then I need something that puts the whole string into temp for it to be shifted out ?

    10000000
    -moves string into temp for LED 1 to go light up
    01000000
    -moves string into temp for LED 2 to go light up
    00100000
    -moves string into temp for LED 3 to go light up
    00010000
    -moves string into temp for LED 4 to go light up
    00001000
    -moves string into temp for LED 5 to go light up
    00000100
    -moves string into temp for LED 6 to go light up
    00000010
    -moves string into temp for LED 7 to go light up
    00000001
    -moves string into temp for LED 8 to go light up

    -start of code/int
    -first led lit on top layer
    -delay
    -turns off
    -second led lit on top layer
    -delay
    -turns off
    -third led lit on top layer
    -delay
    -turns off
    -forth led lit on top layer
    -delay
    -turns off
    -fith led lit on top layer
    -delay
    -turns off
    -sixth led lit on top layer
    -delay
    -turns off
    -seventh led lit on top layer
    -delay
    -turns off
    -eight led lit on top layer
    -delay
    -turns off
    -first led lit on mid layer
    -delay
    -turns off
    -second led lit on mid layer
    -delay
    -turns off
    -third led lit on mid layer
    -delay
    -turns off
    -forth led lit on mid layer
    -delay
    -turns off
    -fith led lit on mid layer
    -delay
    -turns off
    -sixth led lit on mid layer
    -delay
    -turns off
    -seventh led lit on mid layer
    -delay
    -turns off
    -eight led lit on mid layer
     
  13. skyhawk

    skyhawk New Member

    Joined:
    Feb 9, 2007
    Messages:
    235
    Likes:
    7
    Location:
    Morgantown, WV
    If you are just trying to cycle the LEDs in a layer, why not clock out a one and latch it to light the first LED. After the delay clock out a zero shifting the one in the shift register. Then latch, delay and repeat until the one has been shifted out of the shift register.

    OK, I see this won't work if you've cascaded shift registers to get 12 bits of output.
     
    Last edited: Oct 7, 2008
  14. futz

    futz Active Member

    Joined:
    Sep 15, 2007
    Messages:
    2,043
    Likes:
    24
    Location:
    Vancouver, B.C.
    OK, now I get what you were ranting about! :p What you want to do is do your RRF, then check the carry and change the high bit of the byte you RRFed to match ("move" the bit from the carry to the byte), then get the byte in W (movf rot,w) and store it in temp (movwf temp). Simple.

    Once again, a byte is NOT a string. It's a byte. :D
     
  15. AtomSoft

    AtomSoft Well-Known Member

    Joined:
    Feb 7, 2008
    Messages:
    5,670
    Likes:
    41
    Location:
    Brooklyn, NY US
    whats a good Shift Register where i can control a MINIMUM of 35 LED's? Today is shopping day lol

    EDIT:

    Alsot I need another shift register with a minimum of 9 outputs. Any Thoughts?
     
    Last edited: Oct 8, 2008
  16. futz

    futz Active Member

    Joined:
    Sep 15, 2007
    Messages:
    2,043
    Likes:
    24
    Location:
    Vancouver, B.C.
    Micrel MM5451YN

    HEF4894B by NXP. It's a 12-stage open drain chip.
     
    Last edited: Oct 8, 2008
  17. AtomSoft

    AtomSoft Well-Known Member

    Joined:
    Feb 7, 2008
    Messages:
    5,670
    Likes:
    41
    Location:
    Brooklyn, NY US
    thanks futz. Ill be sure to add them to the list.
     
  18. Darkstar64

    Darkstar64 New Member

    Joined:
    Apr 3, 2008
    Messages:
    112
    Likes:
    0
    Im a little confused what I think your getting at is first RRF, then test the carry flag, then move the bit in the carry flag to w, then move w too temp ? something like that im a little confused about getting the byte from w and what not ? But other then this I have a few pattern's working right now im soon going to go to the 4x4x4 Cube in hopes of going bigger after that and probably upgrading the PIC
     
    Last edited: Oct 12, 2008
  19. AtomSoft

    AtomSoft Well-Known Member

    Joined:
    Feb 7, 2008
    Messages:
    5,670
    Likes:
    41
    Location:
    Brooklyn, NY US
    im going to try a 4x4x4 in about a week and a month after that ill try a 8x8x8. Thats 512 LEDs. Thats gonna be fun. Maybe (MAYBE) ill try a 16x16x16 or just make a large table top design to go under my table and a clear glass over it and have a moving table :D but if i do ill be sure to use multiple (2-RB or 3-RGB) color leds. for a table it would be so nice with PWM control so i can control dimness.
     
  20. Darkstar64

    Darkstar64 New Member

    Joined:
    Apr 3, 2008
    Messages:
    112
    Likes:
    0
    Nice I was going to do the same thing with the table but use some cheap bright red LED's with some motion sensor's/light sensor's to detect when something is placed on the table then light the led's under it something like that but I still need to understand what fuz is talking about haha
     
  21. AtomSoft

    AtomSoft Well-Known Member

    Joined:
    Feb 7, 2008
    Messages:
    5,670
    Likes:
    41
    Location:
    Brooklyn, NY US
    lol its funny i was going to use a blocked off light sensor like a photo resistor to determine if something is on the table. . The thing is i was goingg to make it look like a ball was bouncing around the table and when ever a object (light is blocked) it wil bounce off that surface.
     

Share This Page