Dallas DS1307 Simple Clock Demo

Discussion on projects that are created by users and posted on mikroElektronika website.
Post Reply
Author
Message
noelrios7
Posts: 10
Joined: 19 Apr 2012 03:52

Dallas DS1307 Simple Clock Demo

#1 Post by noelrios7 » 20 Apr 2012 02:27

Here is a sample code for the Dallas DS1307 Simple Clock Demo using Hardware I2C

Code: Select all

// Simple Real Time clock Example
//MCU : PIC16F877
//Crystal: 4Mhz
//Author: Noel A. Rios

unsigned char seconds;
unsigned char tenseconds;

unsigned char minutes;
unsigned char tenminutes;

unsigned char hours;
unsigned char tenhours;

unsigned char Read_RTC(unsigned char address)
{
    unsigned char buffer;

    I2C_Start();              // issue I2C start signal
    I2C_Wr(0xD0);             // send byte via I2C  (device address + W)
    while (!I2C_Is_Idle())
      asm nop;
    I2C_Wr(address);            // send byte (data address)
    while (!I2C_Is_Idle())
      asm nop;
    I2C_Repeated_Start();     // issue I2C signal repeated start
    I2C_Wr(0xD1);             // send byte (device address + R)
    buffer = I2C_Rd(0u);       // Read the data (NO acknowledge)
    while (!I2C_Is_Idle())
      asm nop;                // Wait for the read cycle to finish
    I2C_Stop();
    Delay_ms(100);
    return(buffer);
}

void main()
{
  Lcd_Config(&PORTD,1,0,2,7,6,5,4);
  Lcd_Init(&PORTD);
  LCD_Cmd(LCD_CLEAR);           // Clear display
  LCD_Cmd(LCD_CURSOR_OFF);      // Turn cursor off
  Delay_ms(1000);
  LCD_Out(1,6,"CLOCK");           // Print text to LCD, 1st row, 1st column
  Delay_ms(1000);
  LCD_Out(2,6,"TEST");        // Print text to LCD, 2nd row, 6th column

  Delay_ms(1000);

  LCD_Cmd(LCD_CLEAR);           // Clear display

  I2C_Init(100000);

  I2C_Start();                 //Initialize DS1307 RTC
  I2C_Wr(0xD0);                //RTC_WRITE_ADDR();
  while (!I2C_Is_Idle())
      asm nop;
  I2C_Wr(0x00);                //Adress
  while (!I2C_Is_Idle())
      asm nop;
  I2C_Wr(0x00);                //Seconds
    while (!I2C_Is_Idle())
      asm nop;
  I2C_Wr(0x00);               //minutes
  while (!I2C_Is_Idle())
      asm nop;
  I2C_Wr(0x00);               //Hours
  while (!I2C_Is_Idle())
      asm nop;

  I2C_Stop();
  Delay_ms(100);
do{
  seconds=Read_RTC(0x00);
  minutes=Read_RTC(0x01);
  hours=Read_RTC(0x02);

  tenseconds=seconds;
  seconds&=0x0F;
  tenseconds>>=4;
  tenseconds&=0x0F;

  tenminutes=minutes;
  minutes&=0x0F;
  tenminutes>>=4;
  tenminutes&=0x0F;

  tenhours=hours;
  hours&=0x0F;
  tenhours>>=4;
  tenhours&=0x0F;

  LCD_Chr(1,7,tenseconds+48);
  LCD_Chr(1,8,seconds+48);
  LCD_Chr(1,6,':');

  LCD_Chr(1,4,tenminutes+48);
  LCD_Chr(1,5,minutes+48);
  LCD_Chr(1,3,':');

  LCD_Chr(1,2,tenhours+48);
  LCD_Chr(1,1,hours+48);
}while(1);
}

noelrios7
Posts: 10
Joined: 19 Apr 2012 03:52

Re: Dallas DS1307 Simple Clock Demo

#2 Post by noelrios7 » 12 Feb 2013 11:27

This is A DS1307 clock Example using a Hardware I2C. For Faster clock Frequencies you need to increase the delay to 500ms

Code: Select all

unsigned char Read_RTC(unsigned char address)
{
unsigned char buffer;

I2C_Start(); // issue I2C start signal
I2C_Wr(0xD0); // send byte via I2C (device address + W)
while (!I2C_Is_Idle())
asm nop;
I2C_Wr(address); // send byte (data address)
while (!I2C_Is_Idle())
asm nop;
I2C_Repeated_Start(); // issue I2C signal repeated start
I2C_Wr(0xD1); // send byte (device address + R)
buffer = I2C_Rd(0u); // Read the data (NO acknowledge)
while (!I2C_Is_Idle())
asm nop; // Wait for the read cycle to finish
I2C_Stop();
Delay_ms(500); <----------- For faster clock frequencies
return(buffer);
}

Mrunal Ahirrao
Posts: 41
Joined: 25 Jun 2012 13:45
Location: India

Re: Dallas DS1307 Simple Clock Demo

#3 Post by Mrunal Ahirrao » 14 Feb 2013 07:27

hi I am also trying to make a timer switch using RTC and I then instead of showing on LCD I created a routine for checking time and if the rtc time matches with the set of this routine then the port's pin is made to logic one! but its not at all working...

Code: Select all

// Software I2C connections
sbit Soft_I2C_Scl           at RB4_bit;
sbit Soft_I2C_Sda           at RB1_bit;
sbit Soft_I2C_Scl_Direction at TRISB4_bit;
sbit Soft_I2C_Sda_Direction at TRISB1_bit;
// End Software I2C connections

// LCD module connections
sbit LCD_RS at RB0_bit;
sbit LCD_EN at RA1_bit;
sbit LCD_D4 at RB2_bit;
sbit LCD_D5 at RB3_bit;
sbit LCD_D6 at RB5_bit;
sbit LCD_D7 at RB6_bit;

sbit LCD_RS_Direction at TRISB0_bit;
sbit LCD_EN_Direction at TRISA1_bit;
sbit LCD_D4_Direction at TRISB2_bit;
sbit LCD_D5_Direction at TRISB3_bit;
sbit LCD_D6_Direction at TRISB5_bit;
sbit LCD_D7_Direction at TRISB6_bit;
// End LCD module connections
sbit Sett at RA2_bit;
sbit Inc at RA3_bit;
sbit Dec at RA4_bit;


/*sbit Filter at RB3_bit;
sbit InSo at RB4_bit;
sbit opmotor at RB5_bit;
sbit Light at RB6_bit;*/



unsigned short read_ds1307(unsigned short address)
{
  unsigned short r_data;
  INTCON.GIE=0;
  Soft_I2C_Start();
  Soft_I2C_Write(0xD0); //address 0x68 followed by direction bit (0 for write, 1 for read) 0x68 followed by 0 --> 0xD0
  Soft_I2C_Write(address);
  Soft_I2C_Start();
  Soft_I2C_Write(0xD1); //0x68 followed by 1 --> 0xD1
  r_data=Soft_I2C_Read(0);
  Soft_I2C_Stop();
  return(r_data);
  INTCON.GIE=1;
}


void write_ds1307(unsigned short address,unsigned short w_data)
{
 INTCON.GIE=0;
 Soft_I2C_Start(); // issue I2C start signal //address 0x68 followed by direction bit (0 for write, 1 for read) 0x68 followed by 0 --> 0xD0
 Soft_I2C_Write(0xD0); // send byte via I2C (device address + W)
 Soft_I2C_Write(address); // send byte (address of DS1307 location)
 Soft_I2C_Write(w_data); // send data (data to be written)
 Soft_I2C_Stop(); // issue I2C stop signal
 INTCON.GIE=1;
}


unsigned char BCD2UpperCh(unsigned char bcd)
{
  return ((bcd >> 4) + '0');
}


unsigned char BCD2LowerCh(unsigned char bcd)
{
  return ((bcd & 0x0F) + '0');
}

/** Bcd2Dec**/

unsigned short Bcd2Dec(unsigned short bcdnum) {
unsigned short tmp = 0;

tmp = (bcdnum >> 4) * 10;
tmp += (bcdnum & 0x0F);
return tmp;
}//

int Binary2BCD(int a)
{
   int t1, t2;
   t1 = a%10;
   t1 = t1 & 0x0F;
   a = a/10;
   t2 = a%10;
   t2 = 0x0F & t2;
   t2 = t2 << 4;
   t2 = 0xF0 & t2;
   t1 = t1 | t2;
   return t1;
}


int BCD2Binary(int a)
{
   int r,t;
   t = a & 0x0F;
   r = t;
   a = 0xF0 & a;
   t = a >> 4;
   t = 0x0F & t;
   r = t*10 + r;
   return r;
}



int second;
int minute;
int hour;
int hr;
int day;
int dday;
int month;
int year;
int ap;

unsigned short set_count = 0;
unsigned short set;
unsigned short i;
unsigned short Dhour;
unsigned short Hcnt;

char time[] = "00:00:00 PM";
char date[] = "00-00-00";

unsigned short Check_time(){
Hcnt=read_ds1307(2);
Dhour=Bcd2Dec(Hcnt);
return Dhour;
}



unsigned short counter;

void interrupt(){

  if (INTCON.T0IF) {
    if (counter >= 20) {
      Soft_I2C_Break();
      counter = 0;              // reset counter
    }
    else
    {
      counter++;                // increment counter

    INTCON.T0IF = 0;            // Clear Timer0 overflow interrupt flag
    }

    }
}


void main()
{
   CMCON = 0x07;   // To turn off comparators
  // ADCON1= 0x06;  // To turn off analog to digital converters
   TRISA = 0b00011100;
   TRISB = 0x00;
   //ANSEL=0;
   OPTION_REG=0x07;
   INTCON=0b10100000;
   PORTB.RB7=0;
   Lcd_Init();                      // Initialize LCD
   Lcd_Cmd(_LCD_CLEAR);               // Clear display
   Lcd_Cmd(_LCD_CURSOR_OFF);          // Cursor off
   Lcd_Out(1,3, "Welcome To");
   Lcd_Out(2,2,"MicroLux India");
   i=0;
  while(i<5){
   delay_ms(300);
   i ++;
  }
   Lcd_Cmd(_LCD_CLEAR);
   Lcd_out(1,1,"Time:");
   Lcd_out(2,1,"Date:");
   Soft_I2C_Init(); // Initialize Soft I2C communication
do{
   set = 0;
     if(Sett == 0)
     {
         Delay_ms(100);
         if(Sett == 0)
         {
             set_count++;
             if(set_count >= 7)
             {
                set_count = 0;
             }

         }
     }
     if(set_count)
     {
        if(Inc == 0)
        {
          Delay_ms(100);
          if(Inc == 0)
              set = 1;
        }

        if(Dec == 0)
        {
          Delay_ms(100);
          if(Dec == 0)
              set = -1;
        }
        if(set_count && set)
        {
          switch(set_count)
          {
            case 1:
                    hour = BCD2Binary(hour);
                    hour = hour + set;
                    hour = Binary2BCD(hour);
                    if((hour & 0x1F) >= 0x13)
                    {
                      hour = hour & 0b11100001;
                      hour = hour ^ 0x20;
                    }
                    else if((hour & 0x1F) <= 0x00)
                    {
                      hour = hour | 0b00010010;
                      hour = hour ^ 0x20;
                    }
                    write_ds1307(2, hour); //write hour
                    break;
            case 2:
                     minute = BCD2Binary(minute);
                     minute = minute + set;
                     if(minute >= 60)
                        minute = 0;
                     if(minute < 0)
                        minute = 59;
                     minute = Binary2BCD(minute);
                     write_ds1307(1, minute); //write min
                     break;
            case 3:
                    if(abs(set))
                      write_ds1307(0,0x00); //Reset second to 0 sec. and start Oscillator
                    break;
            case 4:
                     day = BCD2Binary(day);
                     day = day + set;
                     day = Binary2BCD(day);
                     if(day >= 0x32)
                        day = 1;
                     if(day <= 0)
                        day = 0x31;
                     write_ds1307(4, day); // write date 17
                     break;
            case 5:
                    month = BCD2Binary(month);
                    month = month + set;
                    month = Binary2BCD(month);
                    if(month > 0x12)
                      month = 1;
                    if(month <= 0)
                      month = 0x12;
                    write_ds1307(5,month); // write month 6 June
                    break;
            case 6:
                    year = BCD2Binary(year);
                    year = year + set;
                    year = Binary2BCD(year);
                    if(year <= -1)
                       year = 0x99;
                    if(year >= 0x50)
                       year = 0;
                    write_ds1307(6, year); // write year
                    break;
          }
        }
     }

      second = read_ds1307(0);
      minute = read_ds1307(1);
      hour = read_ds1307(2);
       hr = hour & 0b00011111;
       ap = hour & 0b00100000;
      dday = read_ds1307(3);
      day = read_ds1307(4);
      month = read_ds1307(5);
      year = read_ds1307(6);


      time[0] = BCD2UpperCh(hr);
      time[1] = BCD2LowerCh(hr);
      time[3] = BCD2UpperCh(minute);
      time[4] = BCD2LowerCh(minute);
      time[6] = BCD2UpperCh(second);
      time[7] = BCD2LowerCh(second);

      date[0] = BCD2UpperCh(day);
      date[1] = BCD2LowerCh(day);
      date[3] = BCD2UpperCh(month);
      date[4] = BCD2LowerCh(month);
      date[6] = BCD2UpperCh(year);
      date[7] = BCD2LowerCh(year);

      if(ap)
      {
         time[9] = 'P';
         time[10] = 'M';
      }
      else
      {
         time[9] = 'A';
         time[10] = 'M';
      }


      Lcd_out(1, 6, time);
      Lcd_out(2, 6, date);
       Delay_ms(50);
Check_time();
        if(Dhour==11) check if its 11 o clock
        {
          PORTB.RB7=1; 
        }



   }while(1);
}


will you please help?

User avatar
dejan.odabasic
mikroElektronika team
Posts: 2649
Joined: 30 Apr 2012 14:20

Re: Dallas DS1307 Simple Clock Demo

#4 Post by dejan.odabasic » 18 Feb 2013 12:38

Hello,

@noelrios7:
Thank you for sharing your code with our community.

@Mrunal Ahirrao:
Please understand that custom user code is out of the scope of our technical support.
Maybe some more experienced users will be able to help you.

Best regards.

noelrios7
Posts: 10
Joined: 19 Apr 2012 03:52

Re: Dallas DS1307 Simple Clock Demo

#5 Post by noelrios7 » 17 Sep 2014 12:11

My code uses a Hardware I2C of the Microchip PIC while your's uses a software I2C. Try wiring it using a protoboard and see that it works. If you see it working, try working your code from the posted code. Be aware that you must write to ADCON to turn on the ports to digital if you want to use PORTA as an I/O instead of an Analog Port.

noelrios7
Posts: 10
Joined: 19 Apr 2012 03:52

Re: Dallas DS1307 Simple Clock Demo

#6 Post by noelrios7 » 17 Sep 2014 12:44

Please also note that the I2C pins on the Microchip PIC is fixed so you do not see a pin assignment. You can locate the I2C pins by searching for SDA and SCL. Use a 10K pull up when wiring the PIC to the DS1307.

jsbhalla88
Posts: 57
Joined: 03 Mar 2015 15:23

Re: Dallas DS1307 Simple Clock Demo

#7 Post by jsbhalla88 » 26 Mar 2015 16:10

hi,
I have to use software I2C for 2 sensors, over two different I2C lines...
is it possible to configure PIC16F1825 for that..?? and I am not sure what kind of calculations will be involved in it, so I don't know if PIC18F1625 can handle It or not..??
how do I find the address of the sensors,,,??
I have never worked on temperature and humidity sensors, also I am new to I2C..never used these..

User avatar
Aleksandar.Mitrovic
mikroElektronika team
Posts: 1697
Joined: 11 Mar 2015 12:48

Re: Dallas DS1307 Simple Clock Demo

#8 Post by Aleksandar.Mitrovic » 27 Mar 2015 16:39

Hi,

I suggest you to use one hardware and one software I2C.
For software I2C please refer to Help in compiler and go to mikroC PRO for PIC Libraries > Hardware Libraries > Software I2C Library.
There you will find how to setup software I2C.

Note that you will need to setup ports and directions for your pins.

Best regards,
Aleksandar

jsbhalla88
Posts: 57
Joined: 03 Mar 2015 15:23

Re: Dallas DS1307 Simple Clock Demo

#9 Post by jsbhalla88 » 30 Mar 2015 18:41

thanx..

Post Reply

Return to “User Projects”