#include <reg51.h>
#define lcddata P1
sbit SDA= P0^0;
sbit SCL= P0^1;
sbit RS = P2^0;
sbit RW = P2^1;
sbit EN = P2^2;
sbit BSY = P1^7;
static void I2CInit()
{
SDA = 1;
SCL = 1;
}
//I2c start
static void I2CStart()
{
SCL = 1;
SDA = 0;
SCL = 0;
}
static void I2CStop()
{
SDA = 0;
SCL = 1;
SDA = 1;
}
static void I2CAck()
{
SDA = 0;
SCL = 1;
SCL = 0;
}
static void I2CNak()
{
SDA = 1;
SCL = 1;
SCL = 0;
}
static void I2CRestart(){
SDA = 1;
SCL = 1;
SDA = 0;
}
/* routine to send data on the bus */
static unsigned char I2CSend(unsigned char Data)
{
unsigned char i, ack_bit;
for(i=0;i<8;i++)
{
SCL = 0;
if ((Data & 0x80) == 0)
SDA = 0;
else
SDA = 1;
SCL = 1;
Data<<=1;
}
SCL = 0;
ack_bit = SDA;
SCL = 1;
SCL = 0;
return !ack_bit;
}
/* routine to read the data out of the bus */
static unsigned char I2CRead()
{
unsigned char i, Data=0;
for(i=0;i<8;i++)
{
SCL = 0;
SCL = 1;
if(SDA)
Data |=1;
if(i<7)
Data<<=1;
}
SCL = 0;
SDA = 1;
return Data;
}
static void delay(unsigned int);
static void lcd_ready()
{
//make BSY pin as input
BSY=1;
//Read out from register
RS=0;
//Read
RW=1;
while(BSY==1)
{
EN=0;
delay(1);
EN=1;
}
}
// delay function
static void delay(unsigned int tme)
{
unsigned int i,j;
for(i=0;i<tme;i++)
for(j=0;j<1275;j++);
}
/* code for sending command to the lcd */
static void lcd_cmd(unsigned char val)
{
//check for busy flag
lcd_ready();
lcddata=val;
RS=0;
RW=0;
EN=1;
delay(2);
EN=0;
}
static void lcd_init()
{
//16x2 lcd
lcd_cmd(0x38);
//clear lcd
lcd_cmd(0x01);
//force the cursor to line 1
lcd_cmd(0x80);
//display on cursor blinking
lcd_cmd(0x0E);
}
/* fucntion for transmitting data to the lcd */
static void lcd_data(unsigned char datum)
{
lcd_ready();
lcddata=datum;
RS=1;
RW=0;
EN=1;
delay(1);
EN=0;
}
/* code for BCD to ASCII */
static void bcdconv(unsigned char datum)
{
unsigned char x=0,y=0;
x=datum&0x0f;
x=x|0x30;
y=datum&0xf0;
y=y>>4;
y=y|0x30;
lcd_data(y);
lcd_data(x);
}
/* main code */
void main()
{
unsigned char i, a[7];
unsigned int j;
I2CInit();
lcd_init();
/* Writing on i2c */
I2CStart();
I2CSend(0xD0);
/* first register */
I2CSend(0x00);
/* seconds */
I2CSend(0x59);
/* minutes */
I2CSend(0x23);
/*12-hour mode : need to tick from 3:23 PM */
I2CSend(0x63);
I2CStop();
while(1)
{
I2CStart();
I2CSend(0xD0);
I2CSend(0x00);
/* Actual read */
I2CRestart();
I2CSend(0xD1);
for(i=0;i<3;i++)
{
a[i]=I2CRead();
if(i==2)
I2CNak();
else
I2CAck();
}
I2CStop();
lcd_cmd(0x81);
bcdconv(a[2]);
lcd_data(':');
bcdconv(a[1]);
lcd_data(':');
bcdconv(a[0]);
for(j=65535;j>0;j--);
}
}