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.
First Approache - ShiftIn and ShiftOut ( Only PBP )
'****************************************************************
'* 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
Time to execute the following Routine ( Send) - 990 ticks -> 495.0uS
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
Second Approache - MSSP Module with PBP only
'****************************************************************
'* 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
PIR1.3 = 0
WHILE PIR1.3=0 : WEND
SSPBUF = MCPReg 'Register to Write the Data
PIR1.3 = 0
WHILE PIR1.3=0 : WEND
SSPBUF = DataOut 'Data to be sent
PIR1.3 = 0
WHILE PIR1.3=0 : WEND
nCS = 1 'Disable the MCP23S17
RETURN
RECEIVE_MCP23S17:
nCS = 0 'Enable the MCP23S17
SSPBUF = MCPRED 'Command to Read from the MCP23S17
PIR1.3 = 0
WHILE PIR1.3=0 : WEND
SSPBUF = MCPReg 'Register to Read from
PIR1.3 = 0
WHILE PIR1.3=0 : WEND
SSPBUF = 0 'Send something
PIR1.3 = 0
WHILE PIR1.3=0 : WEND
DataIn = SSPBUF 'Data received from te MCP23S17
nCS = 1 'Disable the MCP23S17
RETURN
END
Time to execute the following Routine ( Send) - 62 ticks -> 31.0uS
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
Third Approache - MSSP Module with PBP and ASM Send and Receive Routine
'****************************************************************
'* 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
bcf PIR1, 3
btfss PIR1, 3
goto $-1
MOVE?BB _MCPReg, SSPBUF ;Register to Write the Data
bcf PIR1, 3
btfss PIR1, 3
goto $-1
MOVE?BB _DataOut, SSPBUF ;Data to be sent
bcf PIR1, 3
btfss PIR1, 3
goto $-1
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
bcf PIR1, 3
btfss PIR1, 3
goto $-1
MOVE?BB _MCPReg, SSPBUF ;Register to Read from
bcf PIR1, 3
btfss PIR1, 3
goto $-1
MOVE?BB _DataOut, SSPBUF ;Send something
bcf PIR1, 3
btfss PIR1, 3
goto $-1
MOVE?BB SSPBUF, _DataIn ;Data received from te MCP23S17
bsf PORTA, 2 ;Disable the MCP23S17
ENDASM
RETURN
END
Time to execute the following Routine ( Send) - 62 ticks -> 31.0uS
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
You can see the originally thread here:
http://www.picbasic.co.uk/forum/showthread.php?t=16066


Menu

Re: 16F690 MCLR as Input
many thanks Henrik to clarify this post.
jackberg1 Yesterday, 20:42that make more sense to me now with further test, when the pin RA3
has nothing connected to it, the input is floating thus
when adding a pulldown it's...