Positron Compiler Documentation

Busout

Source: Positron16 Compiler User Manual, PDF page 143

Syntax

Busout Control, { Address }, [ Variable {, Variable…} ]

or

Busout Variable

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). Or alternatively, if only one operator is included after the Busout command, a single value will be transmitted, along with an Ack reception.

Parameters

Variable is a user defined variable or constant. Control may be a constant value or a Byte sized variable expression. Address may be a constant, variable, or expression.

The Busout command is a software implementation (bit-bashed) and operates as an I2C master without using the device's MSSP module, 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 %10100000 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 Busout command, regardless of its initial value.

Example

' Send a byte to the I2C bus.
  Device = 24FJ64GA002
                                        ' Select the device to compile for
  Declare Xtal = 8
  Declare SCL_Pin = PORTB.3
                                        ' Select the pin for I2C SCL
  Declare SDA_Pin = PORTB.4
                                        ' Select the pin for I2C SDA
  Dim MyByte as Byte
                                        ' We'll only read 8-bits
  Dim Address as Word
                                        ' 16-bit address required
  Symbol cControl = %10100000
                                        ' Target an EEPROM
  Address = 20
                                        ' Write to address 20
  MyByte = 200
                                        ' The value place into address 20
  Busout cControl, Address,[MyByte]
                                        ' Send the byte to the 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, Word or Dword). 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 MyWord as Word
                           ' Create a Word size variable
Busout Control, Address, [MyWord]

Will send a 16-bit value to the bus. While: -

Dim MyByte as Byte
                           ' Create a Byte size variable
Busout cControl, Address, [MyByte]

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 MyByte as Byte
Dim MyWord as Word
Busout cControl, Address, [MyByte, MyWord]

Will send two values to the bus, the first being an 8-bit value dictated by the size of variable MyByte which has been declared as a byte. And a 16-bit value, this time dictated by the size of the variable MyWord 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: -

Busout cControl, Address, ["Hello World", MyByte, MyWord]

Using the second variation of the Busout command, necessitates using the low level commands i.e. Bstart, Brestart, BusAck, or Bstop.

Using the Busout command with only one value after it, sends a byte of data to the I2C bus, and returns holding the Acknowledge reception. This acknowledge indicates whether the data has been received by the slave device.

The Ack reception is returned in the microcontroller's Carry flag, which is SR.0, and also System variable PP4.0. A value of zero indicates that the data was received correctly, while a one indicates that the data was not received, or that the slave device has sent a NAck return. You must read and understand the datasheet for the device being interfacing to, before the Ack return can be used successfully. An code snippet is shown below: -

' Transmit a byte to a 24LC32 serial EEPROM
  Device = 24FJ64GA002
                                     ' Select the device to compile for
  Declare Xtal = 8
  Declare SCL_Pin = PORTB.3
                                     ' Select the pin for I2C SCL
  Declare SDA_Pin = PORTB.4
                                     ' Select the pin for I2C SDA
  Bstart
                              ' Send a Start condition
  Busout %10100000
                              ' Target an EEPROM, and send a Write command
  Busout 0
                              ' Send the High Byte of the address
  Busout 0
                              ' Send the Low Byte of the address
  Busout "A"
                              ' Send the value 65 to the bus
  If SRbits_C = 1 Then GoTo Not_Received ' Has Ack been received OK?
  Bstop
                              ' Send a Stop condition
  DelayMs 5
                              ' Wait for the data to be entered into EEPROM

Str modifier with Busout.

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: -

  Device = 24FJ64GA002
                                     ' Select the device to compile for
  Declare Xtal = 16
  Declare SCL_Pin = PORTB.3
                                     ' Select the pin for I2C SCL
  Declare SDA_Pin = PORTB.4
                                     ' Select the pin for I2C SDA
  Dim MyArray[10] as Byte
                                   ' Create a 10 element byte array.
  MyArray [0] = "A"
                                     ' Load the first 4 bytes of the array
  MyArray [1] = "B"
                                     ' With the data to send
  MyArray [2] = "C"
  MyArray [3] = "D"
  Busout %10100000, Address, [Str MyArray\4] ' Send 4-byte string.

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.

The above example may also be written as: -

  Device = 24FJ64GA002
                                   ' Select the device to compile for
  Declare Xtal = 16
  Declare SCL_Pin = PORTB.3
                                   ' Select the pin for I2C SCL
  Declare SDA_Pin = PORTB.4
                                   ' Select the pin for I2C SDA
  Dim MyArray [10] as Byte
                                   ' Create a 10 element byte array.
  Str MyArray = "ABCD"
                                   ' Load the first 4 bytes of the array
  Bstart
                                   ' Send a Start condition
  Busout %10100000
                                   ' Target an EEPROM, and send a Write command
  Busout 0
                                   ' Send the HighByte of the address
  Busout 0
                                   ' Send the LowByte of the address
  Busout Str MyArray\4
                                   ' Send 4-byte string.
  Bstop
                                   ' Send a Stop condition

The above example, has exactly the same function as the previous one. The only differences are that the string is now constructed using the Str as a command instead of a modifier, and the low-level Hbus commands have been used.

Declares

There are three Declare directives for use with Busout. These are: -

Declare SDA_Pin Port.Pin Declares the port and pin used for the data line (SDA). This may be any valid port on the microcontroller.

Declare SCL_Pin Port.Pin Declares the port and pin used for the clock line (SCL). This may be any valid port on the microcontroller. R2 4.7k R1 4.7k VCC WP

SDA SCL To I/O pin To I/O pin A0

24LC32

A1 A2 VSS

0v These declares, as is the case with all the Declares, may only be issued once in any single program, as they setup the I2C library code at design time.

Declare 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.

Notes.

When the Busout 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 1KΩ to 4.7KΩ 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 device, in order to interface to many devices.

A typical use for the I2C commands is for interfacing with serial eeproms. Shown below is the connections to the I2C bus of a 24LC32 serial EEPROM.

See also : BusAck, Bstart, Brestart, Bstop, Busin, HbStart, HbRestart,

HbusAck, Hbusin, Hbusout.