CircuitGizmos

Electronic Products for Creative Minds

  • Home
  • Gizmo Store/Products
  • Documentation/Datasheets
  • Projects/Libraries
  • GizmoBlog
  • Services/Contact
    • Design
    • Contact Gizmo!
  • Your Gizmo Cart
    • Your Account
You are here: Home / GizmoBlog / MMBasic Language / Input and Output / Inter Integrated Circuit (I2C) bus

Inter Integrated Circuit (I2C) bus

The Inter Integrated Circuit (I2C) bus was developed by Philips (now NXP) for the transfer of data between integrated circuits.

7 and 8 Bit Addressing

The standard addresses used in these commands are 7-bit addresses (without the read/write bit). MMBasic will add the read/write bit and manipulate it accordingly during transfers.

Some vendors provide 8-bit addresses which include the read/write bit. You can determine if this is the case because they will provide one address for writing to the slave device and another for reading from the slave. In these situations you should only use the top seven bits of the address.

For example: If the read address is 9B (hex) and the write address is 9A (hex) then using only the top seven bits will give you an address of 4D (hex). A simple way of finding the address is to take the 8 bit write address and divide it by 2.

Another indicator that a vendor is using 8-bit addresses instead of 7-bit addresses is to check the address range. All 7-bit addresses should be in the range of 08 to 77 (hex). If your slave address is greater than this range then probably your vendor has specified an 8-bit address.

10 Bit Addressing

10-bit addressing was designed to be compatible with 7-bit addresses, allowing developers to mix the two types of devices on a single bus. Devices that use 10-bit addresses will be clearly identified as such in their data sheets.

In 10-bit addressing the slave address is sent in two bytes with the first byte beginning with a special bit pattern to indicate that a 10 bit address is being used. This process is automatically managed by MMBasic when the ‘option’ argument is set for 10-bit addressing. 10-bit addresses can be in the range of 0 to 3FF (hex).

Master/Slave Modes

The master and slave modes can be enabled simultaneously; however, once a master command is in progress, the slave function will be “idle” until the master releases the bus. Similarly, if a slave command is in progress, the master commands will be unavailable until the slave transaction completes.

In master mode, the I2C send and receive commands will not return until the command completes or a timeout occurs (if the timeout option has been specified).

The slave mode uses an MMBasic interrupt to signal a change in status and in this routine the program should write/read the data as specified by the I2C master. This operates the same as a general interrupt on an external I/O pin. Return from the interrupt is via the IRETURN statement except where a user defined subroutine is used (in that case END SUB or EXIT SUB is used).

I/O Pins

On the Maximite pin 12 becomes the I2C data line (SDA) and pin 13 the clock (SCL). For the DuinoMite see the “DuinoMite MMBasic ReadMe.pdf” document for details.

Both of these pins should have external pullup resistors installed (typical values are 10KΩ for 100KHz or 2KΩ for 400 kHz). When the I2C CLOSE command is used the I/O pins are reset to a “not configured” state. Then can then be configured as per normal using SETPIN.

When running the I2C bus at above 150 kHz the cabling between the devices becomes important. Ideally the cables should be as short as possible (to reduce capacitance) and also the data and clock lines should not run next to each other but have a ground wire between them (to reduce crosstalk).

If the data line is not stable when the clock is high, or the clock line is jittery, the I2C peripherals can get “confused” and end up locking the bus (normally by holding the clock line low). If you do not need the higher speeds then operating at 100 kHz is the safest choice.

Example

I2C is ideally suited for communications between integrated circuits. As an example, there might be an occasion when a Maximite does not have enough serial ports, I/O pins, or whatever for a particular application. In that case a Micromite‡ or Maximite could be used as a slave to provide the extra facilities.

This example converts a Micromite into a general purpose I/O expansion chip with 17 I/O pins that can be dynamically configured (by the master) as analog inputs or digital input/outputs. The routines on the master are  simple to use (SSETPIN to configure the slave I/O and SPIN() to control it) and the program running on the master need not know that the physical I/O pins reside on another chip. All communications are done via I2C.

The following illustration shows the connections required:

Program Running On the Slave:

The slave must first set up its I2C interface to respond to requests from the master. With that done it can then drop into an infinite loop while the job of responding to the master is handled by the I2C interrupts.

In the program below the slave will listen on I2C address 26 (hex) for a three byte command from the master.

The format of this message is:

  • Byte 1 is the command type. It can have one of three values; 1 means configure the pin, 2 means set the output of the pin and 3 means read the input of the pin.
  • Byte 2 is the pin number to operate on.
  • Byte 3 is the configuration number (if the command byte is 1), the output of the pin (if the command byte is 2) or a dummy number (if the command byte is 3).

The configuration number used when configuring a slave’s I/O pin is the same as used in earlier versions of Maximite MMBasic (with the SETPIN command) and can be any one of:
0 Not configured or inactive
1 Analog input
2 Digital input
3 Frequency input
4 Period input
5 Counting input
8 Digital output
9 Open collector digital output. In this mode SPIN() will also return the value on the output pin .

Following a command from the master that requests an input, the master must then issue a second I2C command to read 12 bytes. The slave will respond by sending the value as a 12 character string.

This program can fall over if the master issues an incorrect command. For example, by trying to read from a pin that is not an input. If that occurs, an error will be generated and MMBasic will exit to the command prompt.

Rather than trap all the possible errors that the master can make, this program uses the watchdog timer. If an error does occur the watchdog timer will simply reboot the Micromite and the program will restart (because AUTORUN is on) and wait for the next message from the master. The master can tell that something was wrong because it would get a timeout.

This is the complete program running on the slave:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
OPTION AUTORUN ON
DIM msg(2)                                 ' array used to hold the message
 
I2C SLAVE OPEN &H26, 0, 0, WriteD, ReadD   ' slave's address is 26 (hex)
DO                                         ' the program loops forever
  WATCHDOG 1000                            ' this will recover from errors
LOOP
 
ReadD:                                     ' received a message
  I2C SLAVE READ 3, msg(0), recvd          ' get the message into the array
  IF msg(0) = 1 THEN                       ' command = 1
    SETPIN msg(1), msg(2)                  ' configure the I/O pin
  ELSEIF msg(0) = 2 THEN                   ' command = 2
    PIN(msg(1)) = msg(2)                   ' set the I/O pin's output
  ELSE                                     ' the command must be 3
    s$ = str$(pin(msg(1))) + Space$(12)    ' get the input on the I/O pin
  ENDIF
 
IRETURN                                    ' return from the interrupt
 
WriteD:                                    ' request from the master
  I2C SLAVE WRITE 12, s$                   ' send the last measurement
 
IRETURN                                    ' return from the interrupt


Interface Routines On the Master:

These routines run on the Maximite. They assume that the slave Micromite is listening on I2C address 26 (hex).

If necessary these can be modified to access multiple Micromites (with different addresses), all acting as expansion chips and providing an almost unlimited expansion capability.

There are two subroutines and one function that together are used to control the slave:

SSETPIN pin, cfg This subroutine will setup an I/O pin on the slave. It operates the same as the MMBasic SETPIN command and the possible values for ‘cfg’ are listed above.

SPIN pin, output This subroutine will set the output of the slave’s pin to ‘output’ (ie, high or low).

nn = SPIN(pin) This function will return the value of the input on the slave’s I/O pin.

For example, to display the voltage on pin 3 of the slave you would use:


1
2
SSETPIN 3, 1
PRINT SPIN(3)


As another example, to flash a LED connected to pin 15 of the slave you would use:


1
2
3
4
SSETPIN 15, 8
SPIN 15, 1
PAUSE 300
SPIN 15, 0


These are the three routines:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
' configure an I/O pin on the slave
SUB SSETPIN pinnbr, cfg
  I2C OPEN 100, 1000
  I2C WRITE &H26, 0, 3, 1, pinnbr, cfg
  IF MM.I2C THEN ERROR "Slave did not respond"
  I2C CLOSE
END SUB
 
' set the output of an I/O pin on the slave
SUB SPIN pinnbr, dat
  I2C OPEN 100, 1000
  I2C WRITE &H26, 0, 3, 2, pinnbr, dat
  IF MM.I2C THEN ERROR "Slave did not respond"
  I2C CLOSE
END SUB
 
' get the input of an I/O pin on the slave
FUNCTION SPIN(pinnbr)
  LOCAL t$
  I2C OPEN 100, 1000
  I2C WRITE &H26, 0, 3, 3, pinnbr, 0
  I2C READ &H26, 0, 12, t$
  IF MM.I2C THEN ERROR "Slave did not respond"
  I2C CLOSE
  SPin = VAL(t$)
END FUNCTION


Information from Geoff Graham http://geoffg.net

 

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

A Ton of Documentation

Open all | Close all

Projects made by Gizmo, Friends, and Members

open all | close all

Recent GizmoBlog Musings

  • Altair 8800 using a ColorMax!
  • Re-energizing the ColorMax, Pt. 3

Visit us!

  • Facebook

Electronic Products for Creative Minds

CircuitGizmos is your source for electronic products that help you create your embedded projects. Here at CircuitGizmos.com you will find a friendly store filled with creative products and all of the documentation that you need to use these gizmos.

We create devices that we believe make electronics fun, but we also know that our products are used for professional designs. For decades we have designed products for commercial, military, and medical industries. Our gizmos here are great for engineers and hobbyists alike.

Copyright © 2008+ CircuitGizmos, L.L.C. All rights reserved

Image already added

Recently Viewed Products

Copyright © 2021 · Generate Pro Theme on Genesis Framework · WordPress · Log in