I am trying to interface an LCD using I2C but can't quite understand how to do it. I found this example Here's the code: i2c.h:
/* File: I2C_LCD.h */
#define _XTAL_FREQ 16000000
#define I2C_BaudRate 100000
#define SCL_D TRISC3
#define SDA_D TRISC4
#define LCD_BACKLIGHT 0x08
#define LCD_NOBACKLIGHT 0x00
#define LCD_FIRST_ROW 0x80
#define LCD_SECOND_ROW 0xC0
#define LCD_THIRD_ROW 0x94
#define LCD_FOURTH_ROW 0xD4
#define LCD_CLEAR 0x01
#define LCD_RETURN_HOME 0x02
#define LCD_ENTRY_MODE_SET 0x04
#define LCD_CURSOR_OFF 0x0C
#define LCD_UNDERLINE_ON 0x0E
#define LCD_BLINK_CURSOR_ON 0x0F
#define LCD_MOVE_CURSOR_LEFT 0x10
#define LCD_MOVE_CURSOR_RIGHT 0x14
#define LCD_TURN_ON 0x0C
#define LCD_TURN_OFF 0x08
#define LCD_SHIFT_LEFT 0x18
#define LCD_SHIFT_RIGHT 0x1E
#define LCD_TYPE 2 // 0 -> 5x7 | 1 -> 5x10 | 2 -> 2 lines
//-----------[ Functions' Prototypes ]--------------
//---[ I2C Routines ]---
void I2C__Init();
void I2C__Wait();
void I2C__Start();
void I2C__RepeatedStart();
void I2C__Stop();
void I2C_ACK();
void I2C_NACK();
unsigned char I2C__Write(unsigned char data);
unsigned char I2C_Read_Byte(void);
//---[ LCD Routines ]---
void LCD_Init(unsigned char I2C_Add);
void IO_Expander_Write(unsigned char Data);
void LCD_Write_4Bit(unsigned char Nibble);
void LCD_CMD(unsigned char CMD);
void LCD_Set_Cursor(unsigned char ROW, unsigned char COL);
void LCD_Write_Char(char);
void LCD_Write_String(char*);
void Backlight();
void noBacklight();
void LCD_SR();
void LCD_SL();
void LCD_Clear();
I2c.c
#include <xc.h>
#include "I2C.h"
unsigned char RS, i2c_add, BackLight_State = LCD_BACKLIGHT;
//---------------[ I2C Routines ]-------------------
//--------------------------------------------------
void I2C__Init()
{
SSPCON = 0x28;
SSPCON2 = 0x00;
SSPSTAT = 0x00;
SSPADD = ((_XTAL_FREQ/4)/I2C_BaudRate) - 1;
SCL_D = 1;
SDA_D = 1;
}
void I2C__Wait()
{
while ((SSPSTAT & 0x04) || (SSPCON2 & 0x1F));
}
void I2C__Start()
{
I2C__Wait();
SEN = 1;
}
void I2C__RepeatedStart()
{
I2C__Wait();
RSEN = 1;
}
void I2C__Stop()
{
I2C__Wait();
PEN = 1;
}
void I2C_ACK(void)
{
ACKDT = 0; // 0 -> ACK
I2C__Wait();
ACKEN = 1; // Send ACK
}
void I2C_NACK(void)
{
ACKDT = 1; // 1 -> NACK
I2C__Wait();
ACKEN = 1; // Send NACK
}
unsigned char I2C__Write(unsigned char data)
{
I2C__Wait();
SSPBUF = data;
while(!SSPIF); // Wait Until Completion
SSPIF = 0;
return ACKSTAT;
}
unsigned char I2C_Read_Byte(void)
{
//---[ Receive & Return A Byte ]---
I2C__Wait();
RCEN = 1; // Enable & Start Reception
while(!SSPIF); // Wait Until Completion
SSPIF = 0; // Clear The Interrupt Flag Bit
I2C__Wait();
return SSPBUF; // Return The Received Byte
}
//======================================================
//---------------[ LCD Routines ]----------------
//------------------------------------------------------
void LCD_Init(unsigned char I2C_Add)
{
i2c_add = I2C_Add;
IO_Expander_Write(0x00);
__delay_ms(30);
LCD_CMD(0x03);
__delay_ms(5);
LCD_CMD(0x03);
__delay_ms(5);
LCD_CMD(0x03);
__delay_ms(5);
LCD_CMD(LCD_RETURN_HOME);
__delay_ms(5);
LCD_CMD(0x20 | (LCD_TYPE << 2));
__delay_ms(50);
LCD_CMD(LCD_TURN_ON);
__delay_ms(50);
LCD_CMD(LCD_CLEAR);
__delay_ms(50);
LCD_CMD(LCD_ENTRY_MODE_SET | LCD_RETURN_HOME);
__delay_ms(50);
}
void IO_Expander_Write(unsigned char Data)
{
I2C__Start();
I2C__Write(i2c_add);
I2C__Write(Data | BackLight_State);
I2C__Stop();
}
void LCD_Write_4Bit(unsigned char Nibble)
{
// Get The RS Value To LSB OF Data
Nibble |= RS;
IO_Expander_Write(Nibble | 0x04);
IO_Expander_Write(Nibble & 0xFB);
__delay_us(50);
}
void LCD_CMD(unsigned char CMD)
{
RS = 0; // Command Register Select
LCD_Write_4Bit(CMD & 0xF0);
LCD_Write_4Bit((CMD << 4) & 0xF0);
}
void LCD_Write_Char(char Data)
{
RS = 1; // Data Register Select
LCD_Write_4Bit(Data & 0xF0);
LCD_Write_4Bit((Data << 4) & 0xF0);
}
void LCD_Write_String(char* Str)
{
for(int i=0; Str[i]!='\0'; i++)
LCD_Write_Char(Str[i]);
}
void LCD_Set_Cursor(unsigned char ROW, unsigned char COL)
{
switch(ROW)
{
case 2:
LCD_CMD(0xC0 + COL-1);
break;
case 3:
LCD_CMD(0x94 + COL-1);
break;
case 4:
LCD_CMD(0xD4 + COL-1);
break;
// Case 1
default:
LCD_CMD(0x80 + COL-1);
}
}
void Backlight()
{
BackLight_State = LCD_BACKLIGHT;
IO_Expander_Write(0);
}
void noBacklight()
{
BackLight_State = LCD_NOBACKLIGHT;
IO_Expander_Write(0);
}
void LCD_SL()
{
LCD_CMD(0x18);
__delay_us(40);
}
void LCD_SR()
{
LCD_CMD(0x1C);
__delay_us(40);
}
void LCD_Clear()
{
LCD_CMD(0x01);
__delay_us(40);
}
main.c:
#include "I2C.h"
void main(void) {
I2C__Init();
LCD_Init(0x4E); // Initialize LCD module with I2C address = 0x4E
LCD_Set_Cursor(1, 1);
LCD_Write_String(" Welcome To ");
LCD_Set_Cursor(2, 1);
LCD_Write_String(" MicroDigiSoft ");
delay_ms(2500);
while(1)
{
}
return;
}
But I get these Errors: Screenshot of Error Screenshot of Error
I am using MikroC and one thing to note is that I have included the system libraries Lcd and Lcd Constants. How can I fix these errors, and are there any examples of interfacing LCD I2C with microcontrollers apart from this?
You must import the I2C system libray in the the MikroC Library Manager, at the right panel. See the attached image: