#include <htc.h>
#define _XTAL_FREQ 4000000 // 4 MHz clock
__CONFIG(0X3F39);
#define LCD_EN RB0
#define LCD_RS RB1
#define LCD_RW RB4
#define LCD_DATA PORTD
#define LCD_STROBE LCD_EN = 1; __delay_ms(1); LCD_EN=0;
unsigned char time [6] = {"Time:"};
unsigned char date [6] = {"Date:"};
unsigned char I2CData[]= {0x00,0x01,0x40,0x03,0x04,0x05,0x06,0x07};
unsigned I2CInitval []= {0x57,0x59,0x8,0x29,0x29,0x20,0x12,0x20};
unsigned char tmp;
unsigned char i;
void I2CWait(){
while ( ( SSPCON2 & 0x1F ) || ( SSPSTAT & 0x04 ) ); /* wait for any pending transfer */
}
void I2CInit(void){
TRISC3 = 1; /* SDA and SCL as input pin */
TRISC4 = 1; /* these pins can be configured either i/p or o/p */
SSPSTAT |= 0x80; /* Slew rate disabled */
SSPCON = 0x28; /* SSPEN = 1, I2C Master mode, clock = FOSC/(4 * (SSPADD + 1)) */
SSPADD = 0x28; /* 100Khz @ 4Mhz Fosc */
}
void I2CStart(){
I2CWait();
SEN = 1;
while(SEN);
}
void I2CStop(){
PEN = 1; /* Stop condition enabled */
while(PEN); /* Wait for stop condition to finish */
/* PEN automatically cleared by hardware */
}
void I2CRestart(){
RSEN = 1; /* Repeated start enabled */
while(RSEN); /* wait for condition to finish */
}
void I2CAck(){
ACKDT = 0; /* Acknowledge data bit, 0 = ACK */
ACKEN = 1; /* Ack data enabled */
while(ACKEN); /* wait for ack data to send on bus */
}
void I2CNak(){
ACKDT = 1; /* Acknowledge data bit, 1 = NAK */
ACKEN = 1; /* Ack data enabled */
while(ACKEN); /* wait for ack data to send on bus */
}
void I2CSend(unsigned char dat){
SSPBUF = dat; /* Move data to SSPBUF */
while(BF); /* wait till complete data is sent from buffer */
I2CWait(); /* wait for any pending transfer */
}
unsigned char I2CRead(void){
unsigned char temp;
I2CWait(); /* Reception works if transfer is initiated in read mode */
RCEN = 1; /* Enable data reception */
while(!BF); /* wait for buffer full */
temp = SSPBUF; /* Read serial buffer and store in temp register */
/* wait to check any pending transfer */
}
void lcddata(unsigned char value)
{
LCD_RS = 1;
LCD_DATA= (value&0xf0);
LCD_STROBE;
LCD_DATA = ((value<<4)&0xf0);
LCD_STROBE;
__delay_ms(10);
}
void lcdcmd(unsigned char value)
{
LCD_RS = 0;
LCD_DATA= (value&0xf0);
LCD_STROBE;
LCD_DATA = ((value<<4)&0xf0);
LCD_STROBE;
__delay_ms(10);
}
void bcdToascii(unsigned char value){
tmp = value;
tmp = tmp & 0xf0;
tmp = tmp >> 4;
tmp = tmp | 0x30;
lcddata(tmp);
tmp = value;
tmp = tmp & 0x0f;
tmp = tmp | 0x30;
lcddata(tmp);
}
void display (){
lcdcmd(0x80);
for (char i=0;i<5;i++)
{
lcddata(time[i]);
}
bcdToascii(I2CData[2]);
lcddata('-');
bcdToascii(I2CData[1]);
lcddata('-');
bcdToascii(I2CData[0]);
lcdcmd(0xc0);
for (char j=0;j<5;j++)
{
lcddata(date[j]);
}
bcdToascii(I2CData[3]);
lcddata('-');
bcdToascii(I2CData[4]);
lcddata('-');
bcdToascii(I2CData[5]);
bcdToascii(I2CData[6]);
}
void lcd_init(){
TRISD = 0;
TRISB = 0;
TRISC6 = 0;
TRISC5 = 0;
LCD_EN =0;
__delay_us(10);
LCD_DATA =0X30;
LCD_STROBE;
__delay_ms(2);
LCD_RS=0;
__delay_us(10);
LCD_DATA =0X30;
LCD_STROBE;
__delay_ms(2);
LCD_RS=0;
__delay_us(10);
LCD_DATA =0X30;
LCD_STROBE;
__delay_ms(2);
LCD_RS=0;
__delay_us(10);
LCD_DATA =0X20;
LCD_STROBE;
__delay_ms(2);
lcdcmd(0x28);
__delay_ms(15);
lcdcmd(0x01);
__delay_ms(10);
lcdcmd(0x06);
__delay_ms(10);
lcdcmd(0x80);
__delay_ms(10);
lcdcmd(0x0c);
__delay_ms(10);
}
void I2Cwrite(){
/* Initialize I2C Port */
I2CStart(); /* Send Start condition */
I2CSend(0xD0); /* Send DS1307 slave address with write operation */
I2CSend(0x00); /* Send subaddress 0x00, we are writing to this location */
for(i=0;i<8;i++) { /* Loop to write 8 bytes */
I2CSend(I2CInitval[i]); /* send I2C data one by one */
}
I2CStop(); /* Send a stop condition - as transfer finishes */
}
void I2Cread(){
for(i=0;i<8;i++){
I2CStart();
I2CSend(0xD0); /* Send slave address with write */ /* Send address for dummy write operation *//* this address is actually where we are going to read from */
I2CSend(0x00); /* Send a repeated start, after a dummy write to start reading */
I2CRestart();
I2CSend(0xD1); /* send slave address with read bit set */
// for(i=0;i<8;i++) {
I2CData[i] = I2CRead(); /* read a byte */ /* ACK if its not the last byte to read */
}
I2CStop(); /* Send stop */
}
void main(){
I2CInit();
lcd_init();
I2Cwrite();
while(1){
I2Cread();
display();
}
}