A more complete description and additional routines will appear shortly.
' MCP23016_1.Bas
'
' Illustrates an interface with the MCP23016 16-bit I/O Expander. This is inteneded to illustrate all features of the
' MCP23016 other than the capture feature; writing a byte to a register, reading a byte from a register and similarly writing
' and reading a bit at a specified bit position in a register.
'
' The MCP23016 is set up for high speed sampling by writing a 1 to register IOCON0, bit 0. Port0 is set up for outputs by
' writing zeros to all eight bits of IODIR0. Similarly Port1 is setup for all inputs by writing zeros to all eight bits of
' IODIR1. The polarity of GP1.0 is inverted by writing a 1 to register IOPOL1, bit 0.
'
' The program continually loops, reading the state on input GP1.0. If at logic zero, the LED on OLAT0.0 is turned on and off.
'
' Note that the reading of the input state of the GP1.0 bit involves reading the entire GP1 byte and determining the state of
' the specified bit. Note that writing the bit to OLAT0.0 involves reading register OLAT0 and setting the specified bit to
' the specified state.
'
'
' BX24 MCP23016
' Note 1
' Term 9 ------------------------ SDA (term 15) ----------- To other I2C devices
' Term 8 ------------------------ SCL (term 14) -----------
'
' GRD --- A2 (term 16)
' GRD --- A1 (term 17)
' GRD --- A0 (term 18)
'
'
' GRD -- \---- GP1.0 (term 2)
' LED
' GP0.0 (term 21) ----- 330 ---->|--- GRD
'
' Note 1. 4.7K resistor to +5 VDC on SDA, SCL and GP1.0.
'
' CLK circuitry on CLK (term 9) consists of a 4.7K resistor and a 20 pFd capacitor.
'
'
' coyright, Peter H. Anderson, Baltimore, MD, May, '03
const SCL as byte=8
const SDA as byte=9
const GP0 as Byte = &H00
const GP1 as Byte = &H01
const OLAT0 as Byte = &H02
const OLAT1 as Byte = &H03
const IPOL0 as Byte = &H04
const IPOL1 as Byte = &H05
const IODIR0 as Byte = &H06
const IODIR1 as Byte = &H07
const INTCAP0 as Byte = &H08
const INTCAP1 as Byte = &H09
const IOCON0 as Byte = &H0A
const IOCON1 as Byte = &H0B
Sub Main()
Call Sleep(1.0) ' to avoid download problems
Debug.Print "..............." ' to see that something is happening
Call MCP23016WriteBit(0, IOCON0, 0, 1) ' set to high sampling frequency
Call MCP23016WriteByte(0, IODIR0, &H00) ' make Port0 outputs
Call MCP23016WriteByte(0, IODIR1, &Hff) ' Port1 are inputs
Call MCP23016WriteBit(0, IPOL1, 0, 1) ' input 0 on Port1 inverted.
Do
If (MCP23016ReadBit(0, GP1, 0) = 1) Then
Call FlashLed()
End If
Loop
End Sub
Sub FlashLED()
Call MCP23016WriteBit(0, OLAT0, 0, 1) ' turn LED on
Call Sleep(0.25)
Call MCP23016WriteBit(0, OLAT0, 0, 0) ' turn LED off
Call Sleep(0.25)
End Sub
Sub MCP23016WriteByte(ByVal Dev as Byte, ByVal Reg as Byte, ByVal Val as Byte)
Call I2CStart()
Call I2COutByte(bx0100_0000 OR (Dev * 2))
Call I2COutByte(Reg)
Call I2COutByte(Val)
Call I2CStop()
End Sub
Sub MCP23016WriteBit(ByVal Dev as Byte, ByVal Reg as Byte, ByVal BitPos as Byte, ByVal BitVal as Byte)
Dim Val as Byte
Val = MCP23016ReadByte(Dev, Reg)
Call PutBit(Val, BitPos, BitVal)
Call MCP23016WriteByte(Dev, Reg, Val)
End Sub
Function MCP23016ReadByte(ByVal Dev as Byte, ByVal Reg as Byte) as Byte
Dim Val as Byte
Call I2CStart()
Call I2COutByte(bx0100_0000 OR (Dev * 2))
Call I2COutByte(Reg)
Call I2CStart()
Call I2COutByte(bx0100_0000 OR (Dev * 2) + bx0000_0001)
Val = I2CInByte(0)
Call I2CStop()
MCP23016ReadByte = Val
End Function
Function MCP23016ReadBit(ByVal Dev as Byte, ByVal Reg as Byte, ByVal BitPos as Byte) as Byte
Dim Val as Byte
Dim BitVal as Byte
Val = MCP23016ReadByte(Dev, Reg)
MCP23016ReadBit = GetBit(Val, BitPos)
End Function
Sub I2CStart()
Call PutPin(SCL,0)
Call PutPin(SDA,2)
Call PutPin(SCL,2)
Call PutPin(SDA,0)
Call PutPin(SCL,0)
End Sub
Sub I2CStop()
Call PutPin(SCL, 0)
Call PutPin(SDA, 0)
Call PutPin(SCL,2)
Call PutPin(SDA,2)
End Sub
Sub I2COutByte(ByVal X as Byte)
Dim N as Integer
For N=1 to 8
If((x AND &H80) <> 0) Then
Call PutPin(SDA,2)
' Call PutByte(Asc("1")) ' used for debugging
Else
Call PutPin(SDA,0)
' Call PutByte(Asc("0")) ' used for debugging
End If
Call PutPin(SCL,2)
Call PutPin(SCL,0)
x=x*2
Next
' Call NewLine() ' used for debugging
Call PutPin(SDA,2)
Call PutPin(SCL,2)
Call PutPin(SCL,0)
Call PutPin(SDA,2)
End Sub
Function I2CInByte(ByVal Ack as Byte) as Byte
Dim N as Integer
Dim X as Byte
FOR N=1 to 8
Call PutPin(SCL,2)
If(GetPin(SDA)=1) Then
X = X * 2 +1
Else
X = X * 2
End If
Call PutPin(SCL, 0)
NEXT
If (Ack <> 0) Then
Call PutPin(SDA, 0)
Else
Call PutPin(SDA,2)
End If
Call PutPin(SCL,2)
Call PutPin(SCL,0)
Call PutPin(SDA,0)
I2CInByte = X
End Function