I2C PROTOCOL

INTRODUCTION-

We have studied about SPI protocol in the previous section. There are four pins of microcontroller used in data transmission in case of SPI protocol. That means if we transfer data using SPI protocol then, fours pins of microcontroller are engaged always. The power consumption is also high in case of SPI protocol. But Philips came up with better protocol than SPI i.e. I2C . In I2C protocol, only two pins utilize  during data transfer. This protocol is also referred as I2C or I square C.

I2C BUS-

The speed of communication in I2C is low so, I2C protocol is ideal for attaching low speed peripherals to motherboards or embedded system or anywhere where reliable communication over a short distance is required. I2C protocol is mostly popular as provide connection-oriented communication with acknowledgement. The devices which are connected with a microcontroller use only 2 pins for data transfer instead of 8 or more pins as used in traditional buses. They are SCL (serial clock), which synchronize the data transfer between two chips, and SDA (Serial Data). So there is reduction in communication pins reduces package size and power consumption drastically, making them ideal for many applications where space is major concern. These two pins SCL and SDA makes, I2C a 2-wire interface. I2C is also referred to as Two-Wire serial Interface (TWI).

 

I2C ELECTRICAL LINE CHARACTERISTICS-

I2C devices use only 2-bidirectional open drain pins for data communication. In I2C bus two pull up resistors of 4.7kilo-ohm each is required. This implements a wired-AND, which is needed to implement I2C protocol. In I2C bus, there are many devices connected to a microcontroller. But only one device can communicate with microcontroller at a time. When communication between one device and microcontroller occurs then, other devices cannot communicate with microcontroller. So when microcontroller is busy in communicating with device then, at same time other devices should be discarded from communicating with microcontroller. That is why we use wired-AND in I2C bus. When communication between one device an microcontroller occurs then, that device pulls the line low (zero) level so, other device won’t able to communicate with microcontroller. The line state is 1 if none of the devices connected to microcontroller pulls the line to low.

I2C NODES-

In an AVR up to 120 different devices can share an I2C bus. Each of these devices called a node. There are two modes in which each node can be operated –

  1. MASTER
  2. SLAVE

Master is a device which generates the clock for a system; it also initiates and terminates a transmission. The slave is the node that receives the clock and is addressed by the master. There are four modes of operation-

  1. Master transmitter
  2. Master receiver
  3. Slave transmitter
  4. Slave receiver

NOTE-each node has four modes of operation at different times, but it can operate in only one mode of operation at a given time.

 

BIT FORMAT-

I2C is a synchronous serial protocol: each data bit is transferred on the SDA line is synchronized by a high-to-low pulse of the clock generated on SCL line by the master.

NOTE– data line cannot change when the clock line is high; it can change only when clock line is low.

START AND STOP CONDITIONS-

We know that I2C is a connection-oriented protocol that means, to initiate transmission we have to send a START condition and to terminate it we have to send STOP condition.  These START and STOP conditions are generated by the master.

START CONDITION- The START condition generated if SDA line changes from high to low when SCL line is high.

STOP CONDITION- The STOP condition generated if SDA line changes from low to high when SCL line is high.

The bus is considered to be busy between each pair of START and STOP condition and no other device able to take control over the bus between START and STOP conditions. Consider a situation, if a master generated a START condition on a bus and before generating STOP condition if the same master generated START condition again then, this situation is called REPEATED START.

Consider we have connected two AVRs (AVR A and AVR B) with an EEPROM using I2C protocol. Now AVR A wants to find the sum of content present at location 0x02 and 0x04 of an EEPROM. Consider AVR-A doesn’t use REPEATED START. By using I2C, AVR A store the content present at 0x02 of an EEPROM in register R1 and generated STOP condition. Now AVR A looses the control over bus and let at same time AVR B generated START condition and communicating with EEPROM. Consider AVR B changes the content at location 0x04. When AVR A communicate with EEPROM it gets the new value at location 0x04 and the sum is incorrect. That’s why we use REPEATED START. If AVR A uses REPEATED START and don’t loose the control over bus after getting the content at 0x02 then, sum would be correct.

 

PACKET FORMAT IN I2C-

In I2C, each data or address to be transmitted must be framed in packet. Each packet is 9-bits long. The first 8-bits are put on a SDA line by transmitter and 9th bit is an acknowledge bit by receiver (ACK) or it may be not acknowledge (NACK). The clock generated by a master whether it is transmitter or receiver. To get an acknowledge, the transmitter releases the SDA line during 9th clock so that receiver can pull the SDA line low to indicate an ACK. If receiver doesn’t pull the SDA line low, it is considered as NACK.

In I2C, each packet may either contain address or data. The complete data transfer is equals to START condition + address packet + one or more data packet + STOP condition.

ADDRESS PACKET FORMAT-

Why do we study address format? We know that in I2C protocol, master communicate with slaves (devices) connected to it using two-wire interface. But how does master know to communicate with specific a device? It is address which distinguishes different devices connected to master through I2C. Each slave (device) connected to master has its own address, through which master recognizes its slaves (device). Consider a master wants to communicate with device having address “0001 110” then, master write the device address on I2C bus. The device which has that address which is written by master on I2C bus will take control over I2C bus and starts communicating with master.

An address packet is 9-bits long. Each address packet consist of 7-bit address of device + 1-bit for READ/WRITE operation + 1-bit for acknowledgement.

For 7-bit address total 128 devices connected to I2C bus. But there are some exceptions-

  1. Address 0000 000 is reserved for general call.
  2. Address format 1111 xxx are reserved.

That means total 119 (128-1-8) devices can be connected to I2C bus. The 8th bit in address packet READ/WRITE control bit.

  • If this bit is 1 then, read operation. The master will read the data coming from slave. Master acts as receiver and slave acts as transmitter.
  • If this bit is 0 then, write operation. The master will write the data on slave. Master acts as transmitter and slave acts as receiver.

When a slave detect its addressed on the bus, it knows it is being addressed and should acknowledge in the ninth SCL (ACK) cycle by changing the SDA line to zero. But when slave doesn’t want to communicate with master or it doesn’t detect its address on I2C bus then, it should leave the SDA line high on the ninth clock cycle. This is considered as NACK.

Consider an example in which master wants to WRITE to a slave with address 1001 101. The figure given below will illustrate all operations.

We know that slave address 0000 000 is reserved for general call. It means that, when master places this address to I2C bus with write operation then, all slaves connected to that master will receive data simultaneously. This is useful when master wants to transmit the same byte of data to all slaves connected to it. But we don’t use this address when master is in READ operation. As master don’t able to read data from all slaves simultaneously. So we use this address only in WRITE operation.

DATA PACKET FORMAT-

Data packet format is also of 9-bit long. The first 8-bits are data to be transmitted and last bit is acknowledgement. If receiver has received the byte of data and there is no more data to be received or receiver cannot receive or process more data, it will signal NACK by leaving SDA line high.

COMBINING THE ADDRESS AND DATA PACKETS IN TRANSMISSION-

In I2C, normally, a transmission initiated by a START condition, followed by an address packet, one or more data packets, and finished by STOP condition. Consider a master wants to write 1111 0000 to a slave having address 1001 101. The action performed by master is as follows-

  1. The master puts a high-to-low pulse on SDA line while, SCL is high to generate START condition.
  2. The master transmit slave address 1001 101 to I2C bus with 8th bit ‘0’ i.e. 10011010. First seven bits signifies slave address and 8th bit signifies WRITE operation by master in next clock if slave receives its address.
  3. The slave pulls the SDA line low to signifies ACK signal.
  4. After receiving ACK, master write data byte on I2C bus.
  5. When slave device receives the data it leaves the SDA line high to signal NACK. This informs the master that slave doesn’t wants to receive more data.
  6. After receiving NACK, master will know that no more has to be transmitted. The master will changes SDA low-to-high while SCL line is high to generate STOP condition.

READ VS WRITE-

From write operation, we means that master wants to transfer data to slave. The data flow is from master to slave in WRITE operation. From read operation, we means that slave wants to communicate with master and transfer data. The data flow is from slave to master in READ operation.

MULTI-BYTE BURST WRITE-

Burst mode writing is effective means of loading consecutive locations. In burst mode, we provide the address of the first location, followed by the data for that location. From then on, consecutive bytes are written to consecutive memory locations. In this mode, I2C device internally increments the location as long as STOP condition not detected. The following are steps used to transmit multiple bytes of data in burst mode for I2C device-

  1. Generate a START condition.
  2. Transmit the slave address followed by zero (for write).
  3. Transmit the address of first location.
  4. Transmit the data for first location and from then on, simply provide consecutive bytes of data to be placed on in consecutive memory locations.
  5. Generate a STOP condition.

MULTI-BYTE BURST READ-

Burst mode reading is an effective way of bringing out the content os consecutive locations. In burst mode, we provide the address of first location only. From then on, contents are brought by consecutive memory locations. In this mode, the I2C device internally increments the address location as long as it detects STOP condition. The following steps are used to get multiple bytes of data using burst mode for I2C devices-

  1. Generate START condition.
  2. Transmit slave address followed by zero (for address write).
  3. Transmit the address of the first location.
  4. Generate the START condition (REPEATED START).
  5. Transmit the slave address followed by one (for read).
  6. Read the data from first location and then on, brings out the content from consecutive memory locations.
  7. Generate STOP condition.

 

TWO-WIRE INTERFACE (I2C) IN THE AVR:

In this section, we discuss TWI module and registers used with their description. The TWI module in the AVR is composed of four sub modules:

  1. Bit rate generation unit.
  2. Bus interface unit.
  3. Address match unit.
  4. Control unit.

In the figure below the all registers drawn with a thick line are accessible through AVR data bus.

 

  • The bit rate generator unit controls the frequency of the system clock (SCL) when operating in master mode.
  • The bus interface unit controls detects and generate START, STOP and REPEATED START condition. It also detects arbitration, controls the sending or receiving of ACK, and transfers the packet of data or address.
  • The address match unit compares the received address byte with the 7-bit in TWI address register and informs the control if compare match occurs.
  • The control unit control TWI module and generate responses according to setting in the TWI control register. It also set content of status register according to current state.

 

REGISTERS USED AND THEIR DESCRIPTION-

TWI BIT RATE REGISTER (TWBR)-

TWBR selects the division factor to control the SCL clock frequency in master mode. The SCL frequency is controlled by setting in the TWBR and the prescaler bits in the TWSR (TWPS bits). The relation between SCL frequency, TWBR and TWPS bits in TWSR register is shown by following equation-

EXAMPLE– Find the SCL frequency when TWPS in TWSR register is 10 and TWBR is 0001 1100. Given clock frequency is 4MHz.

SOLUTION– We have, TWPS=2 (in decimal)

TWBR=28 (in decimal)

XTAL=4MHz

Using the above formula,

TWI STATUS REGISTER (TWSR)-

TWPS1-TWPS0: These bits Control the bit rate pre scalar (TWPS).

TWPS1 TWPS0 PRE SCALER VALUE
0 0 1
0 1 4
1 0 16
1 1 64

 

TWS7-TWS3: These five bits show the status of the TWI control and bus. The value read from TWSR register contains both 5-bit status value and 2-bit pre scalar value. So, if we want to read status then, we have to mask the first two pre scalar bits and then read TWSR register.

When master write address of any slave on I2C bus then, that address is detected by the slave or not is known to master by reading these status bits in TWSR register. Suppose a slave has address 1010 001 and master writes this address on I2C bus. Then slave detects its address and send ACK to master. Then master knows that slave has received address and send acknowledgement by reading 0x18 from status register. This means that the value of status bits changes as master or slave write on I2C bus. Each code has different meaning as given below in tables:

 

STATUS CODES FOR MASTER TRANSMITTER MODE- 

STATUS CODE (TWSR)

PRESCALER BITS ARE 0

STATUS OF TWO-WIRE SERIAL BUS AND TWO-WIRE SERIAL INTERFACE HARDWARE
0x08 A START condition has been transmitted.
0x10 A REPEATED START condition has been transmitted.
0x18 SLAVE address + WRITE has been transmitted; ACK has been received.
0x20 SLAVE address + WRITE has been transmitted; NOT ACK has been received.
0x28 Data byte has been transmitted; ACK has been received.
0x30 Data byte has been transmitted; NOT ACK has been received.
0x38 Arbitration lost in SLAVE address + WRITE or Data bytes.

 

STATUS CODES FOR MASTER RECEIVER MODE- 

 

STATUS CODE (TWSR)

PRESCALER BITS ARE 0

STATUS OF TWO-WIRE SERIAL BUS AND TWO-WIRE SERIAL INTERFACE HARDWARE
0x08 A START condition has been transmitted.
0x10 A REPEATED START condition has been transmitted.
0x38 Arbitration lost in SLAVE address + READ or NOT ACK bit.
0x40 SLAVE address + READ has been transmitted; ACK has been received.
0x48 SLAVE address + READ has been transmitted; NOT ACK has been received.
0x50 Data byte has been received; ACK has been returned.
0x58 Data byte has been received; NOT ACK has been returned.

We are not discussing status codes for SLAVE receiver and transmitter mode. It can be seen from AVR datasheet.

TWI CONTROL REGISTER (TWCR)-

It controls the operation of TWI.

 

TWI INTERRUPT FLAG (TWINT)-

When the TWI hardware finished its job, it set TWINT bit to one. If the TWI and general interrupts are enabled, changing TWINT to HIGH cause the microcontroller to jump to interrupt vector. When the TWINT bit is set, the TWI module “stretches” the SCL line to provide enough time for software to do specified jobs. When software finishes its job, it must clear the TWINT bit to resume the operation of the TWI module. We can access TWI address, data and status register only when TWINT bit is HIGH. When we try to write in TWI data register when TWINT is low, then collision happen and TWWC bit is set HIGH by software. Software can monitor TWINT bit to know when TWI module finishes its job and ready to get new command.

 

TWI Enable ACKNOWLEDGE (TWEA) bit-

Making this bit HIGH will enable the generation of ACK if any of the following conditions are met-

  1. The TWI address match module detects that the TWI module is addressed by receiving its own slave address from the bus.
  2. A general call has been received while the TWGCE bit in the TWAR is set to one (to enable accepting of global calls).
  3. A data byte has been received in each of the receiving modes, master receiver or slave receiver.

 

NOTE– If we clear TWEA bit than device will doesn’t generate ACK.

 

TWI START bit and TWI STOP bit (TWSTA and TWSTO)-

To generate start and stop condition we have to set TWSTA and TWSTO bits in TWCR register respectively. When we set TWSTA bit then, SDA line changes from high-to-low while SCL is high. When we set TWSTO bit then, SDA line changes from low-to-high while SCL is high.

 

TWI DATA REGISTER (TWDR)-

Suppose we are in master mode and we want to transmit data to slave then, we write the data into TWDR register and waits tills data transmitted. If we are in slave mode then, data transmitted from master comes in TWDR register. So, as soon as we write data into TWDR register then, data is ready for transmission.

 

TWI ADDRESS REGISTER (TWAR)-

If master wants to write slave address on I2C bus then, master write slave address in TWAR register. The slave address is 7-bits long and TWAR register consist of 7-bit long slave address and 8th bit is TWGCE (TWI general call recognition enable). When TWGCE bit is set then, receiving of general call address will cause an interrupt request.

 

TWI PROGRAMMING IN C-

PROGRAMMING OF THE AVR TWI IN MASTER OPERATING MODE-

To operate in master mode we have to do following steps-

  1. Initialize the TWI.
  2. Transmit a START condition.
  3. Send or receive data.
  4. Transmit a stop condition.

Initialization-

To initialize the TWI module in master operating mode, we should do the following steps-

  1. Set TWI clock frequency by setting the values of TWBR register and TWPS bits in TWSR register.
  2. Enable TWI module by setting the TWEN bit in TWCR register.

TRANSMIT START CONDITION-

To start data transfer in master mode, we should first transmit the Start condition. To transmit Start condition we should set the following bits of TWCR register-

  1. TWEN- Setting this bit one enables the TWI module.
  2. TWSTA- Setting this bit to one tells the TWI module to initiate the START condition when bus is free.
  3. TWINT- Setting this bit to one clears the interrupt flag to initiate operation of the TWI module to transmit the START condition. Then we should wait till TWINT flag set. If transmission of START condition completed then, TWINT set.

SEND DATA-

To send a byte of data, we should do the following steps after START condition has been transmitted-

  1. Write the data to be transmitted in TWDR register.
  2. Set TWEN and TWINT bits of TWCR register, to start the transmission of data.
  3. Wait till TWINT flag is set. The TWINT flag remain zero till data transmission occurs so, we have to wait till data transmission occur.

NOTE- We should remember that right after START condition, we should transmit slave address + WRITE or slave address + READ.

  • Right after sending slave address + WRITE, we should write to the slave.
  • After sending slave address + READ, we should read from the slave.

To write a byte of data to a slave we have made I2C_WRITE() function.

RECEIVE DATA-

To receive a byte of data after transmitting slave address + READ, we have to do following steps-

  1. Set TWEN and TWINT bits of TWCR register to start receiving the byte of data. If want to return acknowledgement to device which sends data then, we have to set the TWEA bit in TWCR register.
  2. Wait till TWINT bit set. As we know that while we receiving the data the TWINT bit remains zero. It becomes one if data is completely received.
  3. We know that received data comes in TWDR register then, Copy the data from TWDR register to a new register.

STOP CONDITION-

After data transfer, we must transmit STOP condition. This can be done by setting TWEN, TWINT and TWSTO bits of TWCR register.

PROGRAMMING OF THE AVR TWI IN SLAVE OPERATING MODE-

To work in slave operating mode, we must initialize TWI and send or receive data. One that we need to remember is that in slave mode we don’t transmit START and STOP condition. A listen device should listen to bus and wait to be addressed by a master device or general call.

Initialization-

We should do following steps to initialize device in slave operating mode-

  1. Put the slave address in TWAR register.
  2. Enable TWI module by setting TWEN bit in TWCR register.
  3. Set TWEN, TWINT and TWEA bits in TWCR register to enable TWI and acknowledgment generation.

LISTEN TO THE BUS-

When slave device detects its own address on I2C bus, it sends ACK. Always remember that, when a slave device detects its own address then, it sets TWINT flag. So we have to wait till TWINT flag is set.

SEND DATA-

After being addressed from master, the slave device can send a byte of data. To send data byte from slave we have to do following steps-

  1. Write the data to be transmitted in TWDR register.
  2. Set TWEN and TWINT bits of TWCR register, to start the transmission of data.
  3. Wait till TWINT flag is set. The TWINT flag remain zero till data transmission occurs so, we have to wait till data transmission occur.

RECEIVE DATA-

After being addressed by master, we have to do following steps to receive a byte of data from device-

  1. Set TWEN and TWINT bits of TWCR register to start receiving the byte of data. If want to return acknowledgement to device which sends data then, we have to set the TWEA bit in TWCR register.
  2. Wait till TWINT bit set. As we know that while we receiving the data the TWINT bit remains zero. It becomes one if data is completely received.
  3. We know that received data comes in TWDR register then, Copy the data from TWDR register to a new register.

DS1307 RTC INTERFACING AND PROGRAMMING-

INTRODUCTION-

The real time clock (RTC) is a widely used device which gives accurate time and date information for many applications. Here we are discussing interfacing of DS1307 RTC with AVR microcontroller and its programming. We know that this device gives accurate time and date. So, we extract this accurate information from this device and send it to AVR microcontroller using I2C protocol. The information we extract from RTC device, we display it on a LCD connected to microcontroller. So, basically we are using our microcontroller as a master and receiving information from slave device. Before extracting information from RTC device, we first set the time and date of our own will. There are two operations that we are performing, first is sending data from master to slave, second getting data from slave device continuously. Now we are giving brief information about DS1307 RTC and registers used.

X1-X2- These are input pins that allows DS1307 to connection to external crystal oscillator to provide the clock source to chip. We must use standard 32.768 KHz quartz crystal. The accuracy of clock depends on the quality of crystal.

 

Pin3 can be connected to external +3 volt lithium battery, thereby providing the power source to the chip when the external supply voltage is not available. We must connect this pin to ground if it is not connected to battery.

GND-

Pin4 is ground.

SDA (SERIAL DATA)-

Pin5 is SDA pin and it must be connected to SDA pin of I2C bus.

SCL (SERIAL CLOCK)-

Pin6 is SCL pin and it must be connected to SCL pin of I2C bus.

SWQ/OUT-

Pin7 is an output pin providing 1 KHz, 4 KHz, 8 KHz and 32 KHz frequency if enabled. This pin needs to be connected to external pull-up resistor to generate frequency because it is open drain. If we don’t want to use this pin we can omit the external pull-up resistor.

Pin8 is primary voltage source to the chip. If this voltage source goes below the level of , then DS1307 switches to lithium battery.

 

ADDRESS MAP OF DS1307-

The DS1307 has 64 bytes of RAM space with address range from 0x00 to 0x3F. The first seven bytes are kept aside for RTC values of time and date i.e.0x00 and 0x06 locations are for RTC values. The next byte is used for control register. This means from 0x07 to 0x3F locations are used for general purpose storage. The given figure shows address map of DS1307-

THE DS1307 CONTROL REGISTER-

In DS1307, control register controls the function of SQW/OUT pin.

OUT (OUTPUT CONTROL)- If square wave output is disabled, setting OUT bit to one will make the SQW/OUT pin low, and clearing OUT bit to zero will make SQW/OUT pin high.

SQWE (square wave enable)- If this bit is set high, oscillator output is enabled; otherwise it is disabled.

RS1-RS0 (rate select bit)- These bits select the output frequency of the oscillator output-

RS1 RS0 OUTPUT FREQUENCY
0 0 1Hz
0 1 4.096 KHz
1 0 8.192 KHz
1 1 32.768 KHz

 

CH bit in address 00-

One of the most important bit in the seconds location is CH (clock halt). It is the 7th bit of address 0x00. Setting this bit to one disables the oscilator, while setting CH bit to zero enables the oscillator.

TIME AND DATE ADDRESS LOCATIONS AND MODES-

We know that the byte address 0x00 to 0x06 are kept aside for time and date. DS1307 provides data only in BCD format.

  • We can select 12 -hour or 24-hour mode using bit 6 of hour location 0x02.
  • When D6=1, 12-hour mode selected and when D6=0, 24-hour mode selected.
  • In 12-hour mode we can provide AM and PM using 5th
  • If D5=0, the AM is selected and D5=1, PM is selected.

REGISTER POINTER-

In DS1307 there is register pointer that specifies the byte that will be accessed in next read or write command. After each read or write operation content of register pointer automatically incremented by one.

WRITING TO DS1307-

To set the value of register pointer and write one or more bytes of data to DS1307, we follow the following steps-

  1. To access DS1307 for a write operation, after sending the START condition, we should transmit the address of DS1307 (1001101) followed by 0 to indicate a write operation.
  2. The first byte of data in the write operation will set the register pointer. Suppose we need to access control register. The location of the control register is 0x07 so, we send 0x07 using I2C.
  3. If we want to send more than one byte at a time then, we send a byte and after sending the byte again the value of register pointer incremented by one.
  4. Transmit the STOP condition.

READ FROM DS1307-

Before reading a byte we should first load the address of the byte to register pointer by doing a write operation.

The following steps are required to read a byte of data from register pointer-

  1. To access DS1307 for reading operation, after sending START condition, we should transmit the address of DS1307 followed by 1 to indicate read operation.
  2. Now we can read one or more bytes of data.
  3. Transmit the STOP condition.

EXAMPLE- WRITE A PROGRAM IN WHICH AVR MICROCONTROLLER DISPLAYS THE CURRENT TIME ON LCD USING DS1307.USE I2C PROTOCOL AND XTAL=8MHz.

SOLUTION-

CIRCUIT DIAGRAM-