Port Expander Library
mikroBasic PRO for ARM provides a library for communication with the Microchip’s Port Expander MCP23S17 via SPI interface. Connections of the ARM MCU and MCP23S17 is given on the schematic at the bottom of this page.

- The library uses the SPI module for communication. User must initialize the appropriate SPI module before using the Port Expander Library.
- For MCUs with multiple SPI modules it is possible to initialize all of them and then switch by using the
SPI_Set_Active()
function. See the SPI Library functions. - Library does not use Port Expander interrupts.
Library Dependency Tree

External dependencies of Port Expander Library
Stellaris
The following variables must be defined in all projects using Port Expander Library: | Description : | Example : |
---|---|---|
dim SPExpanderRST as sbit sfr external |
Reset line. | dim SPExpanderRST as sbit at GPIO_PORTA_DATA0_bit |
dim SPExpanderCS as sbit sfr external |
Chip Select line. | dim SPExpanderCS as sbit at GPIO_PORTA_DATA1_bit |
dim SPExpanderRST_Direction as sbit sfr external |
Direction of the Reset pin. | dim SPExpanderRST_Direction as sbit at GPIO_PORTA_DIR0_bit |
dim SPExpanderCS_Direction as sbit sfr external |
Direction of the Chip Select pin. | dim SPExpanderCS_Directions as sbit at GPIO_PORTA_DIR1_bit |
STM32
The following variables must be defined in all projects using Port Expander Library: | Description : | Example : |
---|---|---|
dim SPExpanderRST as sbit sfr external |
Reset line. | dim SPExpanderRST as sbit at GPIOB_ODR.B0 |
dim SPExpanderCS as sbit sfr external |
Chip Select line. | dim SPExpanderCS as sbit at GPIOB_ODR.B1 |
Library Routines
- Expander_Init
- Expander_Init_Advanced
- Expander_Read_Byte
- Expander_Write_Byte
- Expander_Read_PortA
- Expander_Read_PortB
- Expander_Read_PortAB
- Expander_Write_PortA
- Expander_Write_PortB
- Expander_Write_PortAB
- Expander_Set_DirectionPortA
- Expander_Set_DirectionPortB
- Expander_Set_DirectionPortAB
- Expander_Set_PullUpsPortA
- Expander_Set_PullUpsPortB
- Expander_Set_PullUpsPortAB
Expander_Init
Prototype |
sub procedure Expander_Init(dim ModuleAddress as byte) |
---|---|
Description |
Initializes Port Expander using SPI communication. Port Expander module settings :
|
Parameters |
|
Returns |
Nothing. |
Requires |
External dependencies of the library from the top of the page must be defined before using this function. SPI module needs to be initialized. See SPIx_Init and SPIx_Init_Advanced routines. |
Example |
Stellaris' Port Expander module connections dim SPExpanderRST as sbit at GPIO_PORTA_DATA0_bit SPExpanderCS as sbit at GPIO_PORTA_DATA1_bit SPExpanderRST_Direction as sbit at GPIO_PORTA_DIR0_bit SPExpanderCS_Direction as sbit at GPIO_PORTA_DIR1_bit ' End Port Expander module connections ... SPI1_Init() ' initialize SPI module Expander_Init(0) ' initialize Port Expander STM32' Port Expander module connections dim SPExpanderRST as sbit at GPIOB_ODR.B0 SPExpanderCS as sbit at GPIOB_ODR.B1 ' End Port Expander module connections ... SPI1_Init() ' initialize SPI module Expander_Init(0) ' initialize Port Expander |
Notes |
None. |
Expander_Init_Advanced
Prototype |
sub procedure Expander_Init_Advanced(dim byref rstPort as longword, dim as rstPin, haen as byte)p> |
---|---|
Description |
Initializes Port Expander using SPI communication. |
Parameters |
|
Returns |
Nothing. |
Requires |
External dependencies of the library from the top of the page must be defined before using this function. SPI module needs to be initialized. See SPIx_Init and SPIx_Init_Advanced routines. |
Example |
Stellaris' Port Expander module connections dim SPExpanderRST as sbit at GPIO_PORTA_DATA0_bit SPExpanderCS as sbit at GPIO_PORTA_DATA1_bit SPExpanderRST_Direction as sbit at GPIO_PORTA_DIR0_bit SPExpanderCS_Direction as sbit at GPIO_PORTA_DIR1_bit ' End Port Expander module connections ... ' If Port Expander Library uses SPI1 module SPI1_Init() ' initialize SPI module Expander_Init_Advanced(PORTB, 0, 0) ' initialize Port Expander STM32' Port Expander module connections dim SPExpanderRST as sbit at GPIOB_ODR.B0 SPExpanderCS as sbit at GPIOB_ODR.B1 ' End Port Expander module connections ... ' If Port Expander Library uses SPI1 module SPI1_Init() ' initialize SPI module Expander_Init_Advanced(GPIOB_BASE, 0, 0); // Initialize Port Expander |
Notes |
None. |
Expander_Read_Byte
Prototype |
sub function Expander_Read_Byte(dim ModuleAddress, RegAddress as byte) as byte |
---|---|
Description |
The function reads byte from Port Expander. |
Parameters |
|
Returns |
Byte read. |
Requires |
Port Expander must be initialized. See Expander_Init. |
Example |
' Read a byte from Port Expander's register dim read_data as byte ... read_data = Expander_Read_Byte(0,1) |
Notes |
None. |
Expander_Write_Byte
Prototype |
sub procedure Expander_Write_Byte(dim ModuleAddress, RegAddress, Data as byte) |
---|---|
Description |
Routine writes a byte to Port Expander. |
Parameters |
|
Returns |
Nothing. |
Requires |
Port Expander must be initialized. See Expander_Init. |
Example |
' Write a byte to the Port Expander's register Expander_Write_Byte(0,1,$FF) |
Notes |
None. |
Expander_Read_PortA
Prototype |
sub function Expander_Read_PortA(dim ModuleAddress as byte) as byte |
---|---|
Description |
The function reads byte from Port Expander's PortA. |
Parameters |
|
Returns |
Byte read. |
Requires |
Port Expander must be initialized. See Expander_Init. Port Expander's PortA should be configured as input. See Expander_Set_DirectionPortA and Expander_Set_DirectionPortAB routines. |
Example |
' Read a byte from Port Expander's PORTA dim read_data as byte ... Expander_Set_DirectionPortA(0,$FF) ' set expander's porta to be input ... read_data = Expander_Read_PortA(0) |
Notes |
None. |
Expander_Read_PortB
Prototype |
sub function Expander_Read_PortB(dim ModuleAddress as byte) as byte |
---|---|
Description |
The function reads byte from Port Expander's PortB. |
Parameters |
|
Returns |
Byte read. |
Requires |
Port Expander must be initialized. See Expander_Init. Port Expander's PortB should be configured as input. See Expander_Set_DirectionPortB and Expander_Set_DirectionPortAB routines. |
Example |
' Read a byte from Port Expander's PORTB dim read_data as byte ... Expander_Set_DirectionPortB(0,$FF) ' set expander's portb to be input ... read_data = Expander_Read_PortB(0) |
Notes |
None. |
Expander_Read_PortAB
Prototype |
sub function Expander_Read_PortAB(dim ModuleAddress as byte) as word |
---|---|
Description |
The function reads word from Port Expander's ports. PortA readings are in the higher byte of the result. PortB readings are in the lower byte of the result. |
Parameters |
|
Returns |
Word read. |
Requires |
Port Expander must be initialized. See Expander_Init. Port Expander's PortA and PortB should be configured as inputs. See Expander_Set_DirectionPortA, Expander_Set_DirectionPortB and Expander_Set_DirectionPortAB routines. |
Example |
' Read a byte from Port Expander's PORTA and PORTB dim read_data as word ... Expander_Set_DirectionPortAB(0,$FFFF) ' set expander's porta and portb to be input ... read_data s= Expander_Read_PortAB(0) |
Notes |
None. |
Expander_Write_PortA
Prototype |
sub procedure Expander_Write_PortA(dim ModuleAddress, Data as byte) |
---|---|
Description |
The function writes byte to Port Expander's PortA. |
Parameters |
|
Returns |
Nothing. |
Requires |
Port Expander must be initialized. See Expander_Init. Port Expander's PortA should be configured as output. See Expander_Set_DirectionPortA and Expander_Set_DirectionPortAB routines. |
Example |
' Write a byte to Port Expander's PORTA ... Expander_Set_DirectionPortA(0,$00) ' set expander's porta to be output ... Expander_Write_PortA(0, $AA) |
Notes |
None. |
Expander_Write_PortB
Prototype |
sub procedure Expander_Write_PortB(dim ModuleAddress, Data as byte) |
---|---|
Description |
The function writes byte to Port Expander's PortB. |
Parameters |
|
Returns |
Nothing. |
Requires |
Port Expander must be initialized. See Expander_Init. Port Expander's PortB should be configured as output. See Expander_Set_DirectionPortB and Expander_Set_DirectionPortAB routines. |
Example |
' Write a byte to Port Expander's PORTB ... Expander_Set_DirectionPortB(0,$00) ' set expander's portb to be output ... Expander_Write_PortB(0,$55) |
Notes |
None. |
Expander_Write_PortAB
Prototype |
sub procedure Expander_Write_PortAB(dim ModuleAddress as byte, dim Data as word) |
---|---|
Description |
The function writes word to Port Expander's ports. |
Parameters |
|
Returns |
Nothing. |
Requires |
Port Expander must be initialized. See Expander_Init. Port Expander's PortA and PortB should be configured as outputs. See Expander_Set_DirectionPortA, Expander_Set_DirectionPortB and Expander_Set_DirectionPortAB routines. |
Example |
' Write a byte to Port Expander's PORTA and PORTB ... Expander_Set_DirectionPortAB(0, $0000) ' set expander's porta and portb to be output ... Expander_Write_PortAB(0, $AA55) |
Notes |
None. |
Expander_Set_DirectionPortA
Prototype |
sub procedure Expander_Set_DirectionPortA(dim ModuleAddress, Data as byte) |
---|---|
Description |
The function sets Port Expander's PortA direction. |
Parameters |
|
Returns |
Nothing. |
Requires |
Port Expander must be initialized. See Expander_Init. |
Example |
' Set Port Expander's PORTA to be output Expander_Set_DirectionPortA(0,$00) |
Notes |
None. |
Expander_Set_DirectionPortB
Prototype |
sub procedure Expander_Set_DirectionPortB(dim ModuleAddress, Data as byte) |
---|---|
Description |
The function sets Port Expander's PortB direction. |
Parameters |
|
Returns |
Nothing. |
Requires |
Port Expander must be initialized. See Expander_Init. |
Example |
' Set Port Expander's PORTB to be input Expander_Set_DirectionPortB(0,$FF) |
Notes |
None. |
Expander_Set_DirectionPortAB
Prototype |
sub procedure Expander_Set_DirectionPortAB(dim ModuleAddress, Direction as word) |
---|---|
Description |
The function sets Port Expander's PortA and PortB direction. |
Parameters |
|
Returns |
Nothing. |
Requires |
Port Expander must be initialized. See Expander_Init. |
Example |
' Set Port Expander's PORTA to be output and PORTB to be input Expander_Set_DirectionPortAB(0,$00FF) |
Notes |
None. |
Expander_Set_PullUpsPortA
Prototype |
sub procedure Expander_Set_PullUpsPortA(dim ModuleAddress, Data as byte) |
---|---|
Description |
The function sets Port Expander's PortA pull up/down resistors. |
Parameters |
|
Returns |
Nothing. |
Requires |
Port Expander must be initialized. See Expander_Init. |
Example |
' Set Port Expander's PORTA pull-up resistors Expander_Set_PullUpsPortA(0, $FF) |
Notes |
None. |
Expander_Set_PullUpsPortB
Prototype |
sub procedure Expander_Set_PullUpsPortB(dim ModuleAddress, Data as byte) |
---|---|
Description |
The function sets Port Expander's PortB pull up/down resistors. |
Parameters |
|
Returns |
Nothing. |
Requires |
Port Expander must be initialized. See Expander_Init. |
Example |
' Set Port Expander's PORTB pull-up resistors Expander_Set_PullUpsPortB(0, 0xFF) |
Notes |
None. |
Expander_Set_PullUpsPortAB
Prototype |
sub procedure Expander_Set_PullUpsPortAB(dim ModuleAddress as byte, dim PullUps as word) |
---|---|
Description |
The function sets Port Expander's PortA and PortB pull up/down resistors. |
Parameters |
|
Returns |
Nothing. |
Requires |
Port Expander must be initialized. See Expander_Init. |
Example |
' Set Port Expander's PORTA and PORTB pull-up resistors Expander_Set_PullUpsPortAB(0, $FFFF) |
Notes |
None. |
Library Example
The example demonstrates how to communicate with Port Expander MCP23S17. Note that Port Expander pins A2 A1 A0 are connected to GND so Port Expander Hardware Address is 0
.
Stellaris
program PortExpander ' Port Expander module connections dim SPExpanderRST as sbit at GPIO_PORTA_DATA0_bit SPExpanderCS as sbit at GPIO_PORTA_DATA1_bit SPExpanderRST_Direction as sbit at GPIO_PORTA_DIR0_bit SPExpanderCS_Direction as sbit at GPIO_PORTA_DIR1_bit ' End Port Expander module connections dim counter as word main: counter = 0 ' GPIO_PORTD output for LEDs GPIO_Digital_Output(@GPIO_PORTD, _GPIO_PINMASK_ALL) ' Port Expander uses SPI0 module SPI0_Init() Expander_Init(0) ' Initialize Port Expander Expander_Set_DirectionPortA(0, 0x00) ' Set Expander's PORTA to be output Expander_Set_DirectionPortB(0,0xFF) ' Set Expander's PORTB to be input Expander_Set_PullUpsPortB(0,0xFF) ' Set pull-ups to all of the Expander's PORTB pins while ( TRUE ) ' Endless loop Expander_Write_PortA(0, counter) ' Write i to expander's PORTA Inc(counter) GPIO_PORTD_DATA = Expander_Read_PortB(0) ' Read expander's PORTB and write it to LEDs Delay_ms(75) wend end.
STM32
program PortExpander ' Port Expander module connections dim SPExpanderRST as sbit at GPIOB_ODR.B0 SPExpanderCS as sbit at GPIOB_ODR.B1 ' End Port Expander module connections dim counter as word main: counter = 0 ' PORTD output for LEDs GPIO_Digital_Output(@GPIOD_BASE, _GPIO_PINMASK_ALL) ' Port Expander uses SPI1 module at PORTB[3:5] SPI1_Init_Advanced(_SPI_FPCLK_DIV4, _SPI_MASTER or _SPI_8_BIT or _SPI_CLK_IDLE_LOW or _SPI_FIRST_CLK_EDGE_TRANSITION or _SPI_MSB_FIRST or _SPI_SS_DISABLE or _SPI_SSM_ENABLE or _SPI_SSI_1, @_GPIO_MODULE_SPI1_PB345) GPIO_Alternate_Function_Enable(@_GPIO_MODULE_SWJ_JTAGDISABLE) Expander_Init(0) ' Initialize Port Expander Expander_Set_DirectionPortA(0, 0x00) ' Set Expander's PORTA to be output Expander_Set_DirectionPortB(0,0xFF) ' Set Expander's PORTB to be input Expander_Set_PullUpsPortB(0,0xFF) ' Set pull-ups to all of the Expander's PORTB pins while ( TRUE ) ' Endless loop Expander_Write_PortA(0, counter) ' Write i to expander's PORTA Inc(counter) GPIOD_ODR = Expander_Read_PortB(0) ' Read expander's PORTB and write it to LEDs Delay_ms(75) wend end.
What do you think about this topic ? Send us feedback!