I've been doing fine with my LCD1602 I2C configuration but I discovered that command and data functions are the same even though I change the RS command/data bit, but the result is the same.
This is really strange, I really can't do anything about it??!
#define E 2 // E bit
#define RW 1 // RW bit
#define RS 0 // RS bit
#define LCDadd_WR 0x4E
#define LCDadd_RD 0x4F
uint8_t bitmask = 0x08;
uint8_t i, arr[]={0x48,0x65,0x6c,0x6c,0x6f ,0x10 ,0x3a,0x29 ,0x10 ,0x48,0x6f,0x77,0x10
,0x61,0x72,0x65,0x10,0x79,0x6f,0x75,0x65,0x76,0x65,0x72,0x79,0x10,0x6f,0x6e,0x65};
// LCD prototypes
void LCD_Init(void);
void sendCMD(uint8_t CMD);
void sendData(uint8_t data);
void LCD_string(uint8_t arr1[]);
void move_cursor (uint8_t row, uint8_t col);
// I2C prototypes
void I2C_init(void);
void I2C_start(uint8_t address);
void I2C_stop(void);
void I2C_tx(uint8_t data);
void I2C_TWSR_Check(void);
void setup() {
Serial.begin(9600);
I2C_init();
LCD_Init();
}
void loop() {
//sendData(0x0E); /* I commented this line because it has the same effect as sendCMD(0x0F); in sendCMD function */
}
///////////////////////////////////////////////////
///////////////////////////////////////////////////
void LCD_Init(void)
{
sendCMD(0x33);
sendCMD(0x32);
sendCMD(0x28);
sendCMD(0x0F);
sendCMD(0x01);
}
void sendCMD(uint8_t CMD)
{
bitmask = 0x08;
I2C_start(LCDadd_WR);
I2C_tx(bitmask &= ~(1<<RS));
Serial.println("CMD");
Serial.println(bitmask, HEX);
I2C_tx(bitmask &= ~(1<<RW));
I2C_tx(bitmask = CMD & 0xF0 | 0x08);
_delay_ms(5);
I2C_tx(bitmask |= (1<<E));
_delay_ms(1);
I2C_tx(bitmask &= ~(1<<E));
_delay_ms(1);
I2C_tx(bitmask = (CMD<<4) & 0xF0 | 0x08);
I2C_tx(bitmask |= (1<<E));
_delay_ms(1);
I2C_tx(bitmask &= ~(1<<E));
I2C_stop();
}
void sendData(uint8_t data)
{
bitmask = 0x08;
I2C_start(LCDadd_WR);
I2C_tx(bitmask |= (1<<RS));
Serial.println("data");
Serial.println(bitmask, HEX);
I2C_tx(bitmask &= ~(1<<RW));
I2C_tx(bitmask = data & 0xF0 | 0x08);
_delay_ms(5);
I2C_tx(bitmask |= (1<<E));
_delay_ms(1);
I2C_tx(bitmask &= ~(1<<E));
_delay_ms(1);
I2C_tx(bitmask = (data<<4) & 0xF0 | 0x08);
I2C_tx(bitmask |= (1<<E));
_delay_ms(1);
I2C_tx(bitmask &= ~(1<<E));
I2C_stop();
}
uint8_t BF(void)
{
I2C_start(LCDadd_WR);
I2C_tx(bitmask &= ~(1<<RS));
I2C_tx(bitmask |= (1<<RW));
I2C_stop();
I2C_start(LCDadd_RD);
I2C_rx();
while (!(TWDR == (bitmask & (bitmask<<3))));
I2C_stop();
I2C_start(LCDadd_WR);
I2C_tx(bitmask |= (1<<RS));
_delay_ms(500);
I2C_tx(bitmask &= ~(1<<RS));
_delay_ms(500);
I2C_stop();
}
void move_cursor (uint8_t row, uint8_t col)
{
if (row==1)
sendCMD(0x80+col);
if (row==2)
sendCMD(0xC0+col);
}
void LCD_string(uint8_t arr1[])
{
uint8_t cnt=0;
for (i=0;i<29;i++)
{
sendData(arr1[i]);
_delay_ms(500);
cnt++;
if (cnt==16)
sendCMD(0xC0);
}
sendData(0x10);
}
///////////////////////////////////////////////////
///////////////////////////////////////////////////
void I2C_init(void)
{
//set SCL to 100kHz
TWSR = 0x00;
TWBR = 0x48;
//enable TWI
TWCR = (1<<TWEN);
}
void I2C_start(uint8_t address)
{
TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN);
while (!(TWCR & (1<<TWINT)));
TWDR = address;
TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWEA);
while (!(TWCR & (1<<TWINT)));
}
void I2C_stop(void)
{
TWCR = (1<<TWINT)|(1<<TWSTO)|(1<<TWEN);
}
void I2C_tx(uint8_t data)
{
TWDR = data;
TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWEA);
while (!(TWCR & (1<<TWINT)));
}
uint8_t I2C_rx(void)
{
TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWEA);
while (!(TWCR & (1<<TWINT)));
return TWDR;
}