Attiny45 I2C PCF8574 LCD














code :
//#define PCF8574A_ID 0x70  //01110000 :000 slave address
#define PCF8574_ID 0x40   //01000000 :000 slave address
// Arduino Pins
#define SDA   0                         // i2c Serial data
#define SCL   1                         // i2c Serial clock


#define ATcommand 0x20                  //LCD command   EN=1 ; RS=0       0010  0000
#define ATdata 0x30                     //LCD data      EN=1 ; RS=1       0011  0000
                                        //    port PCF8574t                 P7-P0
//pinout lcd   1    2    3    4    5    6    7    8    9    10   11   12   13   14   15   16
//more         GND  VCC  R0   RS   RW   EN   D0   D1   D2   D3   D4   D5   D6   D7   A+   K-
//pcf8574t     GND  VCC  VR   P4   GND  P5   P0   P1   P2   P3   GND  GND  GND  GND  GND  VCC 


/*#define ATcommand 0x10                  //LCD command   EN=1 ; RS=0       0001  0000
#define ATdata 0x50                     //LCD data      EN=1 ; RS=1       0101  0000
                                        //    port PCF8574t                 P7-P0
//pinout lcd   1    2    3    4    5    6    7    8    9    10   11   12   13   14   15   16
//more         GND  VCC  R0   RS   RW   EN   D0   D1   D2   D3   D4   D5   D6   D7   A+   K-
//pcf8574t     GND  VCC  VR   P6   P5   P4   P0   P1   P2   P3   GND  GND  GND  GND  GND  VCC */

void i2c_start(void);
void i2c_stop(void);
void i2c_write(unsigned char output_data);
void PCF8574A_Write(unsigned char data);
void i2c_write_bit(int data_bit);
//------------------------- library I2C ----------------------
void i2c_start(void)
{
  digitalWrite(SDA, LOW);
  delayMicroseconds(1);
  digitalWrite(SCL, LOW);
  delayMicroseconds(1);
}
void i2c_acknowledge(void)
{
  digitalWrite(SDA, LOW);
  delayMicroseconds(1);
  digitalWrite(SCL, HIGH);
  delayMicroseconds(1);
  digitalWrite(SCL, LOW);
  delayMicroseconds(1);
  digitalWrite(SDA, LOW);
  delayMicroseconds(1);
}
void i2c_stop(void)
{
  digitalWrite(SCL, HIGH);
  delayMicroseconds(1);
  digitalWrite(SDA, HIGH);
}
void i2c_write(unsigned char output_data)
{
  int iBit=0;
  for(int iloop = 0 ; iloop < 8 ; iloop++)
  {
    iBit = ((output_data & 0x80) >> 7 ) ; 
    delayMicroseconds(1);
    digitalWrite(SDA,iBit);
    delayMicroseconds(1);
    digitalWrite(SCL, HIGH);
    delayMicroseconds(1);
    digitalWrite(SCL, LOW);
    delayMicroseconds(1);
    digitalWrite(SDA, LOW);
    output_data = output_data << 1 ;
  }
  delayMicroseconds(1);
}
void PCF8574_Write(unsigned char data)
{
  i2c_start();              //         |-[S]-|  ;Start Condition
  i2c_write(PCF8574_ID);    //         |---Slave address (PCF8574)--[A2=0,A1=0,A0=0]---|   +    |-R/W-|
  i2c_acknowledge();        //         |-[A]-|  ;Active LOW 
  i2c_write(data);          //         |-------------------data to port-----------------------|
  i2c_acknowledge();        //         |-[A]-|  ;Active LOW 
  i2c_stop();               //         |-[P]-|  ;Stop Condition
}
//-------------------end library I2C --------------------------

//---------------------LCD library ----------------------------
void Write_LCD_Byte(char command_data ,int value) //bool lcd_command ,
{
  int iMSB=0;
  int iLSB=0;
  iMSB = (value & 0xF0)>>4;
  iLSB = (value & 0x0F);
  
  PCF8574_Write(command_data|iMSB);//0xFF
  delayMicroseconds(1);
  PCF8574_Write(0x00|iMSB);
  
  PCF8574_Write(command_data|iLSB);
  delayMicroseconds(1);
  PCF8574_Write(0x00|iLSB);
}
void initial_LCD(void)
{
 delay(50);//ให้รออย่างน้อย 15ms
  PCF8574_Write(0x00);//ให้ขา E = 0 ให้ขา RS= 0 กำหนดเป็นคำสั่ง ให้ขา R/W = 0 เขียนข้อมูล
  delay(50);
  //ส่งข้อมูลค่ำสั่ง Function Set 3 ครั้ง ข้อมูล D4-D7 จะถูกส่งไปที่ bus
  PCF8574_Write(0x23);      //1    0x20 + 0x03   
  delayMicroseconds(1);
  PCF8574_Write(0x03);
  delay(5);                //wait 4ms
  PCF8574_Write(0x23);     //2
  delayMicroseconds(1);
  PCF8574_Write(0x03);
  delayMicroseconds(100);  //wait 100us
  PCF8574_Write(0x23);     //3
  delayMicroseconds(1);
  PCF8574_Write(0x03);
  //end
  //กำหนดการทำงานของ LCD ให้เป็น 4 bit 0010xxxx
  PCF8574_Write(0x22);//Function Set (BIT5=1) [001DNF00 ],Sets buss size 4bit (D=0)ข้อมูลเฉพาะ D4-D7 จะถูกส่งออกไปที่บัส
  delayMicroseconds(1);
  PCF8574_Write(0x02);
  //end เมื่อเป็น 4 bit ต้องส่งข้อมูลคำสั่งสองครั้งๆ ละ 4 bit
  //Function Set (BIT5=1)  0x28 กำหนด ขนาดข้อมูล,จำนวนบรรทัด, ขนาดตัวอักษร
  Write_LCD_Byte(ATcommand,0x28);// 00101000 : [001DNF00 ],Sets buss size 4bit (D=0),number of lines=2 (N=1),font size =5x7(F=0)
  //Display/Cursor (BIT3=1)  0x0C กำหนดการแสดงผล, เคอร์เซอร์
  Write_LCD_Byte(ATcommand,0x0C);//00001100 : [00001DUB] ,Display On (D=1),Cursor Off (U=0) ,blinking block cursor Off (B=0)
  //Entry Mode Set (BIT2=1) 0x06 โหมดการป้อนข้อมูล 
  Write_LCD_Byte(ATcommand,0x06);//00000110 : [000001MS] , Cursor direction right (M=1);no scroll (S=0)
  //0x01 clear screen
  Write_LCD_Byte(ATcommand,0x01);
  //0x0F cursor on
  //Write_LCD_Byte(ATcommand,0x0F); 
}
//--------------------------end LCD library---------------------

void setup() 
  pinMode(SCL, OUTPUT);
  pinMode(SDA, OUTPUT);
  digitalWrite(SDA, HIGH);
  digitalWrite(SCL, HIGH);
  initial_LCD();
}
void loop()
{    
  Write_LCD_Byte(ATcommand,0x80|0x00);// line 1 เริ่มตำแหน่ง 00
  for(int icount = 0 ; icount < 16 ; icount ++)
  {
    Write_LCD_Byte(ATdata,0x41+icount);
    delay(200);
  }
  delay(500);
  // line 2 เริ่มตำแหน่ง 00
  Write_LCD_Byte(ATcommand,0x80|0x40);// line 2 เริ่มตำแหน่ง 00
  Write_LCD_Byte(ATdata,'B');
  Write_LCD_Byte(ATdata,'r');
  Write_LCD_Byte(ATdata,'o');
  Write_LCD_Byte(ATdata,'g');
  Write_LCD_Byte(ATdata,'i');
  Write_LCD_Byte(ATdata,'l');
  Write_LCD_Byte(ATdata,'e');
  Write_LCD_Byte(ATdata,'E');
  Write_LCD_Byte(ATdata,'l');
  Write_LCD_Byte(ATdata,'e');
  Write_LCD_Byte(ATdata,'c');
  Write_LCD_Byte(ATdata,'t');
  Write_LCD_Byte(ATdata,'o');
  Write_LCD_Byte(ATdata,'d');
  Write_LCD_Byte(ATdata,'a');
  Write_LCD_Byte(ATdata,'y');
  delay(2000);
  Write_LCD_Byte(ATcommand,0x01);
}