MCP23S17 - Three different approaches - ShiftIn/ShiftOut / MSSP+PBP / MSSP+ASM


Closed Thread
Results 1 to 19 of 19
  1. #1
    Join Date
    Aug 2008
    Location
    Portugal
    Posts
    240

    Post MCP23S17 - Three different approaches - ShiftIn/ShiftOut / MSSP+PBP / MSSP+ASM

    Hi everyone;

    In a project that came up was necessary to use the MCP23S17. After searching the forum, i did not find any example that would satisfy my needs.

    For this reason, I decided to write my own code to communicate with the MCP23S17. There were written three different approaches to communicate with the IC.

    The first uses only PBP and the commands and shiftin ShiftOut, the second approach, uses the MSSP module of the PIC IC with PBP, and the third, also uses the MSSP module, but the "send" and "receive" routines were written in ASM.

    The following three examples below, one per post. In each post you can see the size of the code, and the time that takes to execute the "Send" and "receive" routine.

    All codes are commented well enough to understand its operation. Also the schematic is founded attached, and the Proteus simulation. ( You must take off the ".txt" from each file )

    The code was written in Microcode Studio 3.0.0.5 and PBP2.60C.
    The IC that was used is PIC16F887.
    To test the codes, was used the development board Mikroelektronika EASYPICv6 and software PROTEUS 7.7 SP2.

    I hope it will be useful to someone.
    Attached Files Attached Files
    Thanks and Regards;
    Gadelhas

  2. #2
    Join Date
    Aug 2008
    Location
    Portugal
    Posts
    240


    Did you find this post helpful? Yes | No

    Default First Approache - ShiftIn and ShiftOut ( Only PBP )

    Code:
    '****************************************************************
    '*  Name    : MCP23S17 + PBP + ShiftIN & ShiftOut               *
    '*  Author  : [GADELHAS]                                        *
    '*  Notice  : Copyright (c) 2012                                *
    '*          : All Rights Reserved                               *
    '*  Date    : 31-01-2012                                        *
    '*  Version : 1.0                                               *
    '*  Notes   :                                                   *
    '*          : EASYPICV6 + PIC16F887 + MCP23S17                  *
    '****************************************************************
    '                              CONFIGS
    ' ================================================================
    @ __CONFIG _CONFIG1, _HS_OSC & _WDT_OFF & _PWRTE_OFF & _MCLRE_ON & _CP_OFF & _BOR_OFF & _DEBUG_OFF & _LVP_OFF & _FCMEN_ON & _IESO_OFF  
    @ __CONFIG _CONFIG2, _WRT_OFF & _BOR40V'                          DEFINES & INCLUDES
    ' ================================================================
     DEFINE OSC 8
     include "modedefs.bas"
    '                REGISTERS AND PINOUT ( 1 = IN; 0 = OUT )
    ' ================================================================
               '76543210          '76543210
     TRISA   = %00000000: PORTA = %00000000 
     TRISB   = %00000000: PORTB = %00000000
     TRISC   = %00000000: PORTC = %00000000
     TRISD   = %00000000: PORTD = %00000000
     TRISE   = %00000000: PORTE = %00000000
     ADCON0  = %00000000
     ADCON1  = %00000000
     ANSEL   = %00000000 
     ANSELH  = %00000000
     CM1CON0 = %00000000
     CM2CON0 = %00000000
     
    '                         ALIAS & MODIFIERS
    ' ================================================================
      nCS VAR PORTA.2 
     nRST VAR PORTA.3
     SCLK VAR PORTC.3
      SDI VAR PORTC.4
      SDO VAR PORTC.5
      
    '                        VARIABLES & COSTANTS
    ' ================================================================
     MCPWRT CON $40    'Command o write in MCP23S17 Address $00
     MCPRED CON $41    'Command o read from MCP23S17 Address $00
     IOCON  CON $0A    'Register address to MCP23S17 Config
     IODIRA CON $00    'Register address to MCP23S17 PortA(1)
     IODIRB CON $01    'Register address to MCP23S17 PortB(2)
     GPIOA  CON $12    'Register address to MCP23S17 GPIOA(1)
     GPIOB  CON $13    'Register address to MCP23S17 GPIOB(2)
     OLATA  CON $14    'Register address to MCP23S17 LATA(1)
     OLATB  CON $15    'Register address to MCP23S17 LATB(2)
      
     DataOut VAR BYTE  'Variable for Data Byte to Send to the MCP23S17
     DataIn  VAR BYTE  'Variable for Data Byte to Receive from the MCP23S17
     MCPReg  VAR BYTE  'Variable for the Register to Send to the MCP23S17
     
    '                           PROGRAM INIT
    ' ================================================================
        GOSUB INIT_MCP23S17    'Init the MCP23S17
    '                            MAIN LOOP
    ' ================================================================
    MAIN:
        MCPReg=OLATA             'This light up the leds, connected in
        DataOut=DataOut+1        'PortA(1) of the MCP23S17
        GOSUB SEND_MCP23S17
        
        MCPReg = GPIOB           'This read the PortB(1) of the MCP23S17
        GOSUB RECEIVE_MCP23S17   'and show the result on the PORTB of the
        PORTB = DataIn           'PIC
        
        PAUSE 200
    GOTO MAIN
    '                              SUB - ROTINES
    ' ================================================================    
    INIT_MCP23S17:
        nRST = 0                'Reset the port expander
        PAUSE 1
        nRST = 1
        MCPReg = IOCON          'Configures the MCP23S17
        DataOut = $20
        GOSUB SEND_MCP23S17
        MCPReg = IODIRA         'Configures PortA(1) All Output
        DataOut = $00
        GOSUB SEND_MCP23S17
        
        MCPReg = IODIRB         'Configures PortB(2) All Input
        DataOut = $FF
        GOSUB SEND_MCP23S17      
    RETURN
    SEND_MCP23S17:
        nCS = 0                'Enable the MCP23S17
        SHIFTOUT SDO, SCLK, MSBFIRST, [MCPWRT,MCPReg,DataOut]        
        nCS = 1                'Disable the MCP23S17
    RETURN
    RECEIVE_MCP23S17:
        nCS = 0                'Enable the MCP23S17
        SHIFTOUT SDO, SCLK, MSBFIRST, [MCPRED,MCPReg]        
        SHIFTIN SDI, SCLK, MSBPRE, [DataIn]    
        nCS = 1                'Disable the MCP23S17
    RETURN
    END

    Size: 285 Words

    Time to execute the following Routine ( Send) - 990 ticks -> 495.0uS
    Code:
        MCPReg=OLATA             'This light up the leds, connected in
        DataOut=DataOut+1        'PortA(1) of the MCP23S17
        GOSUB SEND_MCP23S17

    Time to execute the following Routine ( Receive) - 927 ticks -> 463.1uS
    Code:
        MCPReg = GPIOB           'This read the PortB(1) of the MCP23S17
        GOSUB RECEIVE_MCP23S17   'and show the result on the PORTB of the
        PORTB = DataIn           'PIC
    Thanks and Regards;
    Gadelhas

  3. #3
    Join Date
    Aug 2008
    Location
    Portugal
    Posts
    240


    1 out of 1 members found this post helpful. Did you find this post helpful? Yes | No

    Default Second Approache - MSSP Module with PBP only

    Code:
    '****************************************************************
    '*  Name    : MCP23S17 + MSPP + PBP                             *
    '*  Author  : [GADELHAS]                                        *
    '*  Notice  : Copyright (c) 2012                                *
    '*          : All Rights Reserved                               *
    '*  Date    : 31-01-2012                                        *
    '*  Version : 1.0                                               *
    '*  Notes   :                                                   *
    '*          : EASYPICV6 + PIC16F887 + MCP23S17                  *
    '****************************************************************
    '                              CONFIGS
    ' ================================================================
    @ __CONFIG _CONFIG1, _HS_OSC & _WDT_OFF & _PWRTE_OFF & _MCLRE_ON & _CP_OFF & _BOR_OFF & _DEBUG_OFF & _LVP_OFF & _FCMEN_ON & _IESO_OFF  
    @ __CONFIG _CONFIG2, _WRT_OFF & _BOR40V'                          DEFINES & INCLUDES
    ' ================================================================
     DEFINE OSC 8
    '                REGISTERS AND PINOUT ( 1 = IN; 0 = OUT )
    ' ================================================================
               '76543210          '76543210
     TRISA   = %00000000: PORTA = %00000000 
     TRISB   = %00000000: PORTB = %00000000
     TRISC   = %00010000: PORTC = %00000000
     TRISD   = %00000000: PORTD = %00000000
     TRISE   = %00000000: PORTE = %00000000
     ADCON0  = %00000000
     ADCON1  = %00000000
     ANSEL   = %00000000 
     ANSELH  = %00000000
     CM1CON0 = %00000000
     CM2CON0 = %00000000
     SSPSTAT = %00000000  'Configures the SPI Module ( Read DataSheet ) 
     SSPCON  = %00110000  'Configures the SPI Module ( Read DataSheet ) 
     
    '                         ALIAS & MODIFIERS
    ' ================================================================
      nCS VAR PORTA.2 
     nRST VAR PORTA.3
     SCLK VAR PORTC.3
      SDI VAR PORTC.4
      SDO VAR PORTC.5
      
    '                        VARIABLES & COSTANTS
    ' ================================================================
     MCPWRT CON $40    'Command o write in MCP23S17 Address $00
     MCPRED CON $41    'Command o read from MCP23S17 Address $00
     IOCON  CON $0A    'Register address to MCP23S17 Config
     IODIRA CON $00    'Register address to MCP23S17 PortA(1)
     IODIRB CON $01    'Register address to MCP23S17 PortB(2)
     GPIOA  CON $12    'Register address to MCP23S17 GPIOA(1)
     GPIOB  CON $13    'Register address to MCP23S17 GPIOB(2)
     OLATA  CON $14    'Register address to MCP23S17 LATA(1)
     OLATB  CON $15    'Register address to MCP23S17 LATB(2)
      
     DataOut VAR BYTE  'Variable for Data Byte to Send to the MCP23S17
     DataIn  VAR BYTE  'Variable for Data Byte to Receive from the MCP23S17
     MCPReg  VAR BYTE  'Variable for the Register to Send to the MCP23S17
     
    '                           PROGRAM INIT
    ' ================================================================
        GOSUB INIT_MCP23S17    'Init the MCP23S17
    '                            MAIN LOOP
    ' ================================================================
    MAIN:
        MCPReg=OLATA             'This light up the leds, connected in
        DataOut=DataOut+1        'PortA(1) of the MCP23S17
        GOSUB SEND_MCP23S17
        
        MCPReg = GPIOB           'This read the PortB(1) of the MCP23S17
        GOSUB RECEIVE_MCP23S17   'and show the result on the PORTB of the
        PORTB = DataIn           'PIC
        
        PAUSE 200
    GOTO MAIN
    '                              SUB - ROTINES
    ' ================================================================    
    INIT_MCP23S17:
        nRST = 0                'Reset the port expander
        PAUSE 1
        nRST = 1
        MCPReg = IOCON          'Configures the MCP23S17
        DataOut = $20
        GOSUB SEND_MCP23S17
        MCPReg = IODIRA         'Configures PortA(1) All Output
        DataOut = $00
        GOSUB SEND_MCP23S17
        
        MCPReg = IODIRB         'Configures PortB(2) All Input
        DataOut = $FF
        GOSUB SEND_MCP23S17      
    RETURN
    SEND_MCP23S17:
        nCS = 0                 'Enable the MCP23S17
        SSPBUF = MCPWRT         'Command to Write to the MCP23S17
        PAUSEUS 1    
        SSPBUF = MCPReg         'Register to Write the Data
        PAUSEUS 1 
        SSPBUF = DataOut        'Data to be sent
        PAUSEUS 1           
        nCS = 1                 'Disable the MCP23S17
    RETURN
    RECEIVE_MCP23S17:
        nCS = 0                 'Enable the MCP23S17
        SSPBUF = MCPRED         'Command to Read from the MCP23S17
        PAUSEUS 1 
        SSPBUF = MCPReg         'Register to Read from
        PAUSEUS 1  
        SSPBUF = 0              'Send something
        PAUSEUS 1  
        DataIn = SSPBUF         'Data received from te MCP23S17
        PAUSEUS 1 
        nCS = 1                 'Disable the MCP23S17
    RETURN
    END

    Size: 166 Words

    Time to execute the following Routine ( Send) - 92 ticks -> 46.0uS
    Code:
        MCPReg=OLATA             'This light up the leds, connected in
        DataOut=DataOut+1        'PortA(1) of the MCP23S17
        GOSUB SEND_MCP23S17

    Time to execute the following Routine ( Receive) - 119 ticks -> 59.1uS
    Code:
        MCPReg = GPIOB           'This read the PortB(1) of the MCP23S17
        GOSUB RECEIVE_MCP23S17   'and show the result on the PORTB of the
        PORTB = DataIn           'PIC
    Thanks and Regards;
    Gadelhas

  4. #4
    Join Date
    Aug 2008
    Location
    Portugal
    Posts
    240


    Did you find this post helpful? Yes | No

    Default Third Approache - MSSP Module with PBP and ASM Send and Receive Routine

    Code:
    '****************************************************************
    '*  Name    : MCP23S17 + MSPP + ASM                             *
    '*  Author  : [GADELHAS]                                        *
    '*  Notice  : Copyright (c) 2012                                *
    '*          : All Rights Reserved                               *
    '*  Date    : 31-01-2012                                        *
    '*  Version : 1.0                                               *
    '*  Notes   :                                                   *
    '*          : EASYPICV6 + PIC16F887 + MCP23S17                  *
    '****************************************************************
    '                              CONFIGS
    ' ================================================================
    @ __CONFIG _CONFIG1, _HS_OSC & _WDT_OFF & _PWRTE_OFF & _MCLRE_ON & _CP_OFF & _BOR_OFF & _DEBUG_OFF & _LVP_OFF & _FCMEN_ON & _IESO_OFF  
    @ __CONFIG _CONFIG2, _WRT_OFF & _BOR40V
    '                          DEFINES & INCLUDES
    ' ================================================================
     DEFINE OSC 8
    '                REGISTERS AND PINOUT ( 1 = IN; 0 = OUT )
    ' ================================================================
               '76543210          '76543210
     TRISA   = %00000000: PORTA = %00000100 
     TRISB   = %00000000: PORTB = %00000000
     TRISC   = %00010000: PORTC = %00000000
     TRISD   = %00000000: PORTD = %00000000
     TRISE   = %00000000: PORTE = %00000000
     ADCON0  = %00000000
     ADCON1  = %00000000
     ANSEL   = %00000000 
     ANSELH  = %00000000
     CM1CON0 = %00000000
     CM2CON0 = %00000000
     SSPSTAT = %00000000  'Configures the SPI Module ( Read DataSheet ) 
     SSPCON  = %00110000  'Configures the SPI Module ( Read DataSheet ) 
     
    '                         ALIAS & MODIFIERS
    ' ================================================================
      nCS VAR PORTA.2 
     nRST VAR PORTA.3
     SCLK VAR PORTC.3
      SDI VAR PORTC.4
      SDO VAR PORTC.5
      
    '                        VARIABLES & COSTANTS
    ' ================================================================
     MCPWRT CON $40    'Command o write in MCP23S17 Address $00
     MCPRED CON $41    'Command o read from MCP23S17 Address $00
     IOCON  CON $0A    'Register address to MCP23S17 Config
     IODIRA CON $00    'Register address to MCP23S17 PortA(1)
     IODIRB CON $01    'Register address to MCP23S17 PortB(2)
     GPIOA  CON $12    'Register address to MCP23S17 GPIOA(1)
     GPIOB  CON $13    'Register address to MCP23S17 GPIOB(2)
     OLATA  CON $14    'Register address to MCP23S17 LATA(1)
     OLATB  CON $15    'Register address to MCP23S17 LATB(2)
     
     DataOut VAR BYTE  'Variable for Data Byte to Send to the MCP23S17
     DataIn  VAR BYTE  'Variable for Data Byte to Receive from the MCP23S17
     MCPReg  VAR BYTE  'Variable for the Register to Send to the MCP23S17
     
    '                           PROGRAM INIT
    ' ================================================================
        GOSUB INIT_MCP23S17    'Init the MCP23S17
    '                            MAIN LOOP
    ' ================================================================
    MAIN:
        MCPReg=OLATA             'This light up the leds, connected in
        DataOut=DataOut+1        'PortA(1) of the MCP23S17
        GOSUB SEND_MCP23S17
        
        MCPReg = GPIOB           'This read the PortB(1) of the MCP23S17
        GOSUB RECEIVE_MCP23S17   'and show the result on the PORTB of the
        PORTB = DataIn           'PIC
        
        PAUSE 200
    GOTO MAIN
    '                              SUB - ROTINES
    ' ================================================================    
    INIT_MCP23S17:
        nRST = 0                'Reset the port expander
        PAUSE 1
        nRST = 1
        MCPReg = IOCON          'Configures the MCP23S17
        DataOut = $20
        GOSUB SEND_MCP23S17
        MCPReg = IODIRA         'Configures PortA(1) All Output
        DataOut = $00
        GOSUB SEND_MCP23S17
        
        MCPReg = IODIRB         'Configures PortB(2) All Input
        DataOut = $FF
        GOSUB SEND_MCP23S17      
    RETURN
    SEND_MCP23S17:  
    ASM
     bcf PORTA, 2               ;Enable the MCP23S17
     MOVE?CB _MCPWRT, SSPBUF    ;Command to Write to the MCP23S17
     call _delay
     MOVE?BB _MCPReg, SSPBUF    ;Register to Write the Data
     call _delay
     MOVE?BB _DataOut, SSPBUF   ;Data to be sent
     call _delay                
     bsf PORTA, 2               ;Disable the MCP23S17
    ENDASM
    RETURN
    RECEIVE_MCP23S17:
    ASM
     bcf PORTA, 2               ;Enable the MCP23S17
     MOVE?CB _MCPRED, SSPBUF    ;Command to Read from the MCP23S17
     call _delay
     MOVE?BB _MCPReg, SSPBUF    ;Register to Read from
     call _delay
     MOVE?BB _DataOut, SSPBUF   ;Send something
     call _delay 
     MOVE?BB SSPBUF, _DataIn    ;Data received from te MCP23S17
     bsf PORTA, 2               ;Disable the MCP23S17
    ENDASM
    RETURN
    delay:                      'Delay Routine 3uS - You may have to change if running OSC faster  
    asm                         ;8Mhz/4 = 2Mhz = 0.5uS X 6cycles(2 p/goto) = 3uS
     goto $+1
     goto $+1
     goto $+1
    endasm
    return
    END

    Size: 157 Words

    Time to execute the following Routine ( Send) - 47 ticks -> 23.1uS
    Code:
        MCPReg=OLATA             'This light up the leds, connected in
        DataOut=DataOut+1        'PortA(1) of the MCP23S17
        GOSUB SEND_MCP23S17

    Time to execute the following Routine ( Receive) - 50 ticks -> 25.0uS
    Code:
        MCPReg = GPIOB           'This read the PortB(1) of the MCP23S17
        GOSUB RECEIVE_MCP23S17   'and show the result on the PORTB of the
        PORTB = DataIn           'PIC
    Thanks and Regards;
    Gadelhas

  5. #5
    Join Date
    Jan 2005
    Location
    Montreal, Quebec, Canada
    Posts
    2,588


    Did you find this post helpful? Yes | No

    Default Re: Third Approache - MSSP Module with PBP and ASM Send and Receive Routine

    This is great stuff. I use the MCP23016, but this new IC is much faster.

    Can you explain how you came up with the 3us delay in the 3rd approach? I look at your comment and the SPI characteristics in the datasheet and don't know what to use exactly.

    Robert
    Last edited by Demon; - 2nd February 2012 at 02:33.

  6. #6
    Join Date
    Aug 2008
    Location
    Portugal
    Posts
    240


    Did you find this post helpful? Yes | No

    Default Re: Third Approache - MSSP Module with PBP and ASM Send and Receive Routine

    Quote Originally Posted by Demon View Post
    This is great stuff. I use the MCP23016, but this new IC is much faster.

    Can you explain how you came up with the 3us delay in the 3rd approach? I look at your comment and the SPI characteristics in the datasheet and don't know what to use exactly.

    Robert
    Hi Robert, Thanks for your comment.

    Hi came up with 3 uS by trial and error. I tried 2 uS, but it wasn´t enough. The problem is not the MCP23S17, but the SSPUBUF register of the PIC. I think if you run the PIC faster, for instance @20Mhz, you can even reduce that time.
    Thanks and Regards;
    Gadelhas

  7. #7
    Join Date
    Jan 2005
    Location
    Montreal, Quebec, Canada
    Posts
    2,588


    Did you find this post helpful? Yes | No

    Default Re: Third Approache - MSSP Module with PBP and ASM Send and Receive Routine

    Wouldn't it be the other way around? If you run a PIC faster, it would cycle quicker so you'd need more delay instructions no?

    I checked the datasheet again and page 35 table 2-4 has 500ns for Serial Data to Output Valid. Does that mean it takes 500ns for the IC to process a complete output operation?

    I would assume reading is quicker...?

    Robert

  8. #8
    Join Date
    Aug 2008
    Location
    Portugal
    Posts
    240


    Did you find this post helpful? Yes | No

    Default Re: Third Approache - MSSP Module with PBP and ASM Send and Receive Routine

    Quote Originally Posted by Demon View Post
    Wouldn't it be the other way around? If you run a PIC faster, it would cycle quicker so you'd need more delay instructions no?

    I checked the datasheet again and page 35 table 2-4 has 500ns for Serial Data to Output Valid. Does that mean it takes 500ns for the IC to process a complete output operation?

    I would assume reading is quicker...?

    Robert
    The problem is that when you put a byte in the SSPUF of the PIC, it takes some time for the PIC to output that byte( @8Mhz ~3uS ). If you run the PIC faster, the time that it takes to output the byte gets reduced.
    At this speed ( 8Mhz ), you put the byte into the SSPUF and you must wait 3us to put another byte in the SSPUF, if you put a byte before the 3us, for instance at 2us, the byte before will be corrupted and the pic will output the new byte and miss the byte before. You can try this in the simulation that is attached.

    You are looking at the wrong table ( 2-4 GP and INT TIMMING). You should look table 2-3 (SPI Characteristics ). The MCP23S17 can RUN at a max of 10Mhz ( SPI ).
    Thanks and Regards;
    Gadelhas

  9. #9
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,517


    1 out of 1 members found this post helpful. Did you find this post helpful? Yes | No

    Default Re: MCP23S17 - Three different approaches - ShiftIn/ShiftOut / MSSP+PBP / MSSP+ASM

    Hi,
    Instead of relying on software timing you can check the MSSP interrupt flag:
    Code:
    myByte VAR BYTE
    SSPIF VAR PIR1.3
    
    myByte = 123
    
    SSPBUF = myByte                 ' Load byte to shiftregister buffer
    SSPIF = 0                             ' Clear interrupt flag
    WHILE SSPIF=0 : WEND        ' Wait for transmission to finish
    This way you don't have to change any timing if you change the oscillator or if you change the MSSP module clock divisor etc.

    Check the datasheet and make sure the SSPIF is at PIR1.3 for your device. (I think they try to keep it consistent but you never know)

    /Henrik.

  10. #10
    Join Date
    Aug 2008
    Location
    Portugal
    Posts
    240


    Did you find this post helpful? Yes | No

    Default Re: MCP23S17 - Three different approaches - ShiftIn/ShiftOut / MSSP+PBP / MSSP+ASM

    Quote Originally Posted by HenrikOlsson View Post
    Hi,
    Instead of relying on software timing you can check the MSSP interrupt flag:
    Code:
    myByte VAR BYTE
    SSPIF VAR PIR1.3
    
    myByte = 123
    
    SSPBUF = myByte                 ' Load byte to shiftregister buffer
    SSPIF = 0                             ' Clear interrupt flag
    WHILE SSPIF=0 : WEND        ' Wait for transmission to finish
    This way you don't have to change any timing if you change the oscillator or if you change the MSSP module clock divisor etc.

    Check the datasheet and make sure the SSPIF is at PIR1.3 for your device. (I think they try to keep it consistent but you never know)

    /Henrik.
    Hi Henrik,

    You are correct. I did try the PIR1.3 flag, however i forgot to clear it before test it, and because of that it was not working like should be.
    One problem with this approach is that it takes more memory.

    One more thing, to test if the SSPBUF has received a byte, we should test the SSPSTAT.BF bit, like:

    Code:
        DataIn = SSPBUF         'Data received from te MCP23S17
        SSPSTAT.0 = 0              
        WHILE SSPSTAT.0 : WEND
    Now i need to change the code that i posted before this little improvement, but i can modify my posts!!!!

    Thanks!!!
    Thanks and Regards;
    Gadelhas

  11. #11
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,517


    Did you find this post helpful? Yes | No

    Default Re: MCP23S17 - Three different approaches - ShiftIn/ShiftOut / MSSP+PBP / MSSP+ASM

    Hi,
    I initially used the the SSPSTAT.0 bit for both sending and receiving but eventually got into trouble. Darrel then made me aware in this thread of that the purpose of SSPSTAT.0 flag really is when the PIC is operating in slave mode and data is shifted into to PIC by an external clock source, ie when something else is providing the SPI clock. (Thanks Darrel!)

    When the PIC is acting as the master, as is the case in all your examples, it works fine with the interrupt flag. For shifting in a byte you simply write a "dummy" value to SPPBUF, the module will then shift that dummy byte out with 8 clockpulses and then you'll have your input byte in SSPBUF.

    IF you're going to use the SSPSTAT.0 bit I suspect you want to poll it before reading SSPBUF to see if there's a byte available to be read. The way you have in your latest post you grab whatever is in SSPBUF and then sit there waiting for another byte before continuing. Is that the intentended operation?

    /Henrik.

  12. #12
    Join Date
    Aug 2008
    Location
    Portugal
    Posts
    240


    Did you find this post helpful? Yes | No

    Default Re: MCP23S17 - Three different approaches - ShiftIn/ShiftOut / MSSP+PBP / MSSP+ASM

    Quote Originally Posted by HenrikOlsson View Post
    Hi,
    IF you're going to use the SSPSTAT.0 bit I suspect you want to poll it before reading SSPBUF to see if there's a byte available to be read. The way you have in your latest post you grab whatever is in SSPBUF and then sit there waiting for another byte before continuing. Is that the intentended operation?

    /Henrik.
    No, i actully take it of in my last version. Since the last thing that the MCP sends is the byte that i want, i just grab it and put it on the PORTB.
    Thanks and Regards;
    Gadelhas

  13. #13
    Join Date
    Aug 2008
    Location
    Portugal
    Posts
    240


    Did you find this post helpful? Yes | No

    Default Re: MCP23S17 - Three different approaches - ShiftIn/ShiftOut / MSSP+PBP / MSSP+ASM

    You can find the last code on the WIKI.
    Thanks and Regards;
    Gadelhas

  14. #14
    Join Date
    Jan 2011
    Location
    Harare
    Posts
    5


    Did you find this post helpful? Yes | No

    Default Re: MCP23S17 - Three different approaches - ShiftIn/ShiftOut / MSSP+PBP / MSSP+ASM

    Hi Gaelas,
    I realized when you mailed the above was quite a while ago. Did you ever extendedyour code to drive a 8 or 4 bits LCD? I am using PicDem board and also the ISISversion but both are written in PASM and trying to get the PBP or Proton basicto do the same thing. Any advises or basic code will be welcome.
    Regards,
    Yves


  15. #15
    Join Date
    Aug 2008
    Location
    Portugal
    Posts
    240


    Did you find this post helpful? Yes | No

    Default Re: MCP23S17 - Three different approaches - ShiftIn/ShiftOut / MSSP+PBP / MSSP+ASM

    Quote Originally Posted by Yvesmazzon View Post
    Hi Gaelas,
    I realized when you mailed the above was quite a while ago. Did you ever extendedyour code to drive a 8 or 4 bits LCD? I am using PicDem board and also the ISISversion but both are written in PASM and trying to get the PBP or Proton basicto do the same thing. Any advises or basic code will be welcome.
    Regards,
    Yves
    Hi;

    No i don't have any example how to interface the MCP with a LCD. It never was necessary. Maybe one day i develop such example, but for now i'm working on other examples.
    Thanks and Regards;
    Gadelhas

  16. #16
    Join Date
    Sep 2006
    Location
    Indiana, USA
    Posts
    72


    Did you find this post helpful? Yes | No

    Default Re: MCP23S17 - Three different approaches - ShiftIn/ShiftOut / MSSP+PBP / MSSP+ASM

    Im having trouble getting this to work. my circuit is the same as Gadelhas has in his schematic, except im not grabbing any inputs with my circuit and i'm using a different PIC . The way I have it coded is so that I can use it with a 16F648A w/ 4Mhz internal OSC and I think it should light each led on the MCP23S17s PORTA one at a time before reseting at the end of the string and repeating, but its not working in that the leds never light. I have an LED on PORTB.4 as kind of a watch dog blinky and its behaving as I would expect. Any ideas on whats wrong with my version of Gadelhas' code or something else I'm missing?

    Code:
    '                              CONFIGS
    ' ================================================================
    @ DEVICE PIC16F648A, INTRC_OSC_NOCLKOUT, WDT_OFF, PWRT_OFF, MCLR_OFF, PROTECT_OFF, BOD_OFF, LVP_OFF
    
    '                          DEFINES & INCLUDES
    ' ================================================================
     DEFINE OSC 4
     include "modedefs.bas"
    '                REGISTERS AND PINOUT ( 1 = IN; 0 = OUT )
    ' ================================================================
               '76543210          
    CMCON = 7                              ' Turn off un-needed PIC hardware
    VRCON = 0                              '   ''             ''
    CCP1CON = 0                            '   ''             ''
    INTCON = %00000000                     '   ''             ''
    
     
    '                         ALIAS & MODIFIERS
    ' ================================================================
      nCS VAR PORTA.0 
     nRST VAR PORTB.5
     SCLK VAR PORTB.0
      SDO VAR PORTB.3
      
    '                        VARIABLES & COSTANTS
    ' ================================================================
     MCPWRT CON $40    'Command o write in MCP23S17 Address $00
     MCPRED CON $41    'Command o read from MCP23S17 Address $00
     IOCON  CON $0A    'Register address to MCP23S17 Config
     IODIRA CON $00    'Register address to MCP23S17 PortA(1)
     IODIRB CON $01    'Register address to MCP23S17 PortB(2)
     GPIOA  CON $12    'Register address to MCP23S17 GPIOA(1)
     GPIOB  CON $13    'Register address to MCP23S17 GPIOB(2)
     OLATA  CON $14    'Register address to MCP23S17 LATA(1)
     OLATB  CON $15    'Register address to MCP23S17 LATB(2)
      
     DataOut VAR BYTE  'Variable for Data Byte to Send to the MCP23S17
     DataIn  VAR BYTE  'Variable for Data Byte to Receive from the MCP23S17
     MCPReg  VAR BYTE  'Variable for the Register to Send to the MCP23S17
     
    '                           PROGRAM INIT
    ' ================================================================
    clear
    pause 100
    nrst = 1
    ncs = 1
    sclk = 0
    sdo = 0
    pause 100
        GOSUB INIT_MCP23S17    'Init the MCP23S17
    '                            MAIN LOOP
    ' ================================================================
    MAIN:
        MCPReg=OLATA             'This light up the leds, connected in
        DataOut=DataOut+1        'PortA(1) of the MCP23S17
        if dataout >=8 then
        dataout=0
        GOSUB SEND_MCP23S17
        gosub INIT_MCP23S17:
        endif
        GOSUB SEND_MCP23S17
        
    '    MCPReg = GPIOB           'This read the PortB(1) of the MCP23S17
    '   GOSUB RECEIVE_MCP23S17   'and show the result on the PORTB of the
    '   PORTB = DataIn           'PIC
        
        PAUSE 500
        if dataout = 0 then
        high PORTB.4
        pause 250
        low PORTB.4
        pause 250
        endif 
        high PORTB.4
        pause 500
        low PORTB.4
    GOTO MAIN
    '                              SUB - ROTINES
    ' ================================================================    
    INIT_MCP23S17:
        nRST = 0                'Reset the port expander
        PAUSE 1
        nRST = 1
        MCPReg = IOCON          'Configures the MCP23S17
        DataOut = $20
        GOSUB SEND_MCP23S17
        MCPReg = IODIRA         'Configures PortA(1) All Output
        DataOut = $00
        GOSUB SEND_MCP23S17
        
        MCPReg = IODIRB         'Configures PortB(2) All Input
        DataOut = $FF
        GOSUB SEND_MCP23S17      
    RETURN
    SEND_MCP23S17:
        nCS = 0                'Enable the MCP23S17
        SHIFTOUT SDO, SCLK, MSBFIRST, [MCPWRT,MCPReg,DataOut]        
        nCS = 1                'Disable the MCP23S17
    RETURN
    'RECEIVE_MCP23S17:
    '    nCS = 0                'Enable the MCP23S17
    '    SHIFTOUT SDO, SCLK, MSBFIRST, [MCPRED,MCPReg]        
    '   SHIFTIN SDI, SCLK, MSBPRE, [DataIn]    
    '    nCS = 1                'Disable the MCP23S17
    'RETURN
    END

  17. #17
    Join Date
    Aug 2008
    Location
    Portugal
    Posts
    240


    Did you find this post helpful? Yes | No

    Default Re: MCP23S17 - Three different approaches - ShiftIn/ShiftOut / MSSP+PBP / MSSP+ASM

    Hi Ryan7777;

    Try to add this 2 lines after the INTCON configuration and see if it works.

    TRISA = %00000000
    TRISB = %00000000
    Thanks and Regards;
    Gadelhas

  18. #18
    Join Date
    Aug 2008
    Location
    Portugal
    Posts
    240


    Did you find this post helpful? Yes | No

    Default Re: MCP23S17 - Three different approaches - ShiftIn/ShiftOut / MSSP+PBP / MSSP+ASM

    Hi Ryan7777;

    Have you allready tried my sugestion?

    I've tried and it worked, so you must add those to lines that i mention.
    Also remember that you are working with binary numbers, so this;

    Code:
        DataOut=DataOut+1        
        if dataout >=8 then
    will not light up all the leds.
    Thanks and Regards;
    Gadelhas

  19. #19
    Join Date
    Sep 2006
    Location
    Indiana, USA
    Posts
    72


    Did you find this post helpful? Yes | No

    Default Re: MCP23S17 - Three different approaches - ShiftIn/ShiftOut / MSSP+PBP / MSSP+ASM

    Oh hey, Thanks! You're exactly right the set up of my ports was the snag. I was also confused with the dataOut= and the pins on the port expander being addressed as a binary number (1,2,4,8,16,32,64,128). My first go after after setting up TRIS, the port expander was counting up in binary and of course stopping because of the if dataOut >=8 then bit of code. I fixed all of that and tossed together some quick, sloppy code using a couple of FOR NEXT loops and SELECT CASE structure to get it to count up and down in proper fashion to scan the LEDs one at a time up PORTA and back down. So if I wanted to play "night rider", now I all I'd need is a black firebird Now I feel like a have a good grasp on how to talk to the MCP23S17 for the project I had originally intended it for. Thank you for the fast replies and for posting your tutorial on this part! I'll post my "blinky" code when I get back to my real PC.

    Thanks again!

    Ryan

Members who have read this thread : 4

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