PIC18F4550 I2C - PIC Controllers
PIC18F4550 I2C - PIC Controllers
Introduction
I2C (Inter-Integrated Circuit) is a master-slave protocol that may have one master or many master and many slaves whereas
SPI has only one master.
It is a synchronous serial protocol that communicates data between two devices.
It is generally used for communication over a short distance. It is a slow speed protocol as compared to SPI communication.
The I2C device has 7-bit or 10-bit unique address. So to access these devices, the master has to address them by the 7-bit or
10-bit unique address.
I2C is used in many applications like reading RTC (Real-time clock), accessing external EEPROM memory. It is also used in
sensor modules like gyro, magnetometer, etc.
It is also called as Two Wire Interface (TWI) protocol.
1. Serial Clock (SCL): It is a clock signal. Data will be sent to other devices on the clock tick event. The only master device has
control over this SCL line.
2. Serial Data(SDA): It is a serial data line which is used to send data in either direction.
The I2C bus is an open-drain configuration which means they can pull the corresponding signal line low but cannot drive it high.
Hence the line will go into an unknown state. In order to avoid this, pull up resistors need to be connected to SCL and SDA pins.
PORTB.0 and PORTB.1 pins are used for I2C communication as SDA and SCL respectively.
PIC18F4550 has Master Synchronous Serial Protocol module (MSSP) which includes I2C protocol.
I2C Registers
To establish I2C communication between devices, we have to configure PIC18F4550. To do this, PIC18F4550 has different registers
which are as follows
In I2C protocol, SSPBUF is a data register which is used for transmission and reception of data.
It is a shift register that is used to shift data in and out on the SDA line. It is not directly accessible.
In Master mode:
In Slave mode:
SSPCON1: MSSP Control 1 Register
1 = SSPBUF Register is written while it is still transmitting the previous word.
0 = No collision.
1 = A byte is received while SSPBUF Register is still holding the previous word.
0 = No overflow.
1 = Enables the Serial Port and configures SDA and SCL pin as a serial port pin.
In slave mode:
1110 = I2C Slave mode, 7-bit address with Start and Stop interrupt enabled
1111 = I2C Slave mode, 10-bit address with Start and Stop interrupt enabled
This bit is used when the master requests to slave devices for reading/receiving of data.
1 = Not acknowledge which tells other devices stop sending data.
1 = Initiate acknowledge sequence on SDA and SCL pins and transmit ACKDT data bit which is automatically cleared by
hardware.
1 = Slew rate control disabled for standard speed mode (100 kHz and 1MHz).
0 = Slew rate control enabled for high speed mode (400 kHz).
In Slave mode:
1 = indicates that the last byte received or transmitted was data
0 = indicates that the last byte received or transmitted was address
1 = indicates that the stop bit has been detected last
0 = stop bit was not detected last
1 = indicates that the start bit has been detected last
In Slave mode:
1 = Read
0 = Write
In Master mode:
1 = Indicates that the user needs to update the address in the SSPADD register.
In Transmit mode:
In Receive mode:
1 = SSPBUF is full (does not include ACK and stop bit.)
After complete transmission of data/address, Buffer full flag is set, and also acknowledge signal is received. After reception of
the acknowledge signal, the SSPIF interrupt flag is set.
Whereas in data reception, the Buffer full flag is set when a complete byte is received and the device needs to send an
Acknowledge signal for indication of reading continuation. And when data is shifted from SSPSR register to SSPBUF, SSPIF
flag is set.
So to check whether the transmission/reception is complete or not, we have to monitor either BF flag or the SSPIF interrupt
flag.
I2C_Master
void I2C_Init()
TRISB1=1;
SSPCON2=0;
SSPIF=0;
Send start pulse to the slave device by setting a bit in SEN in the SSPCON2 register.
Wait for SEN bit to clear.
Also, check S bit in SSPSTAT register which indicates the start bit is detected or not.
And then send the device slave address along with write operation and check for acknowledgment signal.
SSPIF=0;
Write/Transmit Data
We have to monitor BF flag or SSPIF which will set when transmission/reception of a byte is complete.
Check the BF flag and R/W bit in the SSPSTAT register for finding the I2C bus is ready or not.
void I2C_Ready()
while(SSPSTATbits.BF || (SSPSTATbits.R_nW));
Also SSPIF flag can be used to poll the complete byte transmit/receive status. Also, it is necessary to clear the SSPIF interrupt flag
through software.
void I2C_Ready()
Copy/write data to the SSPBUF register for transmission and wait for the completion of the transmission.
I2C_Ready();
return 1;
else
return 2;
Set the PEN bit in SSPCON2 register and wait for the PEN bit to clear.
Also, check P bit in the SSPSTAT register which indicates the stop bit is detected.
char I2C_Stop()
I2C_Ready();
SSPIF = 0;
Read/Receive Data
/* Read data from location and send ack or nack depending upon parameter*/
int buffer=0;
/* Wait for buffer full flag which when complete byte received */
while(!SSPSTATbits.BF);
if(flag==0)
I2C_Ack();
else
I2C_Nack();
I2C_Ready();
return(buffer);
Acknowledgment
void I2C_Ack()
while(ACKEN);
Negative Acknowledgement
void I2C_Nack()
while(ACKEN);