LCD 16×2 via I2C with PIC16

Embedded, I2C, PIC
1 Comment

Description

100%
100%

I wrote a tutorial few days ago explaining I2C and PIC16 and today I am going to show you an application of it. So today I am going to interface LCD 16×2 via I2C with PIC16.
LCD 16×2 have around 16 pins which needs to be connected to microcontroller in order to make it work. But by using an I2C extender, we only needs to connect 2 pins (SDA and SCL) to the microcontroller. This saves other pins for other functions and also reduce the wiring.
The I2C extender I am going to use is PCF8574 with the I2C address 0x4E and it is already attached to the LCD I have. I am using PIC16F877A and the concept will be pretty much same for other PIC microcontrollers.

First of all let’s see the connections between the PCF8574 and the LCD.
As shown in the figure, connect the first pin of the PCF8574 to the VSS of the LCD, 2nd pin to the VCC and so on. The input pins of the PCF8574 i.e. SCL and SDA should be connected with the SCL and SDA of the microcontroller.

Check out the connections in the next TAB.

Some Insight into the CODE

As I mentioned I am going to use the same I2C functions as discussed in the previous tutorial with additional few. Check out that tutorial HERE. These functions are as follows:-

  • I2C_wait (); wait for the bits in the status register to clear before starting another transaction
  • I2C_start (); Starts the I2C
  • I2C_stop (); Stops the I2C
  • I2C_write(); writes the data or command to the slave
  • I2C_init (uint32_t clock); initialise I2C with the given clock speed

Other than these, I am going to write some new functions for the LCD purpose
lcd_send_cmd sends the command to the LCD

void lcd_send_cmd (unsigned char data)
{
	unsigned char data_l, data_u;
	data_l = (data<<4)&0xf0;  //select lower nibble by moving it to the upper nibble position
	data_u = data&0xf0;  //select upper nibble

	I2C_start();
	I2C_write (SLAVE_ADDRESS_LCD);
	I2C_write (data_u|0x0C);  //enable=1 and rs =0
	I2C_write (data_u|0x08);  //enable=0 and rs =0

	I2C_write (data_l|0x0C);  //enable =1 and rs =0
	I2C_write (data_l|0x08);  //enable=0 and rs =0

	I2C_stop();
}

lcd_send_data sends the data to the LCD

void lcd_send_data (unsigned char data)
{
	unsigned char data_l, data_u;
	data_l = (data<<4)&0xf0;  //select lower nibble by moving it to the upper nibble position
	data_u = data&0xf0;  //select upper nibble

	I2C_start();
	I2C_write (SLAVE_ADDRESS_LCD);
	I2C_write (data_u|0x0D);  //enable=1 and rs =1
	I2C_write (data_u|0x09);  //enable=0 and rs =1

	I2C_write (data_l|0x0D);  //enable =1 and rs =1
	I2C_write (data_l|0x09);  //enable=0 and rs =1

	I2C_stop();
}

lcd_send_string sends the string of data

void lcd_send_string (char *str)
{
	while (*str) lcd_send_data (*str++);
}

lcd_init initialise the Display

void lcd_init (void)
{
	lcd_send_cmd (0x02);
	lcd_send_cmd (0x28);
	lcd_send_cmd (0x0c);
	lcd_send_cmd (0x80);
}

Now we just need to initialise I2C and Display and than start sending the data

Lcd-Commands

Lcd-Commands
int main ()
{
    
    I2C_init (100000);  // initialise I2C at 100KHz
    lcd_init ();
    
    lcd_send_string ("hello world");

    
    while (1)
    {
       
    }
}

YOU CAN DOWNLOAD FULL CODE AT THE END OF THIS POST

100%
100%

Connection

100%
100%
100%
100%

Result

100%
100%
Check out the VIDEO Below
100%
100%

DOWNLOAD

You can buy me a coffee sensor 🙂

download the CODE below

100%
100%
, , , , , , , , ,

1
Leave a Reply

avatar
1 Comment threads
0 Thread replies
0 Followers
 
Most reacted comment
Hottest comment thread
1 Comment authors
Andres Recent comment authors
  Subscribe  
newest oldest most voted
Notify of
Andres
Guest

Hi, i have a question, if have a variable X that changes in time, can i add it using this:
lcd_send_string (“TIME=%02U”,X);

Menu