Interface LCD usnig PCF8574 I/O Expander with micro controller.
Interface LCD using I2C protocol and PCF8574 IO expander IC.
Schematic shows the LCD connections with controller ATmega328p through PCF8574.
Code is written in Atmel studio 6
Following is the c code for run LCD:-
#define LCD_RS 2
#define LCD_EN 3
#define LCD_DATA4 4
#define LCD_DATA5 5
#define LCD_DATA6 6
#define LCD_DATA7 7
#define PCF8574 0x40
unsigned char LCD_DataArray[20]={0};
unsigned char ASCII_NumArray[10]={0};
unsigned char LCD_DATA;
void lcd_init(void);
void lcd_cw8(unsigned char);
void lcd_cw4(unsigned char);
void lcd_dw8(unsigned char);
void lcd_dw4(unsigned char);
void display(char *);
void LCDDataGoto(unsigned char LineNo,unsigned int loc);
void LCDDataPutchar(unsigned char character);
void lcd_init(void)
{
delay_ms(30);
lcd_cw4(0x30);
delay_ms(15);
lcd_cw4(0x30);
delay_ms(15);
lcd_cw4(0x30);
delay_ms(15);
lcd_cw4(0x20);
delay_ms(15);
lcd_cw8(0x28); //0 0 1 DL N F * * DL=0 4bit N=1 No of Lines F=5×7
lcd_cw8(0x14); //0 0 0 1 S/C R/L * * S/C=0 shift cursor R/L=1 Right
lcd_cw8(0x0C); //0 0 0 0 0 1 D C B D=1 C = 1 B = 1
lcd_cw8(0x06); //0 0 0 0 0 0 1 I/D S I/D= 1 S = 0
lcd_cw8(0x01); //clear Screen
lcd_cw8(0x80);
}
//———————————————-
void lcd_cw8(unsigned char value)
{
lcd_cw4(value);
lcd_cw4(value<<4);
}
//———————————————-
void lcd_cw4(unsigned char value)
{
LCD_DATA = ~(1<<LCD_RS); //RS = 0 command
PFC_WriteI2C(PCF8574, LCD_DATA ); // PCF8574 I/O expander address = 0x40
// LCD_DATA |=(value & 0xF0); //PA4 to PA7 = 4 bit data //(LCD_DATA & 0x0F)|
// PFC_WriteI2C(0x40, 0x40, LCD_DATA );
LCD_DATA &= ~(1<<LCD_DATA4); // make data pins 0
LCD_DATA &= ~(1<<LCD_DATA5);
LCD_DATA &= ~(1<<LCD_DATA6);
LCD_DATA &= ~(1<<LCD_DATA7);
if((value & 0x80)) LCD_DATA |= (1<<LCD_DATA7); // if condition true make port pin 1
if((value & 0x40)) LCD_DATA |= (1<<LCD_DATA6);
if((value & 0x20)) LCD_DATA |= (1<<LCD_DATA5);
if((value & 0x10)) LCD_DATA |= (1<<LCD_DATA4);
PFC_WriteI2C(PCF8574, LCD_DATA ); // write data to pin
LCD_DATA |= (1<<LCD_EN); //EN = 1 // enable and disable EN pin
PFC_WriteI2C(PCF8574, LCD_DATA );
delay_ms(1);
LCD_DATA &= ~(1<<LCD_EN); //EN = 0;
PFC_WriteI2C(PCF8574, LCD_DATA );
}
//———————————————-
void lcd_dw8(unsigned char value)
{
lcd_dw4(value);
lcd_dw4(value<<4);
}
//———————————————-
void lcd_dw4(unsigned char value)
{
LCD_DATA = (1<<LCD_RS); //RS = 1 Data
PFC_WriteI2C(PCF8574, LCD_DATA );
// LCD_DATA |= (value & 0xF0); //PA4 to PA 7 = 4 bit data //(LCD_DATA & 0x0F)|
// PFC_WriteI2C(0x40, 0x40, LCD_DATA );
LCD_DATA &= ~(1<<LCD_DATA4); // make data pins 0
LCD_DATA &= ~(1<<LCD_DATA5);
LCD_DATA &= ~(1<<LCD_DATA6);
LCD_DATA &= ~(1<<LCD_DATA7);
if((value & 0x80)) LCD_DATA |= (1<<LCD_DATA7); // if condition true make port pin 1
if((value & 0x40)) LCD_DATA |= (1<<LCD_DATA6);
if((value & 0x20)) LCD_DATA |= (1<<LCD_DATA5);
if((value & 0x10)) LCD_DATA |= (1<<LCD_DATA4);
PFC_WriteI2C(0x40, LCD_DATA );
LCD_DATA |= (1<<LCD_EN); //EN = 1
PFC_WriteI2C(PCF8574, LCD_DATA );
delay_ms(1);
LCD_DATA &= ~(1<<LCD_EN); //EN = 0;
PFC_WriteI2C(PCF8574, LCD_DATA );
}
//———————————————-
//———————————-
void display( char *str)
{
unsigned char len,i;
len = strlen(str);
for(i=0;i<len;i++)
{
if(i==16)
lcd_cw8(0xC0);
lcd_dw8(*str);
str++;
}
}
void LCDDataGoto(unsigned char LineNo,unsigned int loc)
{
if(LineNo == 1)
{
lcd_cw4(((0x80 + (loc-1)) &0xf0));
lcd_cw4(((0x80 + (loc-1)) <<4 &0xf0));
}
else if(LineNo == 2)
{
lcd_cw4(((0xc0 + (loc-1)) &0xf0));
lcd_cw4(((0xc0 + (loc-1)) <<4 &0xf0));
}
else if(LineNo == 3)
{
lcd_cw4(((0x94 + (loc-1)) &0xf0));
lcd_cw4(((0x94 + (loc-1)) <<4 &0xf0));
}
else
{
lcd_cw4(((0xD4 + (loc-1)) &0xf0));
lcd_cw4(((0xD4 + (loc-1)) <<4 &0xf0));
}
}
void LCDDataPutchar(unsigned char character)
{
lcd_dw4((character ) & 0xF0);
lcd_dw4(((character) << 4) & 0xF0);
}
Please comment for more information and data sharing….