10.1 I2C Basics | Engscope
http://ww w.engscope.com/pic24-tutorial/10-1-i2c-basics/
Engscope An Engineer's Life Life
10.1 I2C I2C Basic s
10.1 I2C Basics I’ve gotten quite a few requests for the I2C bus section se ction of the PIC24 tut orial. orial. This is understandable since most digital digital electronics these days, both to reduce design cost and pin count, uses the I2C bus for inter-IC inter-IC (get it…? IIC = I2C, yeah engineers are smart like that…) communications. Just in case you have h ave no clue what I2C is, it is a communications communications bus invented inven ted by Philips Philips.. Although there are provisions in the I2C standard for multi-master environments, as well as 10 bit addressing, the most simple and commonly used configuration is the single master, 7 bit addressing. This configuration will be the only one addressed in this PIC24 tutorial.
Unlike the UART, which is an asynchronous asynchronous form of communication, the I2C is syn chronous. The master device sends both the data signal, signal, as well as the clock signal, with the exception during data reads. reads. The receiver syncs up with the clock signal, signal, and samples the data on the rising edge of the clock. Ultimately, this means that the transmitter transmitter and receiver do not need to know the clock rate because bec ause a clock signal is sent along with data. If you remember from the UART tutorial, tutorial , a predetermined clock speed must be known on both the transmitter transmitter and the receiver. This is great news for engineers, because you don’t have to do clock calculations (for the most part). There are upper limits to how fast you can send the clock c lock signal, but as long as you are below the u pper limits, limits, the bus will work fine. The I2C bus bu s requires two wires wires to be connected connec ted between the master and slaves, as well as a return (GND) wire. This usually means that at l east three wires needs to be connected from the master to the slave. However, there are several s everal advantages advantages over other forms of buses bu ses for communications communications between betwee n chips. Personally I prefer using the I2C for the ease of use and reliability of communications. The minimal clock calculations, most of the time as an afterthought is a huge advantage over the UART. In addition, you can also establish communications between more than just two chips. There are provisions in the I2C standard that allows for multiple devices, and layers of software and hardware to decode the transmission so that the packet sent by the master device device gets accepted by the intended slave device, and only by the inte nded slave device. This is NOT the case in the UART. In the UART communications model, there is a transmitter, and a receiver. If you have multiple receivers, well, I don’t know what would happen. The convention is to name the data line SDA,
10.1 I2C Basics | Engscope
http://www.engscope.com/pic24-tutorial/10-1-i2c-basics/
and the clock line SCL, and as such, I will use this convention in the tutorial. I will not explain every single section of the I2C standard, but I will provide diagrams for the most basic communications. Hardware Obviously, you’ll need to have two devices: a master I2C device and a slave I2C device. For most applications, the master device is obviously the PIC24. We want to use it as a programmable controller, to control one or several slave devices. Second, the I2C bu s is an open drain pull-down bus. What this means is that the bus needs to be pulled up to a nominal voltage (Vdd) when no devices are occupying the wires. Because it is an open drain bus, this nominal voltage is not strictly specified. Usually I use 3.3V, but applications such as the DDC in your monitor use 5V. A set of pull-up resistors need to be tied from the data and clock lines to Vdd. This assures that when the bus is idle, the voltages on data and clock are always at Vdd. In such a configuration, the devices on the I2C bus pull DOWN on data and clock. This way the devices don’t have to generate the nominal Vdd voltage if it wants to send a “1”, which might be somewhat electrically difficult because it is arbitrarily fixed (i.e. it is very hard for a 3.3V powered device to generate a 5V signal on a 5V I2C bus). A device only needs to pull the data line to a GND if it wants to send a “0”. Since GND is a reference point that all devices must have, it is technically possible to have a 5V device communicate with a 3.3V device on the same I2C bus! Generally speaking, the pull up resistor values must be big enough so that it doesn’t overpower the pull down ability of weakest pull down device (i.e., if I pull up the SDA line to Vdd with a 10 Ohm resistor, can my device pull the SDA line to GND hard enough to overcome that resister when it wants to send a “0”? The device must overcome the resistor in order to manipulate the SDA and SCL lines). However the pull up resistors must also be small enough such that they can pull enough cu rrent to return the SDA and SCL lines back to Vdd in a very short amount of time. Small enough such that the rise time of the pull-up is short compared to the clock period. In technical terms, if you like EE speak, it means that the impedance created by the pu ll up resistors on the transmission lines must be such that a clock signal can be sent through with crisp edges. If the resistor is too large, your rising edges will be damped. If you resistor is too small, your chips gets can’t dissipate enough current to pull down, and your falling edges get damped. In practical terms, stick with 2.5K Ohms. That should satisfy most situations. Whatever you do, only put ONE set of pull up resistors for each line. DO NOT put one set of pull up resistors for each device. This would put the resistors in parallel. And we all remember from circuits 101 what resistors in parallel do. Basic I2C Communications On the electrical level, the I2C communications functions as follows:
Image credit goes to Wikipedia. In a hypothetical situation, let’s say there is one master device and one slave
10.1 I2C Basics | Engscope
http://www.engscope.com/pic24-tutorial/10-1-i2c-basics/
device on an I2C bus line with pull-up resistors pulling to 3.3V. When the bus is idle, both the SCL and SDA lines are pulled high by the pull-up resistors. If the master wants to send a byte of data, it must first initiate a start bit (Label S), where the SDA line is pulled to a logical 0, while maintaining a logical 1 on the SCL line. Next it starts sending a clock signal. Because the SCL is pulled high at the start bit, the master must pull SCL down for half a clock cycle, before the first rising edge. Since the data is only sampled on the rising edge, at all other times, the master is allowed to transition the SDA between a logical 0 and a logical 1. On the first rising edge, the SDA line must have stabilized. The slave device samples the data (Label B1). This process is repeated until the 8th rising edge, or the 8th bit. Right after the 8th rising edge, the master device releases control of the SDA line. It has finished sending its data, and is now awaiting a response from the slave device. The slave device has one clock cycle to transition the SDA clock to a logical 0 to acknowledge the reception of the data byte. This is referred to the /ACK bit. The slash in front of the “ACK” indicates that it is an active low signal. The master then sends a 9th rising edge on the SCL line, and samples the SDA line. If it is a logical 0, then the slave device has successfully received the byte. If it is a logical 1, then something wrong has occurred (under most circumstances, the /ACK is not required during the last byte of a read command). Lastly the SCL is held high, and subsequently the SDA line is pulled high to signal a stop bit (P). In the subsequent explanation of I2C packets, I will refer to the ACK bit with these notations: /ACK refers to an acknowledge bit. Since the signal is an active low signal, when a device wants to communicate an acknowledgment, it must send a logical 0 (i.e., 0 V). However, when the device wants to indicate that there is something wrong, or that it did not correctly receive a piece of data, it sends a /NACK as an acknowledgement, represented by a logical 1 (i.e. 3.3 V or 5 V). Basic I2C Packet
There are two main types of operations the I2C bus. These are the random write command, and the random read command. In general, a packet sent by the master for a write command looks something like this:
This picture is taken from the datasheet of the AT24C02B EEPROM chip from Amtel. Three bytes are sent from the master device, and received by the slave if he is present on the bus. The first byte is the slave address and the read/write indicator. The first 7 bits is the slave device address. This value is always indicated in the data sheet of the slave address. In order for the I2C bus to allow for multiple slaves, the master must indicate which device the message is intended. The slave address, which begins every I2C transaction is the address that corresponds to a devices on the bus. Obviously there cannot be multiple slaves with the same address. This would create a collision on the I2C bus. The 8th bit of the first byte is the read/write indicator. If the bit is a 0, the master wants to write a byte, if it is a 1, the master intends to read. Next, on the 9th bit of the first byte, the master waits for an
10.1 I2C Basics | Engscope
http://www.engscope.com/pic24-tutorial/10-1-i2c-basics/
acknowledge bit from the slave. If the address sent by the master corresponds to the slave address of a slave device, the slave device MUST acknowledge on the 9th bit. If the /ACK is a 1, a non-acknowledge, then the master thinks there is no slave with the sent address. It terminates the packet with a STOP bit. However, if a slave does send back a /ACK with logical 0, then the master device begins sending the second byte. The second byte is usually the slave’s internal address (referred to as the “WORD ADDRESS” in the above drawing). For example, on the AT24C02B EEPROM, there are 256 memory locations of 8 bits each. Whenever I want to write to the device, I must specify which one of the 256 memory locations I wish to write to. This is what the second byte of the packet is usually used for. On the 9th byte of the second byte the slave device must acknowledge that the specified address exists as one of the slave device’s internal addresses. Lastly, the master device sends the data it intends to write. This is usually referred to as the data byte. Finally the slave device acknowledges the received byte, and the communications is terminated by a stop bit. The second most commonly used command is the random read. It is called a random read because this is the ability to read any address at will, as opposed to a sequential read, everything must be read, until the correct piece of data is located. Think of it as a DVD, where you can access anything instantly, versus a VCR, where you need to wined the tape to the correct spot before watching a particular scene.
A random read must be done in the following manner. The master device must first act like it intends to do a random write by sending the slave device address with a write command bit (recall that the slave address is 7 bits long, NOT 8 bits long, the last bit of the first byte is reserved for the read/write command indicator). It then sends the internal address just as if it intends to do a device write. The slave address must send a /ACK on 9 th bit of both the bytes to indicate to the master device of its presence. However, at the end of the 2nd byte, the master device resents a start bit. For the 3rd byte, the master device resends the slave address, but with the read command bit for the 8th bit of the 3rd byte. At this point, after the slave address sends a /ACK back to the master, the roles are reversed between the slave and master. On the next byte, the slave device takes over the SDA line and waits for /ACKs from the master device. After the slave device takes over the SDA line, it starts transmitting the byte located at the internal address. The slave device starts manipulating the SDA line according to the clock. On each of the rising edge of the SCL line, sent by th e master device, the slave device must be ready with the bit it intends the master device to read. After the 8th bit is sent, the master device must indicate a /NACK, the inverse of the inverse-ACK (logical 1) to tell the slave device to stop taking control of the SDA line. It ends the transmission with a stop bit. On the Subject of Writing Be careful when writing to EEPROMS, or devices with permanent memory. It usually takes about 10 ms or so before the device successfully finishes writing the data to memory. The AT24C02B for example, requires you to wait a full 5 ms before allowing a subsequent write operation:
10.1 I2C Basics | Engscope
http://www.engscope.com/pic24-tutorial/10-1-i2c-basics/
You must take into account these write cycle times when using a microcontroller. This is why it is important to take note of the /ACK signals sent by the slave device. When a slave device is NOT READY for a subsequent write operation, it will reply with a /NACK, logical 1, on every byte sent by the master. Advanced I2C packets The two advanced packet formats are the sequential write and the sequential read. As you can see from the two basic packet formats, there are a lot of overhead data required to write one or two bytes to a device. What I mean by this is that, if I want to write 8 bytes to an EEPROM device with my PIC24, I will need to actually send 24 bytes of data using random write commands. This is because 8 bytes of the data is used to send the slave address, 8 bytes of the data is used to send the internal address, and finally 8 bytes of data is the actual data that I wish to write. In addition, EEPROMs have long write cycles of several milliseconds. To get around these limitations, most EEPROM have the ability to write 8 or so bytes in one “sequential write”. In addition, most EEPROMs allow you to read all its data in one sequential read. A sequential write is very similar to a random write. The following diagram from the AT24C02B datasheet does a great job of illustrating the point.
The master device sends the exact same packet as a single write. However, after the /ACK bit of the 3rd byte is sent, it DOES NOT send a stop bit. It continues to send data, expecting a /ACK from the slave after each byte. After each transmitted byte, the internal address of the slave device is automatically incremented, and therefore the master device does not have to manually select the next internal address. Usually sequential writes are limited to about 8 bytes before the internal buffer of the slave device is full, in which case it will stop sending /ACKs, indicating that something is wrong. After the last byte that the master wishes to send, and waiting for the corresponding /ACK signal from the slave device, the master device sends a stop bit to terminate the transmission. A sequential read is also very similar to a random read.
The master device sends the exact same packet as a single read. But whereas in a random read the master sends a /NACK to stop the transmission, this time it send a /ACK to indicate to the slave device that it wants more data. The internal address is automatically incremented and the next byte of data is sent by the slave. The slave will keep on sending data until it receives a /NACK, at which point the master device terminates the
10.1 I2C Basics | Engscope
http://www.engscope.com/pic24-tutorial/10-1-i2c-basics/
transmission with a stop bit. There are usually no limitations on how many bytes the slave is limited to sending. The slave device just keeps on sending data on the SDA line unit it receives a /NACK from the master. In the next section of the tutorial, I’ll show you the basic functions of the I2C module on the PIC24. Table of Contents
10 Responses to
10.1 I2C Basic s
ED says: January 7, 2010 at 11:10 am
I cant find your RSS feed i would like to subscribe to your content.
jliu83 says: January 11, 2010 at 8:25 am
http://www.engscope.com/feed/ I think that’s the standard wordpress address… Works for me in firefox, does seem to have some problems with chrome. Didn’t bother checking it with IE. -J
Danny Cranmer says: March 5, 2010 at 10:07 am
Hi, I know this isnt I2C but i thought I would let you know anyway. Have been using the SPI modules on PIC24FJ128GA006 just the SDO and SCK pins to talk to a DAC. I have come to the conclusion that the flag “SPITBF” does not work. As follows Chip_Select = 0; SPIXBUF = data; while ( !SPIXSTATbits.SPITBF ); OR while ( SPIXSTATbits.SPITBF ); Chip_Select = 1; Both of these variations have no effect and viewing on an oscilloscope shows the CS going low then high before the SCK pin does anything (note the SPI module still operates just a dodgy Flag ) I have overcome this using a small time delay Chip_Select = 0; SPIXBUF = data;
10.1 I2C Basics | Engscope
http://www.engscope.com/pic24-tutorial/10-1-i2c-basics/
Delay_mS(3); Chip_Select = 1; Obviously the time de lay relates to the pre scalers and Clock Frequency I am using and Where i have used SPIXBUF the X represents the module number you are u sing. I’m not sure if this problem is just on my particular chip or I have some buggy header files but hopefully It can stop someone’s brain hurting Let me know if anybody has had the same problem Danny Cranmer –
[email protected] These tutorials are the best and have helped me so much, thankyou very much !
jliu83 says: March 5, 2010 at 9:09 pm
Have you checked the most recent errata? Maybe there’s some hints on it. Did you eventually figure out the CN0/ CN1 problem? -J
Danny Cranmer says: March 6, 2010 at 9:05 am
No still havn’t got round to them pins yet as have been busy with other parts but I will let you know . Eventually ….
Dave Wall says: May 10, 2012 at 8:45 am
In the 15th paragraph (just above “on the subject of writing”) you say: “The master device is still in control of the SDA line, but the slave device takes over the SDA line and waits for /ACKs from the master device.” I think it’s supposed to be that the slave takes control of the data line. Thanks for a great website – I always use and recommend it!
jliu83 says: May 17, 2012 at 4:03 am
@Dave Wall. I’ve changed the wording to make it more clear. Thank you for pointing that out. -J
Kruthik says: July 23, 2012 at 10:15 pm
10.1 I2C Basics | Engscope
http://www.engscope.com/pic24-tutorial/10-1-i2c-basics/
Hi, I wanted a detailed information about , 1. The steps i should follow in SLAVE WRITE operation? and SLAVE READ operation? 2.What is a CURRENT ADDRESS bit?When should i use this bits while programming. 3.What is a MEMORY ADDRESS SELECT BIT (single/two byte address).When can i use this?
jliu83 says: July 27, 2012 at 7:34 pm
@Kruthik. Unfortunately I don’t have a slave I2C driver at the moment. Your on your own for this one, at least for now. Perhaps in the future I might write a tutorial on it. -J
Anderson Ve nturini says: January 21, 2013 at 11:52 am
That’s a great article! It was very useful. Thank you.
Engscope Proudly powered by WordPress.