#include<xc.h>
void delayUs(int x)
{
x>>= 5;
while(x--); // delay Usv ( aprox...)
}
void delayMs(int x)
{
while(x--)
delayUs(1000); // delay Ms
}
void InitI2C()
{
TRISC3=1;
TRISC4=1;
SSPCON=0b00101000;
SSPCON2=0;
SSPSTAT=0b10000000;
SSPADD=50; //20000/(4*100); //Fosc/(4*baud)
SSPIF=0;
BCLIF=0;
}
//Wait for the module to finish it's last action.
void WaitSSP()
{
while(SSPIF==0);
SSPIF=0;
}
//send start bit
void SendStart()
{
SEN=1;
WaitSSP();
}
//Send stop bit.
void SendStop()
{
PEN=1;
WaitSSP();
}
//Send restart bit
void SendRestart()
{
RSEN=1;
WaitSSP();
}
//Send byte and return ack bit - 1=Ack 0=NAck
char SendByte(char Byte)
{
SSPBUF=Byte;
WaitSSP();
return(!ACKSTAT);
}
//Get a byte from the slave
char ReceiveByte()
{
RCEN=1; // get byte
WaitSSP();
return(SSPBUF);
}
//Send a Not Acknowledge (NAck) to the slave
void SendNack()
{
ACKDT=1; // Not Acknowledge
ACKEN=1;
WaitSSP();
}
//Send an Acknowledge (Ack) to the slave
void SendAck()
{
ACKDT=0; // Acknowledge
ACKEN=1;
WaitSSP();
}
//Sends the start and device address.
//If the device is busy then it resends until accepted.
void SendID(char DeviceID)
{
SendStart();
if(SendByte(DeviceID)==1) // Send ID until accepted..
return;
do
{
SendRestart();
}while(SendByte(DeviceID)==0);
}
//Write a byte to The RTC
char WriteRTC(char Address, char Byte)
{
SendID(0b11010000); // Send 0xD0
if(SendByte(Address&0xff)==0) // Send address
return(0);
if(SendByte(Byte)==0) // Send byte
return(0);
SendStop(); // All done
return(1);
}
//Read a byte from the RTC
char ReadRTC(char Address)
{
char Byte;
SendID(0b11010000); // Send 0xD0
if(SendByte(Address&0xff)==0) // Send address
return(0);
SendRestart(); // Re-start
if(SendByte(0b11010001)==0) // Read 0xD1
return(0);
Byte=ReceiveByte(); // Get byte
SendNack(); // No more
SendStop(); // Stop bus
return(Byte); // All done
}
void WriteClock(char *array) // Not used
{
char x;
int tmp;
for(x=0;x<7;x++)
{
tmp = array[x] / 10;
tmp << = 4;
tmp += array[x] % 16;
WriteRTC(x,tmp);
}
}
void ReadClock(char *array)
{
char x;
for(x=0;x<7;x++)
array[x] = ReadRTC(x); // No need to BCD-BIN
}
unsigned char Time[7];
unsigned char DISP[6];
unsigned char digits[] = {0x3f,0x6,0x5b,0x4f,0x66,0x6d,0x7d,0x7,0x7f,0x6f};
void main(void)
{
int idx, SCL; // loop variables
unsigned char DIGIT; // A temporary store for manipulation
TRISC = 0; // portc tris bits
TRISD = 0; // portd tris bits
InitI2C(); // prepare the RTC bus
RC0 = 1; // MR high
RC1 = 0; // OE low
while(1)
{
ReadClock(&Time[0]); // Get time ( BCD format as
delayMs(250); // we are using 7 seg )
DISP[5] = Time[2]>>4; DISP[4] = Time[2] & 0xf; // fill display buffer
DISP[3] = Time[1]>>4; DISP[2] = Time[1] & 0xf; // backwards so it's
DISP[1] = Time[0]>>4; DISP[0] = Time[0] & 0xf; // readable...
for(idx = 0;idx < 6;idx++)
{
DIGIT = digits[DISP[idx]]; // retrive 7 seg code
for(SCL = 0; SCL < 8; SCL++) // 8 clocks
{
RD2 = 1; // No data ( swap for CC )
if(DIGIT & 0x80)RD2 = 0; // Data to send?? ( swap for CC )
DIGIT<<=1;
RD0 = 1; // data clock
NOP();
RD0 = 0;
}
}
RD1 = 1; // Latch clock..
NOP();
RD1 = 0;
}
}