#include <htc.h>
#include<string.h>
#define _XTAL_FREQ 20000000
#define LCD_DATA PORTD
#define RS PORTBbits.RB0
#define RW PORTBbits.RB2
#define EN PORTBbits.RB1
//Function Prototype
void lcd_init();
void lcdcmd(unsigned char value);
void lcddata(unsigned char value);
void lcdstr(unsigned char msg[]);
void i2c_init();
void i2c_start(void);
void i2c_Ack();
void i2c_Nack();
void i2c_restart(void);
void i2c_stop(void);
void i2c_wait(void);
void i2c_send(unsigned char dat);
unsigned char rtc1307_read(unsigned char address);
unsigned char i2c_read(void);
unsigned char BCD2UpperCh(unsigned char bcd);
unsigned char BCD2LowerCh(unsigned char bcd);
unsigned char sec,min,hour;
unsigned char flag = 0;
void main()
{
TRISB = 0x00;
TRISC = 0xFF;
TRISD = 0x00;
lcd_init();
lcdcmd(0x80);
__delay_ms(10);
lcdstr("RTC Test");
i2c_init(); //To Generate the Clock of 100Khz
i2c_start();
i2c_send(0xD0);
i2c_send(0x00);
i2c_send(0x80); //CH = 1 Stop oscillator
i2c_send(0x05);
i2c_send(0x06);
i2c_send(0x01); //Sunday
i2c_send(0x01); //1Date
i2c_send(0x01); //1 Jan
i2c_send(0x12); //2012
i2c_stop();
//Have to start the Clock again
i2c_start();
i2c_send(0xD0);
i2c_send(0x00);
i2c_send(0x00); //start Clock
i2c_stop();
while(1)
{
i2c_start();
i2c_stop();
lcdcmd(0x01);
sec = rtc1307_read(0x00);
/*min = rtc1307_read(0x01);
__delay_ms(1);
hour = rtc1307_read(0x02);
__delay_ms(1);
lcdstr("Time:");
lcddata(BCD2UpperCh(hour));
lcddata(BCD2LowerCh(hour));
lcddata(':');
lcddata(BCD2UpperCh(min));
lcddata(BCD2LowerCh(min));
lcddata(':');*/
lcddata(BCD2UpperCh(sec));
lcddata(BCD2LowerCh(sec));
__delay_ms(100);
}
}
//Fnction Definition
void lcd_init()
{
lcdcmd(0x38);
__delay_ms(1);
lcdcmd(0x0E);
__delay_ms(1);
lcdcmd(0x0C);
__delay_ms(1);
}
void lcdcmd(unsigned char value)
{
LCD_DATA = value;
RS = 0;
RW = 0;
EN = 1;
__delay_ms(1);
EN = 0;
}
void lcddata(unsigned char value)
{
LCD_DATA = value;
RS = 1;
RW = 0;
EN = 1;
__delay_ms(1);
EN = 0;
}
void lcdstr(unsigned char msg[])
{
unsigned int i,len;
len = strlen(msg);
for(i=0;i<len;i++)
{
lcddata(msg[i]);
__delay_ms(1);
}
}
void i2c_init()
{
TRISC3 = 1;
TRISC4 = 1;
SSPSTAT |= 0x80; //Slew Rate Disabled
SSPADD = 49;
SSPCON=0b00101000; //Master mode
SSPADD = 49;
/*SSPEN = 1
Enables the Serial Port and configures the SDA and SCL
Pins as the Serial Pins
SSPM3:SSPM0 --> 1000
I2C Master Mode
Clock = Fosc/4*(SSPADD+1)
*/
}
void i2c_start(void)
{
SEN = 1;
//SSPCON2 bit 0
while (SEN == 1)
continue;
//SEN =1 initiate the Start Condition on SDA and SCL Pins
//Automatically Cleared by Hardwre
// 0 for Idle State
}
void i2c_restart(void)
{
RSEN = 1;
//SSPCON2 bit 1
while (RSEN == 1)
continue;
//RSEN = 1 initiate the Restart Condition
//Automatically Cleared by Hardware
}
void i2c_stop(void)
{
PEN=1;
while(PEN==1)
continue;
}
void i2c_wait(void)
{
while( R_W == 1)
continue;
if(ACKSTAT == 1)
{
i2c_stop();
}
//If ACKSTAT bit is 0 Acknowledgment Received Successfully
//Otherwise Not
}
void i2c_send(unsigned char dat)
{
SSPBUF = dat; /* Move data to SSPBUF */
while(BF); /* wait till complete data is sent from buffer */
i2c_wait(); /* wait for any pending transfer */
}
unsigned char i2c_read(void)
{
unsigned char temp;
RCEN = 1; /* Enable data reception */
while(!BF); /* wait for buffer full */
temp = SSPBUF; /* Read serial buffer and store in temp register */
i2c_wait(); /* wait to check any pending transfer */
return temp; /* Return the read data from bus */
}
unsigned char BCD2UpperCh(unsigned char bcd)
{
unsigned char temp;
temp = bcd >> 4;
temp = temp | 0x30;
return(temp);
}
unsigned char BCD2LowerCh(unsigned char bcd)
{
unsigned char temp;
temp = bcd & 0x0F; //Making the Upper 4-bits
temp = temp | 0x30;
return(temp);
}
unsigned char rtc1307_read(unsigned char address)
{
unsigned char temp1;
i2c_start();
i2c_send(0xD0);
i2c_send(address);
i2c_restart();
i2c_send(0xD1);
temp1 = i2c_read();
i2c_stop();
return temp1;
}
void i2c_Ack()
{
ACKDT = 0; //Acknowledge Data Bit, 0 = Ack
ACKEN = 1; //Acknowledge Enable Bit
while(ACKEN);
//Wait for ack bit to send on bus
}
void i2c_Nack()
{
ACKDT = 1;
ACKEN = 1; //Acknowledge Enable Bit
while(ACKEN);
}