Peter Fleury's I2C Library HOWTO

Atmel AVRPeter Fleury has an excellent collection of AVR software for some very common tasks. The next two posts contain knowledge gained as I learned how to use these libraries, including all the "gotchas" and complete descriptions of the code and circuitry. Hopefully this information will help get you started fast.

The first library we'll be looking at today is the i2cmaster TWI library. It is extremely useful for connecting to external TWI/I2C hardware quickly and painlessly.

This library abstracts I2C functionality into a handy easy to use library. The great thing about i2cmaster is that it can supply I2C for AVRs without native hardware TWI support.

Getting Started

Extract i2cmaster.zip. In here, you'll find the core library and a test program.

  • i2cmaster.S
    The assembly implementation of i2c. If your AVR does not have hardware TWI capability, include this in your makefile ASRC variable. This assembly library could also be potentially used to give an AVR with TWI hardware a second I2C bus. Configure the I2C ports/pins at the top of this file.
  • twimaster.c
    C language wrapper for AVRs with native hardware TWI. This version of i2cmaster has the same interface as i2cmaster.S, so using this library allows you to support more AVR models without extra work. Include this file in your makefile SRC variable for AVRs with TWI.
  • test_i2cmaster.c
    Shows library usage but not required.
  • i2cmaster.h
    API and detailed instructions.

Make sure you have 4.7k to 10k pull-up resistors on the SCL and SDA lines of your I2C bus. You can try the internal AVR pull-up resistors, but external ones seem more stable. The resistance of the internal ones vary wildly.

Test Circuit - AVR with TWI interface
Test Circuit - AVR with TWI interface
Test Circuit - AVR without TWI interface
Test Circuit - AVR without TWI interface

As you can see above, the difference between an AVR with TWI and one without when using i2cmaster is very subtle.

On the ATMega48/88/168 version, the device has hardware TWI support and so SCL and SDA lines are connected to the appropriate pins on the AVR side - the pins are not configurable here. On ATMega48/88/168, SCL is PC5 and SDA is PC4.

ATTiny24/44/84 has no built-in TWI support, so in this case we need to use the software version. The placement of SCL and SDA is arbitrary. In the example above, PA0 and PA1 were chosen, but any two pins would suffice. The ports and pins you choose are configured at the top of i2cmaster.S.

So be sure to know the capabilities of your device and use the hardware mode if your AVR has one. Check your local datasheet for details.

Making An I2C Bus

I2C Bus
I2C Bus

Each I2C capable slave device has a unique address. Part of this address is internal to the device. The examples above use 0xA0, but it will be something different for your device. The device datasheet should specify this base address.

Most I2C devices supply part of the address exposed as pins that you can configure. In the example above and on many actual I2C devices, these are called A0, A1 and A2. Connect these pins to the power supply or ground to tell the device if A0, A1, A2 should be one or zero, respectively.

The actual format is:

[internal address, 4 bits]
[exposed address, 3 bits]
[read/write, 1 bit]

So as stated above, the top four bits are set by the manufacturer. The next three are specified by you on A2, A1, and A0, respectively. The final bit specifies read or write mode when sending addresses to the device.

The formula for finding the address of your device is:

[internal address] + ([external address] << 1)

The external address is shifted left by one bit to make room for the read/write bit. i2cmaster uses simple addition to specify read or write mode every time you specify your address. See the example below which addresses device 0xA2 in read and write mode.

Since 3 bits are exposed, up to 8 devices with the same internal address can be used with this scheme.

Many other devices with differing internal manufacturer addresses can share the same bus. As long as the device works out to have a unique I2C address, it can share this same two wire bus.

Setup

#include "i2cmaster.h"

Write Sequence

// Start up comms.
i2c_init();

// We're going to write to the device at I2C
// address 0xA2. i2c_start_wait() will hang forever
// if it cannot make a connection to the device.
i2c_start_wait(0xA2+I2C_WRITE);

// Register address.
i2c_write(0x05);

// Data.
i2c_write(0x75);

// Done communicating for now.
i2c_stop();

Read Sequence

// Received byte.
unsigned char ret;

// Start up comms.
i2c_init();

// Read from the device at I2C address 0xA2.
i2c_start_wait(0xA2+I2C_WRITE);

// Register address.
i2c_write(0x05);

// Repeat start condition this time with I2C_READ
i2c_rep_start(0xA2+I2C_READ);

// readNak means we're only reading this one byte
// then done. Use i2c_readAck() if you want to
// read more bytes, and i2c_readNak() on the last.
ret = i2c_readNak();

// Done communicating for now.
i2c_stop();

 
 
 
 

Вопрос не в

Вопрос не в тему: Это правда, что Аватар придумал наш писатель?

 
 

Post new comment

The content of this field is kept private and will not be shown publicly.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Allowed HTML tags: <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd>
  • Lines and paragraphs break automatically.

More information about formatting options