PDA

View Full Version : MCP23S17 init all outputs and to a logic 1



ecoli-557
- 22nd February 2016, 21:50
Hello to All-
I have been trying to figure out the best and/or fastest way to initialize a MCP23S17 (SPI) to all outputs with an active low.
I init the devices by calling this routing (Thanks to the Forum)


INIT_OutA_2317:'MCP2317 used for A Outputs:
OutA_MCPReg = IOCON 'Configures the MCP23S17
OutA_DataOut = $20
GOSUB SEND_OutA_2317
OutA_MCPReg = IODIRA 'Configures PortA(1) All OUTPUTS
OutA_DataOut = $00
GOSUB SEND_OutA_2317
OutA_MCPReg = IODIRB 'Configures PortB(2) All OUTPUTs
OutA_DataOut = $00
GOSUB SEND_OutA_2317
RETURN


And the Send Out Sub:


SEND_OutA_2317:
CSA = 0 'Enable the MCP23S17
SSP1BUF = MCPWRT 'Command to Write to the MCP23S17
while !PIR1.3 : wend
PIR1.3=0 'Reset the flag
SSP1CON1.7=0 'Clear collision bit
SSP1BUF = OutA_MCPReg 'Register to Write the Data
while !PIR1.3 : wend
PIR1.3=0 'Reset the flag
SSP1CON1.7=0 'Clear collision bit
SSP1BUF = OutA_DataOut 'Data to be sent
while !PIR1.3 : wend
PIR1.3 = 0 'Reset the flag
SSP1CON1.7=0 'Clear collision bit
CSA = 1 'Disable the MCP23S17
RETURN


And the set port sub:


SetPort_A:
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 3 '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
return


And then do a for next loop:


for i=0 to 15 : OutA.0[i]=1 : gosub SetPort_A : next i


Even working with a 18F6527 at 40 MHz, the thing comes up with all outputs active (active low is what I am looking to do) for a small time but fast enough to trigger all 16 outputs.
I will try cutting some of the pauses but is there a better/faster way to do this?
Any pointers would be helpful - as is always this forum......

richard
- 22nd February 2016, 23:37
from data sheet



Serial Data to Output Valid— — 450 ns


CS Setup Time 50 nS



a 3mS pause is way to long



SetPort_A:
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 3 'Wait a bit cannot see that this is necessary or even adds any value
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
return


if you want speed why set only 1 bit at a time when they all are going to be set anyway


for i=0 to 15 : OutA.0[i]=1 : gosub SetPort_A : next i


OutA=$ffff
gosub SetPort_A
would be 15 times faster

ecoli-557
- 23rd February 2016, 17:07
Thanks Richard!
I get caught up thinking in terms of 8 bits that I forget that I can actually speak in words! Hah!
I did miss the PAUSE statement and have changed it to PAUSEUS 10 and it seems happy.
I used the OutA=$FFFF : gosub SetPort_A and it seems that it too fast for the outputs to actually toggle which is what I was driving for.
Thanks again, good eye and quite helpful.
Steve