The PCF8583 Real Time Clock & PIC16F877A project on the PIC-01 Development Board.

30 April, 2007 (09:39) | Microchip PIC, Projects | By: glogin

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)

Bad Behavior has blocked 58 access attempts in the last 7 days.