Port alias in Port Expanders (MCP23S17)


Closed Thread
Results 1 to 19 of 19
  1. #1
    Join Date
    Sep 2007
    Location
    Waco, Texas
    Posts
    151

    Default Port alias in Port Expanders (MCP23S17)

    Hello to All-
    I am trying to do something and I just can't break through the fog to see how this may be accomplished;
    Assign an alias to a port pin on a port expander.
    I know how to do it with a port/pin on the uProc but I just can't figure it out.
    The port expander is using SPI and each expander has its own chip select.
    How can you alias GPB.2 on chip2 from GPB.2 on chip3?
    What am I missing? Can it be done? Should it be done?
    I get that aliasing is somewhat lazy but it makes for clear code!

    Anyone done this?
    -Stumped......
    "If we knew what we were doing, it wouldn't be called research"
    - Albert Einstein

  2. #2
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,520


    Did you find this post helpful? Yes | No

    Default Re: Port alias in Port Expanders (MCP23S17)

    Hi,
    Since it's on a bus external to the PIC itself you are NOT going to do things like GPB.2 = 1 to "get at" the output directly since the actual data needs to be transfered to the external chip using SHIFTOUT or the MSSP module or whatever. I suspect you know that but wanted to get it squared away just in case.

    Since the port expander is on the SPI bus you're sending it one or more bytes. I'm guessing that one (or more) of those bytes reflects the desired state of the outputs on the expander. (Had you said which chip you're using I could've been more specific).

    So if you have a byte called ChipOne then you can alias each bit as usual ChipOne.0 = 1 but then you obviously need to transfer ChipOne to chip one. If you had a timer interrupt sending the byte to the expander x timer per second then doing ChipOne.4 = 1 might be fast/transparent enough - I don't know.

    /Henrik.

  3. #3
    Join Date
    Sep 2007
    Location
    Waco, Texas
    Posts
    151


    Did you find this post helpful? Yes | No

    Default Re: Port alias in Port Expanders (MCP23S17)

    Thanks, yes I did say which chip in the topic.... <grin>.
    And yes again, that is what I had come up with and I had used that in the past - using
    outputs var byte[4]
    and then indexing by just what you said -> outputs[0].4 = 1 or whatever.
    Just thought there may be other solutions....... more minds the better!
    Thanks for the input, I appreciate it.
    "If we knew what we were doing, it wouldn't be called research"
    - Albert Einstein

  4. #4
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,520


    Did you find this post helpful? Yes | No

    Default Re: Port alias in Port Expanders (MCP23S17)

    Ooops, I missed the topic, sorry about that!

    I guess I don't see the problem then....sorry about that as well :-)

    /Henrik.

  5. #5
    Join Date
    Sep 2007
    Location
    Waco, Texas
    Posts
    151


    Did you find this post helpful? Yes | No

    Default Re: Port alias in Port Expanders (MCP23S17)

    Henrik-
    I may have been too hasty in my description ( I am back on my home project) as I am stumped. I had used the I2C version of this part a while back and have it working. Now I am trying to use the SPI version (MCP23S17) for its speed and I can't seem to figure out how to get from a byte indicating which bit to turn on for the MCP23S17 part.
    Lets say I receive a var and it's value is $E. This var needs to tell the MCP23S17 that the 15th output should turn on. Now that is GPB-7 on the MCP23S17.
    I have a routine that converts HEX to DECIMAL (thanks to this forum years ago) and that works fine, how to I get a single decimal to go to the correct port on the MCP23S17?
    My code works fine to send a binary string (easier to visualize for me) to the MCP23S17 but I can't seem to get the finesse of going from 1 hex or 1 dec char to the right bit output.
    I have looked through the forum and I have seen yours and others pointing to OUT.0[var] which gets to the VAR-position of the OUT variable but as I have 2 eight bit outputs I am stumped......

    From the MCP23S17 datasheet it looks like it may be addressed as one 16 bit output, is that accurate? Any suggestions?
    Some code below:
    Code:
    OutA var byte
    
    OUTtest:'------------ TEST
                          OutA=$1                                                  'Simulate number from serial comm, example '1'
                          K=OutA                                                   'Sets up the conversion from hex to decimal
                          gosub H2D                                               'Performs the conversion
                          debug "After H2D K=",dec1 K,13               'Double-check what the sub did
                          k=k-8                                                        'try this for a pointer
                          OutA_DataOut=OutA.0[k]                        'Try to set the correct bit out of 8 to turn on and pass to OutA_DataOut which is passed to the MCB23S17
                            OutA_MCPReg = OLATA                             'Sets up PORTA output
    '                        OutA_DataOut=%11111110                    'This works by setting individual bits, but not good for what I want to do
                            gosub SEND_OutA_2317                         'Send to the expander
                            pause 10                                               'wait a bit
                            OutA_MCPReg = OLATB                             'Sets up PORTB output
                            OutA_DataOut=%01111111
                            gosub SEND_OutA_2317
    "If we knew what we were doing, it wouldn't be called research"
    - Albert Einstein

  6. #6
    Join Date
    Sep 2007
    Location
    Waco, Texas
    Posts
    151


    Did you find this post helpful? Yes | No

    Default Re: Port alias in Port Expanders (MCP23S17)

    Henrik-
    Also forgot to mention that in the older I2C design I had 8 bits of inputs and 8 bits of outputs on one 2317.
    This new design is all outputs - I thought it would be easier!
    Not so much......
    Regards,
    Steve
    "If we knew what we were doing, it wouldn't be called research"
    - Albert Einstein

  7. #7
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,520


    Did you find this post helpful? Yes | No

    Default Re: Port alias in Port Expanders (MCP23S17)

    Sounds like what you're looking for is the DCD operator:
    DCD returns the decoded value of a bit number. It changes a bit number (0 - 31) into a binary number with only that bit set to 1. All other bits are set to 0.
    B0 = DCD 2 ' Sets B0 to %00000100
    So, perhaps something:
    Code:
    OutBits VAR WORD
      GPA VAR OutBits.BYTE0
      GPB VAR OutBits.BYTE1
    
    Outbits = DCD $E
    Henrik.

  8. #8
    Join Date
    Sep 2007
    Location
    Waco, Texas
    Posts
    151


    Did you find this post helpful? Yes | No

    Default Re: Port alias in Port Expanders (MCP23S17)

    Thanks I will try that!

    I have made some progress but I still need a way to get from 1 byte which will tell me which of the 16 outputs to turn on.

    Current test code:
    Code:
                          OutA=$FFFE                                        'Initial value for word var                      
                          OutA_hi=OutA.highbyte                             'Splits into hibyte
                          OutA_lo=OutA.lowbyte                              'And into low byte of the word var
                          OutA_lo.3=0                                       'Bit mod
                          OutA_hi.5=0                                       'Another bit mod
                            OutA_MCPReg = OLATA                             'Sets up PORTA output
                            OutA_DataOut=OutA_lo                            'Sets up data to be pushed to the MCP23S17 as the low byte
                            gosub SEND_OutA_2317                            'Send it
                            pause 10                                        'Wait a bit
                            OutA_MCPReg = OLATB                             'Sets up PORTB output
                            OutA_DataOut=OutA_hi                            'Sets up data to be pushed to the MCP23S17 as the hi byte
                            gosub SEND_OutA_2317                            'Send it
    This gives me what I want - EXCEPT - for that I have to resolve 1 byte into a word and figure out how to get the pointer right........
    starting with a byte var which has a value from 0-15 to a specific bit on the MCP23S17 still evades me I am afraid.
    "If we knew what we were doing, it wouldn't be called research"
    - Albert Einstein

  9. #9
    Join Date
    Sep 2007
    Location
    Waco, Texas
    Posts
    151


    Did you find this post helpful? Yes | No

    Default Re: Port alias in Port Expanders (MCP23S17)

    Henrik-
    Thanks for the assist, but I don't think I can use that idea. There are some outputs which will be already active which another serial command comes in and I will need to add to the already ON LEDs with whatever new ones are called for.
    There is a serial comm line coming into the project and on that serial comm is a byte which will let me know which output(s) to turn on. Some may or may not be on.
    So, I will have to logically AND them to get the correct outputs on when they need to be.
    "If we knew what we were doing, it wouldn't be called research"
    - Albert Einstein

  10. #10
    Join Date
    Sep 2007
    Location
    Waco, Texas
    Posts
    151


    Did you find this post helpful? Yes | No

    Default Re: Port alias in Port Expanders (MCP23S17)

    Why does this not work?
    OutA.12=0 doesn't gen an error but it nor the other (OutA.15=0) turns ON an LED?????

    Code:
                          OutA=$FFFE                                        'Initial value for word var                      
                          OutA_hi=OutA.highbyte                             'Splits into hibyte
                          OutA_lo=OutA.lowbyte                              'And into low byte of the word var
    '                      OutA_lo.3=0                                       'Bit mod - WORKS
    '                      OutA_hi.5=0                                       'Another bit mod - WORKS
                          OutA.12=0      'Why doesn't this work?
                          OutA.15=0      'Or this?
                            OutA_MCPReg = OLATA                             'Sets up PORTA output
                            OutA_DataOut=OutA_lo                            'Sets up data to be pushed to the MCP23S17 as the low byte
                            gosub SEND_OutA_2317                            'Send it
                            pause 10                                        'Wait a bit
                            OutA_MCPReg = OLATB                             'Sets up PORTB output
                            OutA_DataOut=OutA_hi                            'Sets up data to be pushed to the MCP23S17 as the hi byte
                            gosub SEND_OutA_2317                            'Send it
    "If we knew what we were doing, it wouldn't be called research"
    - Albert Einstein

  11. #11
    Join Date
    May 2013
    Location
    australia
    Posts
    2,388


    Did you find this post helpful? Yes | No

    Default Re: Port alias in Port Expanders (MCP23S17)

    OutA_hi=OutA.highbyte 'Splits into hibyte
    OutA_lo=OutA.lowbyte 'And into low byte of the word var
    is a simple assignment operation not an alias

    OutA=$FFFE 'Initial value for word var
    OutA.12=0
    OutA.15=0
    OutA_hi=OutA.highbyte 'Splits into hibyte
    OutA_lo=OutA.lowbyte 'And into low byte of the word var
    would fix it (get the order correct)

  12. #12
    Join Date
    Sep 2007
    Location
    Waco, Texas
    Posts
    151


    Did you find this post helpful? Yes | No

    Default Re: Port alias in Port Expanders (MCP23S17)

    Thanks!
    I tried your suggestion:
    Code:
                          OutA=$FFFF                                        'Initial value for word var                      
                          OutA.0=0                                       'Bit mod - WORKS
                          OutA.2=0                                       'Another bit mod - WORKS                      OutA.0=0                                       'Bit mod - WORKS
                          OutA.8=0                                       'Another bit mod - WORKS
                          OutA.10=0                                       'Bit mod - WORKS
                          OutA.12=0                                       'Another bit mod - WORKS
                          OutA_hi=OutA.highbyte                             'Splits into hibyte
                          OutA_lo=OutA.lowbyte                              'And into low byte of the word var
                            OutA_MCPReg = OLATA                             'Sets up PORTA output
                            OutA_DataOut=OutA_lo                            'Sets up data to be pushed to the MCP23S17 as the low byte
                            gosub SEND_OutA_2317                            'Send it
                            pause 10                                        'Wait a bit
                            OutA_MCPReg = OLATB                             'Sets up PORTB output
                            OutA_DataOut=OutA_hi                            'Sets up data to be pushed to the MCP23S17 as the hi byte
                            gosub SEND_OutA_2317                            'Send it
    And it works like a CHAMP!
    However (you knew it might come) how do I resolve a single byte variable which tells me which bit to turn on/off into a word var?
    My need for this home project, is to read a byte var and based on its value turn on/off a bit on the expander?
    Example: Var=$C, so I need to turn on the 12th bit on the expander.
    Regards,
    Steve
    "If we knew what we were doing, it wouldn't be called research"
    - Albert Einstein

  13. #13
    Join Date
    Sep 2007
    Location
    Waco, Texas
    Posts
    151


    Did you find this post helpful? Yes | No

    Default Re: Port alias in Port Expanders (MCP23S17)

    Richard-
    I tried the following:
    Code:
                          OutA=$FFFF                                        'Initial value for word var                      
                          PortDevice=$D                                     'Var from comm link
                          K=PortDevice                                      'Copes var to var for hex to dec converter
                          gosub H2D                                         'Perform sub
                          OutA.K=0     'PBP3 barks with 'Bad variable modifier
                          OutA.0=0                                          'Bit mod - WORKS
                          OutA.2=0                                          'Another bit mod - WORKS                      OutA.0=0                                       'Bit mod - WORKS
                          OutA.8=0                                          'Another bit mod - WORKS
                          OutA.10=0                                         'Bit mod - WORKS
                          OutA.12=0                                         'Another bit mod - WORKS
                          OutA_hi=OutA.highbyte                             'Splits into hibyte
                          OutA_lo=OutA.lowbyte                              'And into low byte of the word var
                            OutA_MCPReg = OLATA                             'Sets up PORTA output
                            OutA_DataOut=OutA_lo                            'Sets up data to be pushed to the MCP23S17 as the low byte
                            gosub SEND_OutA_2317                            'Send it
                            pause 10                                        'Wait a bit
                            OutA_MCPReg = OLATB                             'Sets up PORTB output
                            OutA_DataOut=OutA_hi                            'Sets up data to be pushed to the MCP23S17 as the hi byte
                            gosub SEND_OutA_2317                            'Send it
    In an effort to get from the single byte to the pointer, but PBP3 barks with the bad variable modifier.......
    There a ought to be a way to do this.......
    "If we knew what we were doing, it wouldn't be called research"
    - Albert Einstein

  14. #14
    Join Date
    Sep 2007
    Location
    Waco, Texas
    Posts
    151


    Did you find this post helpful? Yes | No

    Default Re: Port alias in Port Expanders (MCP23S17)

    OK, it is working!
    Thanks to all who helped and provided some food for thought.....
    Code below for any others who need to do this:
    Code:
                          OutA=$FFFF                                        'Initial value for word var - everything is OFF                      
                          PortDevice=$A                                     'Var from comm link
                          OutA.0[PortDevice]=0                              'This works!
    '                      OutA.2=0                                          'Manual bit mod - works though  
    '                      OutA.12=0                                         'Manual bit mod - works though
                          OutA_hi=OutA.highbyte                             'Splits into hibyte
                          OutA_lo=OutA.lowbyte                              'And into low byte of the word var
                            OutA_MCPReg = OLATA                             'Sets up PORTA output
                            OutA_DataOut=OutA_lo                            'Sets up data to be pushed to the MCP23S17 as the low byte
                            gosub SEND_OutA_2317                            'Send it
                            pause 10                                        'Wait a bit
                            OutA_MCPReg = OLATB                             'Sets up PORTB output
                            OutA_DataOut=OutA_hi                            'Sets up data to be pushed to the MCP23S17 as the hi byte
                            gosub SEND_OutA_2317                            'Send it
    Happy New Year!
    -Steve
    "If we knew what we were doing, it wouldn't be called research"
    - Albert Einstein

  15. #15
    Join Date
    May 2013
    Location
    australia
    Posts
    2,388


    Did you find this post helpful? Yes | No

    Default Re: Port alias in Port Expanders (MCP23S17)

    Code:
    OutA var word
    
    
    asm
    
    OutA_hi=OutA
    OutA_lo=OutA+1
    
    endasm
    
    OutA_hi var byte EXT
    OutA_lo var byte EXT

    the easy way

    ps I hope I got the endianness correct if not swap the hi byte low byte definitions
    Last edited by richard; - 2nd January 2016 at 23:33.

  16. #16
    Join Date
    May 2013
    Location
    australia
    Posts
    2,388


    Did you find this post helpful? Yes | No

    Default Re: Port alias in Port Expanders (MCP23S17)

    yep I did get it wrong (choice of two I will pick the wrong one every time)

    found my endianness note

    MyVar =$AABB would be stored little-endian. I.E. if the address
    of MyVar starts at 30h, then $BB will be stored at 30h followed by $AA at 31h


    so

    Code:
    asm
    OutA_hi=OutA+1
    OutA_lo=OutA
    endasm

  17. #17
    Join Date
    Sep 2007
    Location
    Waco, Texas
    Posts
    151


    Did you find this post helpful? Yes | No

    Default Re: Port alias in Port Expanders (MCP23S17)

    Thanks, I will give that a try.
    Now if I could write both bytes at the same SPI communication, that would be an even bigger win!
    "If we knew what we were doing, it wouldn't be called research"
    - Albert Einstein

  18. #18
    Join Date
    Aug 2011
    Posts
    408


    Did you find this post helpful? Yes | No

    Default Re: Port alias in Port Expanders (MCP23S17)

    If you have the MCP23S17 IOCON register set to it's default setting of $00 that sets the chip to 16-bit mode (BANK=0) with auto address increment enabled (SEQOP=0).

    In that mode you can send register address byte = $14 (OLATA) and then write the two data bytes and they'll go to OLATA and OLATB.

  19. #19
    Join Date
    Sep 2007
    Location
    Waco, Texas
    Posts
    151


    Did you find this post helpful? Yes | No

    Default Re: Port alias in Port Expanders (MCP23S17)

    That is exactly what I was looking for!
    I thought I had done this before but could have been mistaken.
    Will try later this evening.
    Thanks!
    -Steve
    "If we knew what we were doing, it wouldn't be called research"
    - Albert Einstein

Similar Threads

  1. I2C question w/ MCP23017 Port Expanders
    By dsicon in forum mel PIC BASIC Pro
    Replies: 5
    Last Post: - 26th December 2012, 05:47
  2. 18F2520 - problem configuring fuse for port B as digital port.
    By hwhisperer in forum mel PIC BASIC Pro
    Replies: 2
    Last Post: - 11th October 2010, 11:41
  3. LCD R/S works on Port A but not Port B
    By TDonBass in forum mel PIC BASIC Pro
    Replies: 4
    Last Post: - 10th February 2009, 12:41
  4. RB port sequencer
    By freelancebee in forum mel PIC BASIC
    Replies: 0
    Last Post: - 17th August 2005, 19:58
  5. Duplicating port input to port output
    By lwindridge in forum mel PIC BASIC Pro
    Replies: 0
    Last Post: - 26th April 2004, 21:43

Members who have read this thread : 1

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