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
Re: LCD_AnyPin.pbp
I didn't mean the speeds, I mean not noticing they were no longer Defines, but Variables and Constants.
Demon Today, 21:22I would have spent countless hours looking at my code. :D