Archive for the I2C Category

The Big I2C SEE Table

Not all I2C Serial EEPROMs are created equal. In fact there is a lot of variety out there as the memory size increases the addressing schemes change, the number and use of the device select pins change as well. The size increase reflects more or less closely the passing of time (years) and with it the evolution of the market of serial EEPROMs within and beyond the confines of the original specifications of the bus.

To be able to adapt the code developed in the previous postings, you will need to pay close attention to the details. To simplify the task, I have tried to collect in one big table the key elements that differentiate each device.
Read the rest of this entry »

I2C Interface to Serial EEPROMS (continued)

In a few previous postings we started exploring the I2C interface and in particular its use to access the most common and inexpensive type of Serial EEPROMs (24xxx). After the long preamble, it is about time to start talking about code. Today we will write a set of functions to read and write 16-bit integers to and from a Serial EEPROM device (a 24LC16 to be precise) similarly to what we have done in chapter 7 with the SPI interface to the 25lc256 device. Read the rest of this entry »

I2C Interface to Serial EEPROMs (continued)

In two previous postings (Chapter 7 1/2, I2C Interface) we have started looking into the I2C interface, some of its applications and the very basics of the communication protocol.

It’s time to start sending and receiving data bytes and learn how to form commands to communicate with what is perhaps the most common type of device requiring an I2C interface: the Serial EEPROM (SEE for short). Read the rest of this entry »

I2C Interface (continued)

The I2C bus is based on a very simple protocol, a small set of rules that dictate how the two lines SDA and SCL are supposed to operate to allow the transfer of data.

With the premise that, at idle, both lines are high (pull up):
Rule 1) During the transfer of a bit, the SDA line can change status only when the SCL line is low.
Rule 2) When the SCL line is high, the SDA line status indicates the value of a bit.

Two exceptions to the above rules create special conditions that are used to delimit the beginning and end of each “transaction” between two devices on the bus.

A START condition is indicated when (in violation of rule 1) the SDA line changes from high to low while SCL is high.

A STOP condition is indicated when (again in violation of rule 1) the SDA line changes from low to high while SCL is high.

The figure below extracted from a typical device datasheet is worth a million words.

i2c sequence Read the rest of this entry »

Chapter 7-1/2 The I2C Interface

Over the last year I have received a couple of emails from readers inquiring about the absence of examples on the use of the I2C(tm) synchronous serial ports of the PIC24. I imagine many more of you would have liked to ask the same or at least might have wondered why the omission.

I have to make the premise that it was never my intention to write the “definitive guide” to the PIC24… there are already too many books that start with that claim (often in the title) and fall (way) short or end up basically rephrasing the entire device datasheet. So I set my goal to provide meaningful/entertaining examples on as many features of the PIC24 architecture as I could fit in 300 pages (you will notice that I ended up with almost 400 pages, and that was after the publisher got mad at me and had to reduce the font size twice…)

I also set my sight on one specific hardware platform: the Explorer16 board, trying to exercise all of the features available and then expand using the small prototyping area or the PICTail(tm) connector.

It just happened so that the I2C port was left behind, although it is briefly introduced in chapter 7 and compared to the other main synchronous option: the SPI port.

This omission is in no way an indication of a lesser importance of the subject to the embedded control programmer, on the contrary, if anything the popularity of the I2C interface is growing in the recent years. This is reflected in the continuous introduction of new devices that are based on or support it, but also new advanced application specific protocols that use I2C as their physical level / transport layer.

Examples of devices recently introduced by Microchip and based on the I2C interface are:

Examples of application specific protocols based on the I2C interface are:

  • SMBus, the System Management Bus, used in personal computers (and servers) for low speed system management applications
  • IPMI, the Intelligent Platform Management Interface, used to monitor the system health and manage (mostly servers) systems remotely.
  • PMBus, the Power Management Bus, used by advanced digitally controlled power supply units to monitor, configure and control power.

The PIC24 datasheet and reference manual provide ample documentation on the I2C peripheral features and options available but I will try and provide a little more perspective and practical advice in this and the next few postings.

The hardware requirements of the generic interface are very simple:

  • A clock line (SCL) is controlled by the Master(s)
  • A data line (SDA) is controlled alternatively by Master and Slave devices
  • Two resistors (typically 2.2k ohm each, but the value will vary with selected speed and voltages) are used to pull up the two open-drain output buffers

That’s all!
To begin with, we should ask ourselves if we truly need to use a peripheral module or if we could do without (like most 8-bit PIC microcontrollers used to do)!? In fact the I2C specifications indicate a range of relatively low bus speeds. The original documentation (published by Philips decades ago) indicated 100kbit/s maximum and even if the more recent updates brought the speed up to 400kbit/s first and more recently to 1Mbit/s this is clearly within the realm of software (bit-banged I/O) solutions.

When we consider the most common application, that sees the PIC microcontroller as the only master addressing a handful of devices (typically 24xx serial EEPROMs) this is definitely an option. The advantage of a software approach is in the freedom it provides to choose any I/O pin we want, and the task is further simplified on the PIC24 since all I/Os can easily be configured for open-drain operation (see ODCx registers).

(Trick: In the single master case, the SCL line control never changes and therefore a common hardware and software simplification includes reducing this line to a standard CMOS output.)

In the good old times, on 8-bit PIC microcontrollers and using only assembly programming, I have seen implementations of I2C (single master) interfaces to serial EEPROMs in as little as 40 instructions (ever heard of the famous “Frank code”!?).

Another common trick used in power constrained applications is that of powering the entire peripheral device off one of the I/Os of the PIC microcontroller. In particular referring again to the common Serial EEPROMs (say a 2kbytes capable 24LC16), you will verify that their power consumption is limited to 3mA max. (even when operating at 400kHz) a value that is well within the capabilities of any PIC24 I/O port.

On Microchip web site you will find several examples of “software” I2C libraries (AN1100 for example) , don’t ignore them just because we have the luxury of having two hardware interfaces on the PIC24Fj128GA series … check all your options first!

(to be continued)

|