I2Cout
Syntax
I2Cout SDA_Pin, SCL_Pin, Control, { Address }, [ OutputData ]
Overview
Transmit a value to the I2C bus, by first sending the control and optional address out of the clock pin (SCL), and data pin (SDA).
Parameters
SDA_Pin is a Port.Pin value that specifies the I/O pin that will be connected to the I2C device's data line (SDA). This pin's I/O direction will be changed to input and will remain in that state after the instruction is completed. SCL_Pin is a Port.Pin value that specifies the I/O pin that will be connected to the I2C device's clock line (SCL). This pin's I/O direction will be changed to output. Control is a constant value or a byte sized variable expression. Address is an optional constant, variable, or expression. OutputData is a list of variables, constants, expressions and modifiers that informs I2Cout how to format outgoing data. I2Cout can transmit individual or repeating bytes, convert values into decimal, hex or binary text representations, or transmit strings of bytes from variable arrays.
These actions can be combined in any order in the OutputData list.
The I2Cout command operates as an I2C master and may be used to interface with any device that complies with the 2-wire I2C protocol. The most significant 7-bits of control byte contain the control code and the slave address of the device being interfaced with. Bit-0 is the flag that indicates whether a read or write command is being implemented.
For example, if we were interfacing to an external EEPROM such as the 24LC32, the control code would be 0b10100000 or $A0. The most significant 4-bits (1010) are the EEPROM's unique slave address. Bits 1 to 3 reflect the three address pins of the EEPROM. And Bit-0 is clear to signify that we wish to write to the EEPROM. Note that this bit is automatically cleared by the I2Cout command, regardless of its initial value.
Example
' Send a byte to the I2C bus.
Device = 18F26K40
' Select the device to compile for
Declare Xtal = 16 ' Tell the compiler the device will be operating at 16MHz
Dim bMyVar as Byte
' We'll only read 8-bits
Dim wAddress as Word
' 16-bit address required
Symbol cControl = 0b10100000 ' Target an EEPROM
Dim SDA_Pin as PORTC.3
' Alias the SDA (Data) line
Dim SCL_Pin as PORTC.4
' Alias the SSL (Clock) line
Address = 20
' Write to address 20
bMyVar = 200
' The value place into address 20
I2Cout SDA_Pin, SCL_Pin, cControl, wAddress, [bMyVar] ' Send the byte to EEPROM
DelayMs 10
' Allow time for allocation of byte
Address is an optional parameter that may be an 8-bit or 16-bit value. If a variable is used in this position, the size of address is dictated by the size of the variable used (byte or word). In the case of the above EEPROM interfacing, the 24LC32 EEPROM requires a 16-bit address. While the smaller types require an 8-bit address. Make sure you assign the right size address for the device interfaced with, or you may not achieve the results you intended. The value sent to the bus depends on the size of the variables used. For example: -
Dim wMyVar as Word
' Create a Word size variable
I2Cout SDA_Pin, SCL_Pin, Control, wAddress, [wMyVar]
Will send a 16-bit value to the bus. While: -
Dim bMyVar as Byte
' Create a Byte size variable
I2Cout SDA_Pin, SCL_Pin, cControl, wAddress, [bMyVar]
Will send an 8-bit value to the bus. Using more than one variable within the brackets allows differing variable sizes to be sent. For example: -
Dim bMyVar as Byte
Dim wMyVar as Word
I2Cout SDA_Pin, SCL_Pin, cControl, wAddress, [bMyVar, wMyVar]
Will send two values to the bus, the first being an 8-bit value dictated by the size of variable bMyVar which has been declared as a Byte. And a 16-bit value, this time dictated by the size of the variable wMyVar which has been declared as a Word. Of course, Bit type variables may also be used, but in most cases these are not of any practical use as they still take up a byte within the EEPROM.
A string of characters can also be transmitted, by enclosing them in quotes: -
I2Cout SDA_Pin, SCL_Pin, cControl, wAddress, ["Hello World", bMyVar, wMyVar]
Str modifier with I2Cout
The Str modifier is used for transmitting a string of bytes from a byte array variable. A string is a set of bytes sized values that are arranged or accessed in a certain order. The values 1, 2, 3 would be stored in a string with the value 1 first, followed by 2 then followed by the value 3. A byte array is a similar concept to a string; it contains data that is arranged in a certain order.
Each of the elements in an array is the same size. The string “1,2,3” would be stored in a byte array containing three bytes (elements). Below is an example that sends four bytes from an array: -
Dim bMyArray[10] as Byte = "ABCD" ' Create a 10 element byte array, pre-load it
'
' Send a 4-byte string
'
I2Cout SDA_Pin, SCL_Pin, 0b10100000, wAddress, [Str bMyArray\4]
Note that we use the optional \n argument of Str. If we didn't specify this, the program would try to keep sending characters until all 10 bytes of the array were transmitted. Since we do not wish all 10 bytes to be transmitted, we chose to tell it explicitly to only send the first 4 bytes.
Declares
There are two Declare directives for use with I2Cout and I2Cin. These are: -
Declare I2C_Slow_Bus On - Off or 1 – 0
Slows the bus speed when using an oscillator higher than 4MHz. The standard speed for the I2C bus is 100KHz. Some devices use a higher bus speed of 400KHz. If you use an 8MHz or higher oscillator, the bus speed may exceed the devices specs, which will result in intermittent transactions, or in some cases, no transactions at all. Therefore, use this Declare if you are not sure of the device's spec. The datasheet for the device used will inform you of its bus speed.
Declare I2C_Bus_SCL On - Off, 1 - 0 or True - False Eliminates the necessity for a pull-up resistor on the SCL line.
The I2C protocol dictates that a pull-up resistor is required on both the SCL and SDA lines, however, this is not always possible due to circuit restrictions etc, so once the I2C_Bus_SCL On Declare is issued at the top of the program, the resistor on the SCL line can be omitted from the circuit. The default for the compiler if the I2C_Bus_SCL Declare is not issued, is that a pull-up resistor is required.
Notes
When the I2Cout command is used, the appropriate SDA and SCL Port and Pin are automatically setup as inputs, and outputs. Because the I2C protocol calls for an open-collector interface, pull-up resistors are required on both the SDA and SCL lines. Values of 4.7KΩ to 10KΩ will suffice.
You may imagine that it's limiting having a fixed set of pins for the I2C interface, but you must remember that several different devices may be attached to a single bus, each having a unique slave address. Which means there is usually no need to use up more than two pins on the PICmicro™ in order to interface to many devices.