The PCF8583 Real Time Clock & PIC16F877A project on the PIC-01 Development Board.
This example shows how to realize the Real Time Clock (RTC) using the PCF8583 and PIC16F877A. The ciruit was assembled using solderless breadboard of the PIC-01 Development Board by Loginway. The chip was programmed using the CCS C compiler.
The project uses typical PCF8583 application. Because on the PIC-01 Development Board there is already an I2C device (an I2C EEPROM memory with the address set to A0A1A2=000), the A0 pin has been set high.
The PCF8583.h library contains three functions:
init_PCF8583();write_PCF8583(BYTE address, BYTE data);read_PCF8583(BYTE address);
//--------------------------------------------------------
// Library for a pcf8583p - RTC/Calendar with 240x8bit RAM
// and I2C interface
// Pin Layout:
// |
// | 1: OSCI Oscillator input | 8: VCC +5V |
// |
// | 2: OSCO OScillator output| 7: !INT Interruption output |
// |
// | 3: A0 I2C Address | 6: SCL EEPROM_SCL and Pull-Up |
// |
// | 4: VSS GND | 5: SDA EEPROM_SDA and Pull-Up |
// ------------------------------------------------
//
// PCF8583p Slave I2C Address
//
// 1 0 1 0 0 0 A0 R/!W
//
//--------Pin definition--------//
#define PCF8583_SDA PIN_C4
#define PCF8583_SCL PIN_C3 #define PCF8583_WRITE_ADDRESS 0xA2 //Pin A0 High
#define PCF8583_READ_ADDRESS 0xA3 #ifndef PCF8583_WRITE_ADDRESS
#define PCF8583_WRITE_ADDRESS 0xA0 //Pin A0 Low
#define PCF8583_READ_ADDRESS 0xA1
#endif #use i2c(master, sda=PCF8583_SDA, scl=PCF8583_SCL)void init_PCF8583() {
output_float(PCF8583_SCL);
output_float(PCF8583_SDA);
}BOOLEAN PCF8583_ready() {
int1 ack;
i2c_start();
ack = i2c_write(PCF8583_WRITE_ADDRESS);
i2c_stop();
return !ack;
}void write_PCF8583(BYTE address, BYTE data) {
while(!PCF8583_ready());
i2c_start();
i2c_write(PCF8583_WRITE_ADDRESS);
i2c_write(address);
i2c_write(data);
i2c_stop();
}BYTE read_PCF8583(BYTE address) {
BYTE data;while(!PCF8583_ready());
i2c_start();
i2c_write(PCF8583_WRITE_ADDRESS);
i2c_write(address);
i2c_start();
i2c_write(PCF8583_READ_ADDRESS);
data=i2c_read(0);
i2c_stop();
return(data);
}
The rtc.c listing shows has to read date and time from the PCF8583.
//-------------------------------
// rtc.c
// pcf8583p RTC #include<16f877a.h> //Device
#use delay (clock=4000000) //4.00 MHz#include"lcd_new.h" //LCD driver
#fuses xt,nowdt,protect,noput,nolvp //Fuses #include<pcf8583.h>
byte sec,min,hour,year,month,day,weekday;char const weekday_names[7][4] =
{
{"Sun"},
{"Mon"},
{"Tue"},
{"Wed"},
{"Thu"},
{"Fri"},
{"Sat"}
};void main(void)
{
lcd_init(); //lcd start
lcd_init_custom_chars();init_PCF8583();while(TRUE)
{
delay_ms(100);
lcd_gotoxy(1,1);
weekday=read_PCF8583(0x06);
weekday>>=5;
printf(lcd_putc,"%s",weekday_names[weekday]);
day=read_PCF8583(0x05);
printf(lcd_putc," %x/",day&0x3f);
month=read_PCF8583(0x06);
printf(lcd_putc,"%x/",month&0x1f);
year=read_PCF8583(0x05);
printf(lcd_putc,"20%x",year&0xc0);
hour=read_PCF8583(0x04);
printf(lcd_putc,"\n%x:",hour);
min=read_PCF8583(0x03);
printf(lcd_putc,"%x:",min);
sec=read_PCF8583(0x02);
printf(lcd_putc,"%x",sec);
}
}
For further development, it would be sensible to include set_time() and set_date() functions and using interrupts.
All files available here:
rtc.c (.zip)
rtc.hex (.zip)
PCF8583.h (.zip)