The MCP23008 is an 8-bit I2C I/O expander. Think of it as adding an 8-bit port to the microcontroller using just 2 wires for an I2C interface which can be shared with many devices. It's a handy way to add some extra port pins and a way to add extra interrupt capability to an already-busy microcontroller. Up to 8 MCP23008s may be added to the system by giving each chip a unique address.
The Swordfish driver makes accessing individual pins or the entire port similar to using the microcontroller's port pins in Swordfish, and isolates the complexity of using the I2C interface. There are a few configuration commands and commands for using individual port pins or addressing the entire port at once.
Unlike the driver for the MCP9800, which has a few specific functions dictated by the functions of the chip, the interface for the MCP23008 is both more flexible and more complex because of the nature of the chip. For the most part, the commands are similar to those found in Swordfish although the syntax will be slightly different.
The register descriptions and interrupt configuration are included at the start of the driver module to help clarify how to use the chip's features. Don't worry, the verbose comments don't add to the compiled program's size.
| Command |
Comment |
| I2CDevice = $40 |
Default MCP23008 address |
| Function CheckAddress () |
Returns 0 if address invalid, 1 if address present |
| Function Config_InterruptOutput (Port1 As Byte) |
0 = Open drain output 1 = Active Low 2 = Active High |
| Command |
Comment |
| Function OutputPin(Port1 As Byte) |
Set specified pin to output, IODIR register is returned |
| Function InputPin (Port1 As Byte) |
'Set specified pin to input, IODIR register is returned |
| Function LowPin (Port1 As Byte) |
Sets specified pin to output and low, OLAT register is returned |
| Function HighPin (Port1 As Byte) |
Sets specified pin to output and high, OLAT register is returned |
| Function EnablePullupPin (Port1 As Byte) |
'Enables pullup resistor on specified pin, returns GPPU register |
| Function DisablePullupPin (Port1 As Byte) |
Disables pullup resistor on specified pin, returns GPPU register |
| Function ReadPin (Port1 As Byte) |
Reads specified pin, returns 0 or 1 |
| Function InvertInputPin (Port1 As Byte) |
Changes the sense of the input pin, returns IPOL register |
| Function NormalInputPin (Port1 As Byte) |
Normal sense of the input pin, returns IPOL register |
| Function IntEnablePin (Port1 As Byte) |
Enable interrupt on pin |
| Function IntDisablePin (Port1 As Byte) |
Disable interrupt on pin |
| Function IntCompareValuePin (Port1 As Byte, Value2 As Bit) |
Value to compare pin to if in compare mode |
| Function IntModePin (Port1 As Byte, Value2 As Bit) |
Compare to value if 1, compare to previous if 0 |
| Function IntFlagPin (Port1 As Byte) |
1 if pin caused interrupt |
| Command |
Comment |
| Function IODirPort (Port1 As Byte) |
Set IO Direction, 1 = in, 0 = out. Returns IODIR reg |
| Function OutputPort (Port1 As Byte) |
Sets OLAT to specifed value. Returns OLAT reg. Does not change IODIR reg |
| Function InputPort () |
Reads GPIO. Does not change IODIR reg |
| Function PullupPort (Port1 As Byte) |
Sets GPPU to specifed value. Returns GPPU reg. Does not change IODIR reg |
| Function InputPolarityPort (Port1 As Byte) |
Inverts sense of input levels. Returns IPOL reg. Does not change IODIR reg |
| Function IntEnPort (Port1 As Byte) |
Enables interrupt on each port pin |
| Function IntCompareValuePort (Port1 As Byte) |
Set Interrupt Comparison Values |
| Function IntModePort (Port1 As Byte) |
Compare to value if 1, compare to previous if 0 |
| Function IntFlagPort (Port1 As Byte) |
1 if pin caused interrupt |
| Function IntCapPort (Port1 As Byte) |
Indicates the port state at the time of an interrupt. |
The sample program below sequentially lights LEDs connected to each port pin using pin commands and then extinguishes all of them simultaneously using a port command. Notice how simply the port pins are controlled using the Swordfish module.
{ ***************************************************************************** * Name : MCP23008 Module Demonstration * * Author : Jon Chandler * * Notice : Licensed Under Creative Commons 3.0 SA-BY * * : All Rights Reserved * * Date : 11/15/2010 * * Version : 1.0 * * Notes : Microchip MCP23008 - 8-Bit I/O Expander with Serial Interface * * : * ***************************************************************************** } 'Module MCP23008 Device =18f2520 Clock = 12 Include("MCP23008.bas") Output(PORTB.3) 'LED2 on TAP-28 board MCP23008.I2CDevice = $40 '$40 is the default for the MCP23008 - no need to specify unless different While 1 = 1 MCP23008.CheckAddress 'check I2C device connected each loop. Turn on LED if no response If MCP23008.CheckAddress = 0 Then Low(PORTB.3) Else High(PORTB.3) End If MCP23008.HighPin(0) 'make pin an output and set it high DelayMS(100) MCP23008.HighPin(1) DelayMS(100) MCP23008.HighPin(2) DelayMS(100) MCP23008.HighPin(3) DelayMS(100) MCP23008.HighPin(4) DelayMS(100) MCP23008.HighPin(5) DelayMS(100) MCP23008.HighPin(6) DelayMS(100) MCP23008.HighPin(7) DelayMS(100) MCP23008.OutputPort(%00000000) 'set all bits low DelayMS(200) Wend
{ ***************************************************************************** * Name : MCP23008Module * * Author : Jon Chandler * * Notice : Licensed Under Creative Commons 3.0 SA-BY * * : All Rights Reserved * * Date : 11/15/2010 * * Version : 1.0 * * Notes : Microchip MCP23008 - 8-Bit I/O Expander with Serial Interface * * : * ***************************************************************************** } { --------------------------------------------------------------------------------------------------- Register and Interrupt Information from the data sheet --------------------------------------------------------------------------------------------------- I/O DIRECTION (IODIR) REGISTER Controls the direction of the data I/O. When a bit is set, the corresponding pin becomes an input. When a bit is clear, the corresponding pin becomes an output. These bits control the direction of data I/O <7:0> 1 = Pin is configured as an input. 0 = Pin is configured as an output. --------------------------------------------------------------------------------------------------- INPUT POLARITY (IPOL) REGISTER The IPOL register allows the user to configure the polarity on the corresponding GPIO port bits. If a bit is set, the corresponding GPIO register bit will reflect the inverted value on the pin. These bits control the polarity inversion of the input pins <7:0> 1 = GPIO register bit will reflect the opposite logic state of the input pin. 0 = GPIO register bit will reflect the same logic state of the input pin. --------------------------------------------------------------------------------------------------- INTERRUPT-ON-CHANGE CONTROL (GPINTEN) REGISTER The GPINTEN register controls the interrupt-onchange feature for each pin. If a bit is set, the corresponding pin is enabled for interrupt-on-change. The DEFVAL and INTCON registers must also be configured if any pins are enabled for interrupt-on-change. General purpose I/O interrupt-on-change bits <7:0> 1 = Enable GPIO input pin for interrupt-on-change event. 0 = Disable GPIO input pin for interrupt-on-change event. --------------------------------------------------------------------------------------------------- DEFAULT COMPARE (DEFVAL) REGISTER FOR INTERRUPT-ONCHANGE The default comparison value is configured in the DEFVAL register. If enabled (via GPINTEN and INTCON) to compare against the DEFVAL register, an opposite value on the associated pin will cause an interrupt to occur. --------------------------------------------------------------------------------------------------- INTERRUPT CONTROL (INTCON) REGISTER The INTCON register controls how the associated pin value is compared for the interrupt-on-change feature. If a bit is set, the corresponding I/O pin is compared against the associated bit in the DEFVAL register. If a bit value is clear, the corresponding I/O pin is compared against the previous value. These bits set the compare value for pins configured for interrupt-on-change from defaults <7:0>. Refer to INTCON and GPINTEN. 1 = Controls how the associated pin value is compared for interrupt-on-change. 0 = Pin value is compared against the previous pin value. --------------------------------------------------------------------------------------------------- CONFIGURATION (IOCON) REGISTER The IOCON register contains several bits for configuring the device: • The Sequential Operation (SEQOP) controls the incrementing function of the address pointer. If the address pointer is disabled, the address pointer does not automatically increment after each byte is clocked during a serial transfer. This feature is useful when it is desired to continuously poll (read) or modify (write) a register. • The Slew Rate (DISSLW) bit controls the slew rate function on the SDA pin. If enabled, the SDA slew rate will be controlled when driving from a high to a low. • The Open-Drain (ODR) control bit enables/disables the INT pin for open-drain configuration. • The Interrupt Polarity (INTPOL) control bit sets the polarity of the INT pin. This bit is functional only when the ODR bit is cleared, configuring the INT pin as active push-pull. bit 7-6 Unimplemented: Read as ‘0’. bit 5 SEQOP: Sequential Operation mode bit. 1 = Sequential operation disabled, address pointer does not increment. 0 = Sequential operation enabled, address pointer increments. bit 4 DISSLW: Slew Rate control bit for SDA output. 1 = Slew rate disabled. 0 = Slew rate enabled. bit 3 HAEN: N/A - Address pins are always enabled on MCP23008. bit 2 ODR: This bit configures the INT pin as an open-drain output. 1 = Open-drain output (overrides the INTPOL bit). 0 = Active driver output (INTPOL bit sets the polarity). bit 1 INTPOL: This bit sets the polarity of the INT output pin. 1 = Active-high. 0 = Active-low. bit 0 Unimplemented: Read as ‘0’. --------------------------------------------------------------------------------------------------- PULL-UP RESISTOR CONFIGURATION (GPPU) REGISTER The GPPU register controls the pull-up resistors for the port pins. If a bit is set and the corresponding pin is configured as an input, the corresponding port pin is internally pulled up with a 100 kO resistor. These bits control the weak pull-up resistors on each pin (when configured as an input) 1 = Pull-up enabled. 0 = Pull-up disabled. --------------------------------------------------------------------------------------------------- INTERRUPT FLAG (INTF) REGISTER The INTF register reflects the interrupt condition on the port pins of any pin that is enabled for interrupts via the GPINTEN register. A ‘set’ bit indicates that the associated pin caused the interrupt. This register is ‘read-only’. Writes to this register will be ignored. Note: INTF will always reflect the pin(s) that have an interrupt condition. For example, one pin causes an interrupt to occur and is captured in INTCAP and INF. If before clearing the interrupt another pin changes, which would normally cause an interrupt, it will be reflected in INTF, but not INTCAP These bits reflect the interrupt condition on the port. Will reflect the change only if interrupts are enabled (GPINTEN) <7:0>. 1 = Pin caused interrupt. 0 = Interrupt not pending --------------------------------------------------------------------------------------------------- INTERRUPT CAPTURE (INTCAP) REGISTER The INTCAP register captures the GPIO port value at the time the interrupt occurred. The register is ‘readonly’ and is updated only when an interrupt occurs. The register will remain unchanged until the interrupt is cleared via a read of INTCAP or GPIO. These bits reflect the logic level on the port pins at the time of interrupt due to pin change <7:0> 1 = Logic-high. 0 = Logic-low. --------------------------------------------------------------------------------------------------- PORT (GPIO) REGISTER The GPIO register reflects the value on the port. Reading from this register reads the port. Writing to this register modifies the Output Latch (OLAT) register. These bits reflect the logic level on the pins <7:0> 1 = Logic-high. 0 = Logic-low. --------------------------------------------------------------------------------------------------- OUTPUT LATCH REGISTER (OLAT) The OLAT register provides access to the output latches. A read from this register results in a read of the OLAT and not the port itself. A write to this register modifies the output latches that modify the pins configured as outputs. These bits reflect the logic level on the output latch <7:0> 1 = Logic-high. 0 = Logic-low. --------------------------------------------------------------------------------------------------- --------------------------------------------------------------------------------------------------- Interrupt Logic The interrupt output pin will activate if an internal interrupt occurs. The interrupt block is configured by the following registers: • GPINTEN – enables the individual inputs • DEFVAL – holds the values that are compared against the associated input port values • INTCON – controls if the input values are compared against DEFVAL or the previous values on the port • IOCON (ODR and INPOL) – configures the INT pin as push-pull, open-drain and active-level Only pins configured as inputs can cause interrupts. Pins configured as outputs have no affect on INT. Interrupt activity on the port will cause the port value to be captured and copied into INTCAP. The interrupt will remain active until the INTCAP or GPIO register is read. Writing to these registers will not affect the interrupt. The first interrupt event will cause the port contents to be copied into the INTCAP register. Subsequent interrupt conditions on the port will not cause an interrupt to occur as long as the interrupt is not cleared by a read of INTCAP or GPIO. INTERRUPT CONDITIONS There are two possible configurations to cause interrupts (configured via INTCON): 1. Pins configured for interrupt-on-pin-change will cause an interrupt to occur if a pin changes to the opposite state. The default state is reset after an interrupt occurs. For example, an interrupt occurs by an input changing from 1 to 0. The new initial state for the pin is a logic 0. 2. Pins configured for interrupt-on-change from register value will cause an interrupt to occur if the corresponding input pin differs from the register bit. The interrupt condition will remain as long as the condition exists, regardless if the INTAP or GPIO is read. --------------------------------------------------------------------------------------------------- --------------------------------------------------------------------------------------------------- } Module MCP23008 Include ("i2c.bas") 'Registers Public Const REG_IODIR = $00 Public Const REG_IPOL = $01 Public Const REG_GPINTEN = $02 Public Const REG_DEFVAL = $03 Public Const REG_INTCON = $04 Public Const REG_IOCON = $05 Public Const REG_GPPU = $06 Public Const REG_INTF = $07 Public Const REG_INTCAP = $08 Public Const REG_GPIO = $09 Public Const REG_OLAT = $0A 'Configuration Bits Public Const ConstConfig_SREAD = 5 Public Const ConstConfig_DISSLW = 4 Public Const ConstConfig_HAEN = 3 Public Const ConstConfig_ODR = 2 Public Const ConstConfig_INTPOL = 1 Public Dim I2CDevice As Byte Public Dim I2CPointer As Byte Public Dim Port1 As Byte Public Dim Port2 As Byte Dim Value1 As Byte Dim Value2 As Byte Public Sub Read_REG(Pointer As Byte, ByRef Val1 As Byte) I2C.Start I2C.WriteByte(I2CDevice) I2C.WriteByte(Pointer) I2C.Stop I2C.Restart I2C.WriteByte(I2CDevice+1) Val1 = I2C.ReadByte I2C.Acknowledge(I2C_NOT_ACKNOWLEDGE) I2C.Stop End Sub Public Sub Write_REG(Pointer As Byte, ByRef Val1 As Byte) I2C.Start I2C.WriteByte(I2CDevice) I2C.WriteByte(Pointer) I2C.WriteByte(val1) I2C.Stop End Sub Public Function CheckAddress () As Bit 'Returns 0 if address invalid, 1 if address present Read_REG(REG_GPIO, Value1) If I2C.NotAcknowledged = true Then result = 0 Else result = 1 End If I2C.Stop End Function '**************************************************************************** '* Pin Functions - Agrument is pin number, returned value is register value * '**************************************************************************** Public Function OutputPin(Port1 As Byte) As Byte 'Set specified pin to output, IODIR register is returned Read_REG(REG_IODIR, Value1) Select Port1 Case = 0 Value1.0 = 0 Case = 1 Value1.1 = 0 Case = 2 Value1.2 = 0 Case = 3 Value1.3 = 0 Case = 4 Value1.4 = 0 Case = 5 Value1.5 = 0 Case = 6 Value1.6 = 0 Case = 7 Value1.7 = 0 End Select Write_REG(REG_IODIR, Value1) result = Value1 End Function Public Function InputPin (Port1 As Byte) As Byte 'Set specified pin to input, IODIR register is returned Read_REG(REG_IODIR, Value1) Select Port1 Case = 0 Value1.0 = 1 Case = 1 Value1.1 = 1 Case = 2 Value1.2 = 1 Case = 3 Value1.3 = 1 Case = 4 Value1.4 = 1 Case = 5 Value1.5 = 1 Case = 6 Value1.6 = 1 Case = 7 Value1.7 = 1 End Select Write_REG(REG_IODIR, Value1) result = Value1 End Function Public Function LowPin (Port1 As Byte) As Byte 'Sets specified pin to output and low, OLAT register is returned Read_REG(REG_IODIR, Value1) ' set bit for output Select Port1 Case = 0 Value1.0 = 0 Case = 1 Value1.1 = 0 Case = 2 Value1.2 = 0 Case = 3 Value1.3 = 0 Case = 4 Value1.4 = 0 Case = 5 Value1.5 = 0 Case = 6 Value1.6 = 0 Case = 7 Value1.7 = 0 result = Value1 End Select Write_REG(REG_IODIR, Value1) Read_REG(REG_OLAT, Value1) Select Port1 Case = 0 Value1.0 = 0 Case = 1 Value1.1 = 0 Case = 2 Value1.2 = 0 Case = 3 Value1.3 = 0 Case = 4 Value1.4 = 0 Case = 5 Value1.5 = 0 Case = 6 Value1.6 = 0 Case = 7 Value1.7 = 0 End Select Write_REG(REG_OLAT, Value1) result = Value1 End Function Public Function HighPin (Port1 As Byte) As Byte 'Sets specified pin to output and high, OLAT register is returned Read_REG(REG_IODIR, Value1) ' set bit for output Select Port1 Case = 0 Value1.0 = 0 Case = 1 Value1.1 = 0 Case = 2 Value1.2 = 0 Case = 3 Value1.3 = 0 Case = 4 Value1.4 = 0 Case = 5 Value1.5 = 0 Case = 6 Value1.6 = 0 Case = 7 Value1.7 = 0 result = Value1 End Select Write_REG(REG_IODIR, Value1) Read_REG(REG_OLAT, Value1) Select Port1 Case = 0 Value1.0 = 1 Case = 1 Value1.1 = 1 Case = 2 Value1.2 = 1 Case = 3 Value1.3 = 1 Case = 4 Value1.4 = 1 Case = 5 Value1.5 = 1 Case = 6 Value1.6 = 1 Case = 7 Value1.7 = 1 result = Value1 End Select Write_REG(REG_OLAT, Value1) End Function Public Function EnablePullupPin (Port1 As Byte) As Byte 'Enables pullup resistor on specified pin, returns GPPU register Read_REG(REG_GPPU, Value1) Select Port1 Case = 0 Value1.0 = 1 Case = 1 Value1.1 = 1 Case = 2 Value1.2 = 1 Case = 3 Value1.3 = 1 Case = 4 Value1.4 = 1 Case = 5 Value1.5 = 1 Case = 6 Value1.6 = 1 Case = 7 Value1.7 = 1 End Select Write_REG(REG_GPPU, Value1) result = Value1 End Function Public Function DisablePullupPin (Port1 As Byte) As Byte 'Disables pullup resistor on specified pin, returns GPPU register Read_REG(REG_GPPU, Value1) Select Port1 Case = 0 Value1.0 = 0 Case = 1 Value1.1 = 0 Case = 2 Value1.2 = 0 Case = 3 Value1.3 = 0 Case = 4 Value1.4 = 0 Case = 5 Value1.5 = 0 Case = 6 Value1.6 = 0 Case = 7 Value1.7 = 0 End Select Write_REG(REG_GPPU, Value1) result = Value1 End Function Public Function ReadPin (Port1 As Byte) As Bit 'Reads specified pin, returns 0 or 1 Read_REG(REG_GPIO, Value1) Select Port1 Case = 0 result = Value1.0 Case = 1 result = Value1.1 Case = 2 result = Value1.2 Case = 3 result = Value1.3 Case = 4 result = Value1.4 Case = 5 result = Value1.5 Case = 6 result = Value1.6 Case = 7 result = Value1.7 End Select End Function Public Function InvertInputPin (Port1 As Byte) As Byte 'Changes the sense of the input pin, returns IPOL register Read_REG(REG_IPOL, Value1) Select Port1 Case = 0 Value1.0 = 0 Case = 1 Value1.1 = 0 Case = 2 Value1.2 = 0 Case = 3 Value1.3 = 0 Case = 4 Value1.4 = 0 Case = 5 Value1.5 = 0 Case = 6 Value1.6 = 0 Case = 7 Value1.7 = 0 End Select Write_REG(REG_IPOL, Value1) result = Value1 End Function Public Function NormalInputPin (Port1 As Byte) As Byte 'Normal sense of the input pin, returns IPOL register Read_REG(REG_IPOL, Value1) Select Port1 Case = 0 Value1.0 = 0 Case = 1 Value1.1 = 0 Case = 2 Value1.2 = 0 Case = 3 Value1.3 = 0 Case = 4 Value1.4 = 0 Case = 5 Value1.5 = 0 Case = 6 Value1.6 = 0 Case = 7 Value1.7 = 0 End Select Write_REG(REG_IPOL, Value1) result = Value1 End Function '**************************************************************************** '* Interrupt Functions by Pin * '**************************************************************************** Public Function IntEnablePin (Port1 As Byte) As Byte 'enable interrupt on pin Read_REG(REG_GPINTEN, Value1) Select Port1 Case = 0 Value1.0 = 1 Case = 1 Value1.1 = 1 Case = 2 Value1.2 = 1 Case = 3 Value1.3 = 1 Case = 4 Value1.4 = 1 Case = 5 Value1.5 = 1 Case = 6 Value1.6 = 1 Case = 7 Value1.7 = 1 End Select Write_REG(REG_GPINTEN, Value1) result = Value1 End Function Public Function IntDisablePin (Port1 As Byte) As Byte 'disable interrupt on pin Read_REG(REG_GPINTEN, Value1) Select Port1 Case = 0 Value1.0 = 0 Case = 1 Value1.1 = 0 Case = 2 Value1.2 = 0 Case = 3 Value1.3 = 0 Case = 4 Value1.4 = 0 Case = 5 Value1.5 = 0 Case = 6 Value1.6 = 0 Case = 7 Value1.7 = 0 End Select Write_REG(REG_GPINTEN, Value1) result = Value1 End Function Public Function IntCompareValuePin (Port1 As Byte, Value2 As Bit) As Byte 'value to compare pin to if in compare mode Read_REG(REG_DEFVAL, Value1) Select Port1 Case = 0 Value1.0 = Value2 Case = 1 Value1.1 = Value2 Case = 2 Value1.2 = Value2 Case = 3 Value1.3 = Value2 Case = 4 Value1.4 = Value2 Case = 5 Value1.5 = Value2 Case = 6 Value1.6 = Value2 Case = 7 Value1.7 = Value2 End Select Write_REG(REG_GPINTEN, Value1) result = Value1 End Function Public Function IntModePin (Port1 As Byte, Value2 As Bit) As Byte 'compare to value if 1, compare to previous if 0 Read_REG(REG_INTCON, Value1) Select Port1 Case = 0 Value1.0 = Value2 Case = 1 Value1.1 = Value2 Case = 2 Value1.2 = Value2 Case = 3 Value1.3 = Value2 Case = 4 Value1.4 = Value2 Case = 5 Value1.5 = Value2 Case = 6 Value1.6 = Value2 Case = 7 Value1.7 = Value2 End Select Write_REG(REG_INTCON, Value1) result = Value1 End Function Public Function IntFlagPin (Port1 As Byte) As Bit '1 if pin caused interrupt Read_REG(REG_INTF, Value1) Select Port1 Case = 0 result = Value1.0 Case = 1 result = Value1.1 Case = 2 result = Value1.2 Case = 3 result = Value1.3 Case = 4 result = Value1.4 Case = 5 result = Value1.5 Case = 6 result = Value1.6 Case = 7 result = Value1.7 End Select End Function '****************************************************************************** '* Port Functions - Agrument is byte to set, returned value is register value * '****************************************************************************** Public Function IODirPort (Port1 As Byte) As Byte 'set IO Direction, 1 = in, 0 = out. Returns IODIR reg Write_REG(REG_IODIR, Port1) Read_REG(REG_IODIR, Port1) result = Port1 End Function Public Function OutputPort (Port1 As Byte) As Byte 'sets OLAT to specifed value. Returns OLAT reg Does not change IODIR reg Write_REG(REG_OLAT, Port1) Read_REG(REG_OLAT, Port1) result = Port1 End Function Public Function InputPort () As Byte 'Reads GPIO. Does not change IODIR reg Read_REG(REG_GPIO, Port1) result = Port1 End Function Public Function PullupPort (Port1 As Byte) As Byte 'sets GPPU to specifed value. Returns GPPU reg. Does not change IODIR reg Write_REG(REG_GPPU, Port1) Read_REG(REG_GPPU, Port1) result = Port1 End Function Public Function InputPolarityPort (Port1 As Byte) As Byte 'Inverts sense of input levels. Returns IPOL reg. Does not change IODIR reg Write_REG(REG_IPOL, Port1) Read_REG(REG_IPOL, Port1) result = Port1 End Function '**************************************************************************** '* Interrupt Functions by Port * '**************************************************************************** Public Function IntEnPort (Port1 As Byte) As Byte 'Enables interrupt on each port pin Write_REG(REG_GPINTEN, Port1) Read_REG(REG_GPINTEN, Port1) result = Port1 End Function Public Function IntCompareValuePort (Port1 As Byte) As Byte 'Set Interrupt Comparison Values Write_REG(REG_DEFVAL, Port1) Read_REG(REG_GPINTEN, Port1) result = Port1 End Function Public Function IntModePort (Port1 As Byte) As Byte 'compare to value if 1, compare to previous if 0 Write_REG(REG_INTCON, Port1) Read_REG(REG_INTCON, Port1) result = Port1 End Function Public Function IntFlagPort (Port1 As Byte) As Byte '1 if pin caused interrupt Read_REG(REG_INTF, Port1) result = Port1 End Function Public Function IntCapPort (Port1 As Byte) As Byte 'Indicates the port state at the time of an interrupt. Read_REG(REG_INTCAP, Port1) result = Port1 End Function '****************************************************************************** '* Configuration Options * '****************************************************************************** Public Function Config_InterruptOutput (Port1 As Byte) As Byte Read_REG(REG_IOCON, Value1) Select Port1 Case = 0 'Open drain output Value1.2 = 1 Case = 1 'Active Low Value1.2 = 0 Value1.1 = 0 Case = 2 'Active High Value1.2 = 0 Value1.1 = 1 End Select Write_REG(REG_IOCON, Value1) result = Value1 End Function I2CDevice = $40 'default address I2CPointer = $00 I2C.Initialize I2C.Start I2C.Stop