/*
* Filename : i2c.c
* Hardware : Controller -> PIC16F84A
* XTAL -> 4 MHz
* I/O : SDA -> RA1
* SCL -> RA2
* Compiler : PICC
* Author : Babar Ali
* Date : November 09, 2011
*/
#include "pic.h"
#include "i2c.h"
#include "delay.h"
#define SDA_dir TRISA0 /* Set P2.7 = SDA */
#define SCL_dir TRISA1 /* Set P2.7 = SDA */
#define SDA RA0 /* Set P2.7 = SDA */
#define SCL RA1 /* Set P2.6 = SCL */
void I2C_start(void)
{
SDA_dir = 1; /* Set SDA */
DlyuS(5);
SCL_dir = 1; /* Set SCL */
DlyuS(10);
SDA_dir = 0; /* clear SDA */
DlyuS(5);
SCL_dir = 0; /* clear SCL */
DlyuS(5);
}
void I2C_stop(void)
{
SDA_dir = 0; /* clear SDA */
DlyuS(5);
SCL_dir = 1; /* Set SCL */
DlyuS(5);
SDA_dir = 1; /* Set SDA */
DlyuS(5);
}
bit I2C_write(unsigned char dat)
{
static bit wr_bit;
unsigned char i;
SDA_dir =0; //set as output
for(i=8; i; i--)
{
if(dat&0x80)
SDA_dir = 1;
else SDA_dir = 0;
SCL_dir = 1;
dat <<= 1;
SCL_dir = 0;
}
SDA_dir = 1;
SCL_dir = 1;
DlyuS(5);
wr_bit=SDA; // possible ACK bit
SCL_dir = 0;
return wr_bit;
}
unsigned char I2C_read(char ack)
{
char dat=0x00,i;
SDA_dir=1;
DlyuS(5);
for(i=0;i<8;i++) /* For loop read data 1 byte */
{
dat <<= 1;
do {
SCL_dir = 1;
}while(SCL==0); // wait for any SCL clock stretching
DlyuS(5);
if(SDA)
dat |= 1;
SCL_dir = 0;
}
if(ack)
SDA_dir = 0;
else
SDA_dir = 1;
SCL_dir = 1;
DlyuS(5); // send (N)ACK bit
SCL_dir = 0;
SDA_dir = 1;
return dat;
}