ta_i2c

//Khai báo sử dụng I2C

//đã test chuẩn trên TME_PICKIT với mặc định sử dụng C3 và C4 như theo phần cứng của 16F887

//chưa test trên các chip PIC khác

#bit TRISC4   =0x87.4

#bit TRISC3   =0x87.3

 

#define PIN_SCL PIN_C3

#define PIN_SDA PIN_C4

#define TRIS_SCL TRISC3

#define TRIS_SDA TRISC4

//

//DO NOT MODIFICATION STARTS FROM THIS LINE

//------------------------

//cac dinh nghia tien xu ly

//phan nay su dung cho code và khong duoc thay doi

#define SDA_IN {TRIS_SDA=1;}

#define SDA_OUT   {TRIS_SDA=0;}

#define SCL_0  output_low(PIN_SCL)

#define SCL_1  output_high(PIN_SCL)

#define SDA_0  output_low(PIN_SDA)

#define SDA_1  output_high(PIN_SDA)

#define CHK_SDA  input(PIN_SDA)//input_state

#define i2c_delay delay_us(1)

//

 

void i2c_int();

void i2c_start();

void i2c_stop();

unsigned int i2c_read(unsigned int ack);

unsigned int i2c_write(unsigned int data);

//------------------

 

void i2c_init()

{

   TRIS_SCL=0;//allway out

   SDA_OUT;

   SCL_1; 

   SDA_1;

}

void i2c_start()

{   

   SCL_1;

   SDA_1;

   i2c_delay;

   SDA_0;

   i2c_delay;

   SCL_0;

   i2c_delay;

}

 

void i2c_stop()

{

   SDA_0;

   SCL_0;

   i2c_delay;

   

   SCL_1;

   i2c_delay;

   SDA_1;

   i2c_delay;

}

//

unsigned int i2c_read(unsigned int ack)

{

   int8 i,data;   

   SDA_IN;

   SDA_1;

   for (i=0; i<8;i++){

      data<<=1;

      

      SCL_0;

      i2c_delay;

      

      SCL_1;//clock pull

      while(input_state(PIN_SCL)==0){;} //while for SCL=1

      

      if(CHK_SDA==1){data|=1;}

      

      i2c_delay;

   }

   SCL_0;

   

   //SDA_OUT;// 

   if(ack) SDA_0; //ACK

   else SDA_1;    //NACK

   

   i2c_delay;

   SCL_1;

   i2c_delay;

   SCL_0;

   

   return data;

}

 

unsigned int i2c_write(unsigned int data)

{

   unsigned int ret=0, i;

   SDA_OUT;

   

   for(i=0;i<8;i++){ 

      SCL_0; 

      i2c_delay;

   // truyền từ bit cao đến thấp

      if(data & 0x80) SDA_1;

      else SDA_0;

      data<<=1;

      SCL_1;

      i2c_delay;

      

   }

   //get ACK

   SCL_0;

   SDA_1;

   i2c_delay;

   SDA_IN;//PIN_SDA is input

   SCL_1;

   

   ret= CHK_SDA;

   i2c_delay;

   

   SDA_OUT;

   

   SCL_0;

   

   return ret;

}