Slave PIC to be used like CD4021 chip


Closed Thread
Results 1 to 18 of 18
  1. #1
    Join Date
    Nov 2003
    Location
    Greece
    Posts
    4,128

    Default Slave PIC to be used like CD4021 chip

    This is a little weird but, has anyone used a PIC as a slave device like the 4021 PISO (Parallel Input Serial Output)?

    I am trying to use some 4021 as Digital inputs and also get some analog values (8) and all read by the master controller through a Shiftin command.

    The idea is to use a 65 bit buffer, 64 bits for the 8x8bit analog values, and 1 bit for the input of the device, so other can connect on the bus, like another 4021 or another 8 analog input device.

    My main problem is how to shift the 65 bit array (preferably not in assembly...).

    Thanks,
    Ioannis

  2. #2
    skimask's Avatar
    skimask Guest


    Did you find this post helpful? Yes | No

    Default

    I don't see why it wouldn't work...as long as the PIC was clocked fast enough for you...
    I don't quite see what you're getting at as far as hardware though...
    Are you going to use a large PIC to get 64/65 bits and then shift them out, or the other way around?
    Could you draw up a rough block diagram?

  3. #3
    Join Date
    Sep 2005
    Location
    Campbell, CA
    Posts
    1,107


    Did you find this post helpful? Yes | No

    Default

    I have done what you describe. The "shifting" was done using SEROUT2 and SERIN2. The "master" PIC sent out 4 bytes of data (in my case) and the "slave" took the bytes
    and loaded them into a buffer. The data was followed by a checksum byte. If the checksum matched, the data was written to the port pins. I used a second wire between the two PICs to act as an ACK to indicate a successful trasmission (a pulse LOW was proof that the data got to the slave). The data rate was 19.2 kbaud. Crystals were used on both parts. I used open-collector drive on both lines and 2K pull-ups. The PICs were 6' or so apart.
    Charles Linquist

  4. #4
    skimask's Avatar
    skimask Guest


    Did you find this post helpful? Yes | No

    Default

    So, this might be something like an 18F8723, grabbing 64 bits worth of digital data from the various ports and funneling it out the serial port? A 64bit, single chip PISO?

  5. #5
    Join Date
    Sep 2005
    Location
    Campbell, CA
    Posts
    1,107


    Did you find this post helpful? Yes | No

    Default

    You apparently are aware of my "chip of choice"!
    Charles Linquist

  6. #6
    skimask's Avatar
    skimask Guest


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by Charles Linquis View Post
    You apparently are aware of my "chip of choice"!
    Started off with the 'broken' 8720, moved up along the way as they've came out.
    http://web.ndak.net/jdgrotte/tqfp648...fpadapter.html
    Use it a lot, especially when I need to write 'sloppy' code with a lot of debugging type info. I use the extra pins for LEDs, LCDs, switches, etc.
    Later on, clean up the code, get it down to size and put it on a 40 pin version of the '8723 (i.e. 18F452/4620/4685, whatever). Have a few of a second version that'll allow the '8723 to plug into a 28-pin socket. Same principle applies.
    Very few code changes required as long as I don't use an '8723 specific module or function.

  7. #7
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959


    Did you find this post helpful? Yes | No

    Default

    Now I read Ioannis' post very different.

    I think the idea looks something like this ...



    Where the PIC would have a 64-bit shift register, derived from 8 analog inputs, with a serial IN and OUT pin that would make it PART of a long chain of shift registers.

    Anywhere close Ioannis?
    <br>
    DT

  8. #8
    Join Date
    Nov 2003
    Location
    Greece
    Posts
    4,128


    Did you find this post helpful? Yes | No

    Default

    Hi Boys.

    I am sorry Skimask I did not put a schematic or something but was home, late night.

    Darrel, that was exaclty the idea and setup! I may say that except you are reading posts very clearly, I think you read minds too!

    Charles, your idea is really the oposite of this. And very dependent on the clock. With the circuit that I would post, but Darrel got me, as always he is one step ahead, there is no critical timing needed.

    So the PIC would need a 65 bit buffer to store the 64 bits of the analog values and 1 bit for the previous PISO device. This is not limited to one previous of course. PIC does not know what is before it. It just puts on Sout pin the data of its buffer. The buffer fills from the 8 analog and after that, with the Sin data as arrive on each Clock of the relative pin.

    It looks like RS232 serial communication but is not RS232. It is just serial 8 bit data transfer without start-stop bits and sychronous relative to the Clock line.

    The point for my difficulty is to shift in PBP the 65 bit buffer.

    Ioannis

    P.S. Sorry for the long post...

  9. #9
    Join Date
    Jul 2003
    Posts
    2,358


    Did you find this post helpful? Yes | No

    Default

    Simply treat the 64/65 bit buffer as a Byte or Word Array... Shift it out using the pointers I've given you here...

    http://www.picbasic.co.uk/forum/showthread.php?t=544

  10. #10
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959


    Did you find this post helpful? Yes | No

    Default

    I was just trying to visualize what it would take ...
    But it seems to have turned into a whole program.
    And yup, it uses Melanie's suggestions.

    The idea here is to continuously scan the A/D inputs, saving the results to a buffer array.
    When it gets a Parallel Load signal (INT), it copies the buffer to the "Shift" array.

    Instead of taking the time to actually shift everything each time, it uses an Index counting down from 63 to put each bit out on the pin.

    Each bit that is sent, gets replaced with the Input Bit. After it's finished sending all 64 bits, it wraps around and is now sending the data that was shifted IN like a big circular buffer.

    It's written for a 16F883, because it has 8+ A/D inputs and an internal 8mhz OSC, but it should work on other chips too (after changing a few things).

    I do not have a 16F883, or a CD4021, so this is completely untested.
    It does compile, and I think it's close. Should at least be a good starting point.

    Code:
    '****************************************************************
    '*  Name    : Shift4021.pbp                                     *
    '*  Author  : Darrel Taylor                                     *
    '*  Date    : 9/9/2008                                          *
    '*  Version : 1.0                                               *
    '*  Notes   : Target = 16F883, Internal 8mhz OSC                *
    '*  Thread  : Slave PIC to be used like CD4021 chip             *
    '*     http://www.picbasic.co.uk/forum/showthread.php?t=9544    *
    '****************************************************************
    @    __config _CONFIG1, _INTOSCIO & _WDT_OFF & _LVP_OFF & _CPD_OFF
    DEFINE OSC 8
    
    Clear
    
    PloadPin  VAR PORTB.0      ; Parallel Load (INT)
    ClkPin    VAR PORTB.1      ; Serial Clock
    SerInPin  VAR PORTB.2      ; Serial Input Pin
    SerOutPin VAR PORTB.3      ; Serial Output Pin
    
    ADbuff    VAR BYTE[8]      ; Buffers the A/D readings
    ShiftReg  VAR BYTE[8]      ; The 64-bit shift register
    
    I         VAR BYTE         ; Index variables
    X         VAR BYTE
    BitIdx    VAR BYTE
    ADidx     VAR BYTE
    ClkState  VAR BIT          ; for locating clk edges
    DataBit   VAR BIT          ; Serial In read on falling edge
    
    INTE      VAR INTCON.4     ; Aliases
    INTF      VAR INTCON.1
    GoDone    VAR ADCON0.1
    
    ;---------------------------------------------------------------------------
    Initialize:
        OSCCON = %01110001         ; Internal 8Mhz OSC
        INPUT PloadPin             ; Input(default), just to make sure
        INPUT ClkPin               
        INPUT SerInPin                 
        LOW   SerOutPin            ; start with output LOW
        ADCON0 = %10000001         ; FOSC/32, CH0, ADON
        ANSELH = 0                 ; Turn off upper A/D ports
        INTF = 0                   ; clear INT flag
        INTE = 1                   ; enable INT interrupt
        ON INTERRUPT goto ParallelLoad
    ;---------------------------------------------------------------------------
    Main:
        if !GoDone then NextAD     ; conversion complete, get results
        IF ClkPin then             ; wait for Rising edge
            if !ClkState then
                ClkState = 1 
                GOSUB NextBit      ;   Rising edge found, shift data
            endif
        else                       ; wait for falling edge
            if ClkState then
                ClkState = 0
                DataBit = SerInPin ;   falling edge found, read input
            endif
        endif
    GOTO Main
    
    ; ---- Cycle thru each A/D channel, one at a time --------------------------
    NextAD:
        ADbuff(ADidx) = ADRESH             ; save A/D result
        ADidx = ADidx + 1                  ; point to next A/D channel
        if ADidx = 8 then ADidx = 0        ; circle around
        ADCON0 = %10000001 | (ADidx << 2)  ; Set the A/D ch.
        for I = 1 to 5                     ; Acquisition time
            @ NOP
        NEXT I
        GoDone = 1                         ; Start A/D conversion
    RETURN
    
    DISABLE
    ; ---- Parallel Load -- copy A/D buffer to Shift register ------------------
    ParallelLoad:
        For X = 0 to 7                     ; Copy A/D results
            ShiftReg(X) = ADbuff(X)
        NEXT X
        SerOutPin = ShiftReg.0(63)         ; put MSB on Pin
        BitIdx = 63                        ; start shifting from MSB
        DataBit = SerInPin                 ; read input bit
        INTF = 0                           ; clear the interrupt flag
    RESUME
    
    ; ---- Put next bit on the output pin --------------------------------------
    NextBit:
        ShiftReg.0(BitIdx) = DataBit        ; replace bit with the input data
        BitIdx = BitIdx - 1                 ; point to next bit
        if BitIdx.7 = 1 then BitIdx = 63    ; circle back to beginning
        SerOutPin = ShiftReg.0(BitIdx)      ; put data on output Pin
    return
    HTH,
    Last edited by Darrel Taylor; - 10th September 2008 at 11:00. Reason: added ANSELH = 0, and X looop var
    DT

  11. #11
    Join Date
    Nov 2003
    Location
    Greece
    Posts
    4,128


    Did you find this post helpful? Yes | No

    Default

    Thank you all for the tips. Well, Darrel, it is more than a starting point. It is almost done! Thanks a lot. Also, yes 64 bit is OK. I stuck on 65 for some reason...

    Soon I will post the results.

    Ioannis

  12. #12
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959


    Did you find this post helpful? Yes | No

    Exclamation

    Just made a couple changes. I used the same loop var in the interrupt handler. DOH!
    Changed it to X, was I.

    Also turned off the upper A/D ports.
    ANSELH = 0

    2 less bugs anyways.
    <br>
    DT

  13. #13
    Join Date
    Nov 2003
    Location
    Greece
    Posts
    4,128


    Did you find this post helpful? Yes | No

    Default

    One more bug. On the main the first If/Then needs a gosub.

    I have to admit that your writing style is very clever. Especially I liked the handling of AD inputs with the OR statement. Very clever indeed!

    Thanks again!

    Ioannis

    Edit: Another bug would be the channel selection of A/D module. Since the 883 does not have 5,6 and 7 channel available, it cannot be used as it is the program. Of course it works as is for the bigger cousins 884 and 887.
    Last edited by Ioannis; - 10th September 2008 at 21:18.

  14. #14
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by Ioannis View Post
    One more bug. On the main the first If/Then needs a gosub.
    Ahhh, yes it does. Good catch.

    Another bug would be the channel selection of A/D module. Since the 883 does not have 5,6 and 7 channel available, it cannot be used as it is the program. Of course it works as is for the bigger cousins 884 and 887.
    DOH!

    I wish they'd make the datasheets individually. A separate one for each of the 882/883/884/886/887. Instead of jamming a whole series in one sheet so you have to pick out the differences on your own.

    OK, there's still more than 8 A/D's in there, I'll have to find a workaround.
    Unless you beat me to it.
    <br>
    DT

  15. #15
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959


    Did you find this post helpful? Yes | No

    Default Update

    Moved pins away from the RB1 - RB3 (AN8 - AN10).

    Added GOSUB you found.

    Modified A/D channel selection.

    Sure wish I had one of these chips. BTW, will you be using a different chip?
    Code:
    '****************************************************************
    '*  Name    : Shift4021.pbp                                     *
    '*  Author  : Darrel Taylor                                     *
    '*  Date    : 9/9/2008                                          *
    '*  Version : 1.1                                               *
    '*  Notes   : Target = 16F883, Internal 8mhz OSC                *
    '*  Thread  : Slave PIC to be used like CD4021 chip             *
    '*     http://www.picbasic.co.uk/forum/showthread.php?t=9544    *
    '****************************************************************
    @    __config _CONFIG1, _INTOSCIO & _WDT_OFF & _LVP_OFF & _CPD_OFF
    DEFINE OSC 8
    
    Clear
    
    PloadPin  VAR PORTB.0      ; Parallel Load (INT)
    ClkPin    VAR PORTB.4      ; Serial Clock
    SerInPin  VAR PORTB.5      ; Serial Input Pin
    SerOutPin VAR PORTB.6      ; Serial Output Pin
    
    ADbuff    VAR BYTE[8]      ; Buffers the A/D readings
    ShiftReg  VAR BYTE[8]      ; The 64-bit shift register
    
    I         VAR BYTE         ; Index variables
    X         VAR BYTE
    BitIdx    VAR BYTE
    ADidx     VAR BYTE
    ADchannel VAR BYTE         ; Actual AD ch being used (5,6,7 missing)
    ClkState  VAR BIT          ; for locating clk edges
    DataBit   VAR BIT          ; Serial In read on falling edge
    
    INTE      VAR INTCON.4     ; Aliases
    INTF      VAR INTCON.1
    GoDone    VAR ADCON0.1
    
    ;---------------------------------------------------------------------------
    Initialize:
        OSCCON = %01110001         ; Internal 8Mhz OSC
        INPUT PloadPin             ; Input(default), just to make sure
        INPUT ClkPin               
        INPUT SerInPin                 
        LOW   SerOutPin            ; start with output LOW
        ADCON0 = %10000001         ; FOSC/32, CH0, ADON
        ANSELH = %00000111         ; Turn off upper A/D ports (8,9,10 used)
        INTF = 0                   ; clear INT flag
        INTE = 1                   ; enable INT interrupt
        ON INTERRUPT goto ParallelLoad
    ;---------------------------------------------------------------------------
    Main:
        if !GoDone then GOSUB NextAD   ; conversion complete, get results
        IF ClkPin then                 ; wait for Rising edge
            if !ClkState then
                ClkState = 1 
                GOSUB NextBit          ;   Rising edge found, shift data
            endif
        else                           ; wait for falling edge
            if ClkState then
                ClkState = 0
                DataBit = SerInPin     ;   falling edge found, read input
            endif
        endif
    GOTO Main
    
    ; ---- Cycle thru each A/D channel, one at a time --------------------------
    NextAD:
        ADbuff(ADidx) = ADRESH             ; save A/D result
        ADidx = ADidx + 1                  ; point to next A/D channel
        if ADidx = 8 then ADidx = 0        ; circle around
        ADchannel = ADidx
        if ADidx > 4 then 
            ADchannel = ADchannel + 3      ; correct for missing AN 5,6,7
        endif   
        ADCON0 = %10000001 | (ADchannel << 2)  ; Set the A/D ch.
        for I = 1 to 5                     ; Acquisition time
            @ NOP
        NEXT I
        GoDone = 1                         ; Start A/D conversion
    RETURN
    
    DISABLE
    ; ---- Parallel Load -- copy A/D buffer to Shift register ------------------
    ParallelLoad:
        For X = 0 to 7                     ; Copy A/D results
            ShiftReg(X) = ADbuff(X)
        NEXT X
        SerOutPin = ShiftReg.0(63)         ; put MSB on Pin
        BitIdx = 63                        ; start shifting from MSB
        DataBit = SerInPin                 ; read input bit
        INTF = 0                           ; clear the interrupt flag
    RESUME
    
    ; ---- Put next bit on the output pin --------------------------------------
    NextBit:
        ShiftReg.0(BitIdx) = DataBit        ; replace bit with the input data
        BitIdx = BitIdx - 1                 ; point to next bit
        if BitIdx.7 = 1 then BitIdx = 63    ; circle back to beginning
        SerOutPin = ShiftReg.0(BitIdx)      ; put data on output Pin
    return
    DT

  16. #16
    Join Date
    Nov 2003
    Location
    Greece
    Posts
    4,128


    Did you find this post helpful? Yes | No

    Default

    Thank Darrel. You tempted me to use the new 88x series as I am used to the old 87x ones. But I had a look over the 16F690 and I think is the best for the job and cheaper too. It has the RS-Flip Flop also for anyone willing to do Touch sensors for buttons.

    Thanks for the efforts very much.

    Ioannis

  17. #17
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959


    Did you find this post helpful? Yes | No

    Default

    16F690!

    Dang it, don't have one of those either.
    I really need to expand my inventory.

    Looks like it'll do the job for sure.
    Hope it all works out.

    DT

  18. #18
    Join Date
    Nov 2003
    Location
    Greece
    Posts
    4,128


    Did you find this post helpful? Yes | No

    Default

    Thanks again. You are #1!

    Ioannis

Similar Threads

  1. ShiftOut. Using PIC as Slave device.
    By TonyA in forum mel PIC BASIC Pro
    Replies: 4
    Last Post: - 16th March 2010, 19:10
  2. Reading a slave USB with a pic
    By pcaccia in forum mel PIC BASIC Pro
    Replies: 7
    Last Post: - 25th October 2008, 12:00
  3. Camera with PIC chip
    By The Master in forum Off Topic
    Replies: 5
    Last Post: - 1st July 2008, 14:28
  4. PIC chip resetting. Very weird
    By The Master in forum Off Topic
    Replies: 0
    Last Post: - 28th October 2007, 17:07
  5. Use pic as slave in I2C
    By robert0 in forum General
    Replies: 2
    Last Post: - 3rd February 2006, 19:26

Members who have read this thread : 0

You do not have permission to view the list of names.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts