Ds1307 based digital clock

Status
Not open for further replies.
may be there is an error in the circuit, i am attaching the circuit, please simulate this circuit wiht your code and solve my problem, i also noted that the ds1307 window that appears on playing simulation is also slower than the real time, what about that?
circuit simulation:
https://obrazki.elektroda.pl/1524368600_1353682669.png
 

Proteus realtime simulation is slow. One more thing might be you are using 1 sec or 2 sec or more delays in your while(1) loop. so the rtc time is different from proteus time.

zip and post your proteus .dsn file and mikroC project files. I will check your simulation after 2 hrs. I have to modify the code a little. It is a working code. I have a done rtc usb hid datalogger. It has rtc in it. https://www.edaboard.com/threads/271146/
 





whats compiler version and microcontroller you are using??
i will use the same,, if you have any circuit, please attach it too

- - - Updated - - -





here is all the project, code, and simulation files, compiler is mplab ide v8.73 and proteus is 6.9
 

Attachments

  • edaboard dc.rar
    147.8 KB · Views: 117

Sometime back you said you are using mikroC abd now you are saying that you are using MPLAB IDE. Are you using mikroC or Hi-Tech C or C18?

I am using mikroC Pro 5.6.0 and Proteus 7.10 SP0. I have used rtc with PIC18F4550 and PIC18F46J50.

You can use any PIC, just change the code for Lcd Connections and buttons if you are using.
 

there is an error in i2c2_wr() and i2c2_stop()
i am using mikroc pro 5.6.1 and you are using 5.6.0
the error is

undeclared identifier "i2c2_wr" in expression

whats the solution?
is that any error in code? as we normally use "i2c_wr"
are you doing this mistake?

- - - Updated - - -

mikroc pro v5.6.1 have "i2c1_start()" and "soft_i2c_start()" but no "i2c2_start()"
now what to do please ??
 

I am not doing any mistake. Some PIC have dual I2C. In that code i am using I2C2 Library, you have to use I2C1 Library.

I finished modifying the code and it is working. See the attached files. I have not called Write_Time() function from while(1) loop. I haven't used that function, but it has working code for that function. You can try using Write_Time() in real hardware to set time for DS1307 RTC.

Buttons are not coded yet.
 

Attachments

  • ds1307_rtc_sim.rar
    175.4 KB · Views: 124
  • PIC16F877A DS1307 RTC Hafiz Imran.rar
    78.1 KB · Views: 97

If you have PIC18F4539 in Proteus 6.5, you can use it. What happened to Proteus 7.10?

mikroC Pro 5.6.1 has I2C1_Start(), I2C2_Start(), Soft_I2C1_Start(), and Soft_I2C2_Start() library functions

 
Last edited:

1) its slower than the real time, is it only in simulaiton?
2) "day" button is working while other two are not working, why? the working button also changes "fri" to "sat" momentarily and then again changes to "fri" why??
 

It is working fine for me. post the code that you are using for simulation. I will check it.
 

the same you just sent,,, give me image of circuit from simulation by using print screen key,,,

check it with some stop watch on your mobile,,,,,its slow for me and i think it would be same for you
here is the code


Code:
#ifndef DS1307
#define DS1307 0xD0
#endif

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

sbit LCD_RS_Direction at TRISB2_bit;
sbit LCD_EN_Direction at TRISB3_bit;
sbit LCD_D4_Direction at TRISB4_bit;
sbit LCD_D5_Direction at TRISB5_bit;
sbit LCD_D6_Direction at TRISB6_bit;
sbit LCD_D7_Direction at TRISB7_bit;
// End LCD module connections

unsigned char num,flag;
char b, x, i, sec, min1, hr, week_day, day, mn, year, year1, month1, day1, hours1, mins2, seconds1;
char *txt, tnum[4], time_format[3], sihr[17];
char colon[] = ":";
int cnt, ihr, error, am_pm = 0;

void Zero_Fill(char *value) {
        if (value[1] == 0) {
                value[1] = value[0];
                value[0] = 48;
                value[2] = 0;
        }
}

void Write_Time() {
        I2C1_Start();          // issue start signal
        I2C1_Wr(DS1307);       // address DS1307
        I2C1_Wr(0);            // start from word at address (REG0)
        I2C1_Wr(0x80);         // write $80 to REG0. (pause counter + 0 sec)
        I2C1_Wr(0);            // write 0 to minutes word to (REG1)
        I2C1_Wr(0x17);         // write 17 to hours word (24-hours mode)(REG2)
        I2C1_Wr(0x02);         // write 2 - Monday (REG3)
        I2C1_Wr(0x04);         // write 4 to date word (REG4)
        I2C1_Wr(0x05);         // write 5 (May) to month word (REG5)
        I2C1_Wr(0x01);         // write 01 to year word (REG6)
        I2C1_Stop();           // issue stop signal

        I2C1_Start();          // issue start signal
        I2C1_Wr(0xD0);         // address DS1307
        I2C1_Wr(0);            // start from word at address 0
        I2C1_Wr(0);            // write 0 to REG0 (enable counting + 0 sec)
        I2C1_Stop();           // issue stop signal
}

void Read_Time(char *sec, char *min, char *hr, char *week_day, char *day, char *mn, char *year) {
        I2C1_Start();
        I2C1_Wr(DS1307);
        I2C1_Wr(0);
        I2C1_Repeated_Start();
        I2C1_Wr(0xD1);
        *sec =I2C1_Rd(1);
        *min =I2C1_Rd(1);
        *hr =I2C1_Rd(1);
        *week_day =I2C1_Rd(1);
        *day =I2C1_Rd(1);
        *mn =I2C1_Rd(1);
        *year =I2C1_Rd(0);
        I2C1_Stop();
}

void Transform_Time(char  *sec, char *min, char *hr, char *week_day, char *day, char *mn, char *year) {
        *sec  =  ((*sec & 0x70) >> 4)*10 + (*sec & 0x0F);
        *min  =  ((*min & 0xF0) >> 4)*10 + (*min & 0x0F);
        *hr   =  ((*hr & 0x30) >> 4)*10 + (*hr & 0x0F);
        *week_day =(*week_day & 0x07);
        *day  =  ((*day & 0xF0) >> 4)*10 + (*day & 0x0F);
        *mn   =  ((*mn & 0x10) >> 4)*10 + (*mn & 0x0F);
        *year =  ((*year & 0xF0)>>4)*10+(*year & 0x0F);
}

void Display_Time(char sec, char min, char hr, char week_day, char day, char mn, char year) {



        switch(week_day){
                case 1: txt="Sun"; break;
                case 2: txt="Mon"; break;
                case 3: txt="Tue"; break;
                case 4: txt="Wed"; break;
                case 5: txt="Thu"; break;
                case 6: txt="Fri"; break;
                case 7: txt="Sat"; break;
        }
        Lcd_Out(1,1,txt);
        Lcd_Chr(1,5,(day / 10)   + 48);    // Print tens digit of day variable
        Lcd_Chr(1,6, (day % 10)   + 48);    // Print oness digit of day variable
        Lcd_Chr(1,7,'/');
        Lcd_Chr(1,8,(mn / 10) + 48);
        Lcd_Chr(1,9,(mn % 10) + 48);
        Lcd_Chr(1,10,'/');
        Lcd_Out(1,11,"2");
        Lcd_Out(1,12,"0");
        Lcd_Chr(1,13, (year / 10)  + 48);          // Print year vaiable + 8 (start from year 2008)
        Lcd_Chr(1,14, (year % 10)  + 48);

        if(hr >= 12) {
           Lcd_Out(2,2,"PM");
           am_pm = 1;
        }
        else if(hr < 12) {
           Lcd_Out(2,2,"AM");
           am_pm = 0;
        }

        Lcd_Chr(2,5,(hr / 10)  + 48);
        Lcd_Chr(2,6,(hr % 10)  + 48);
        Lcd_Out(2,7,":");
        Lcd_Chr(2,8,(min / 10) + 48);
        Lcd_Chr(2,9,(min % 10) + 48);
        Lcd_Out(2,10,":");
        Lcd_Chr(2,11,(sec / 10) + 48);
        Lcd_Chr(2,12,(sec % 10) + 48);

}

void main() {

     TRISA = 0b00000111;
     PORTA = 0b00000000;
     TRISB = 0b00000000;
     PORTB = 0b00000000;
     ADCON0 = 0b00000000;
     ADCON1 = 0b10110101;

     cnt = 0;


     Lcd_Init();
     Lcd_Cmd(_LCD_CLEAR);
     Lcd_Cmd(_LCD_CURSOR_OFF);
     Lcd_Out(1,4,"RTC DS1307");
     Delay_ms(3000);
     I2C1_Init(100000);
     Lcd_Cmd(_LCD_CLEAR);

     while(1) {
         //Write_Time();
         Read_Time(&sec,&min1,&hr,&week_day,&day,&mn,&year);
         Transform_Time(&sec,&min1,&hr,&week_day,&day,&mn,&year);
         Display_Time(sec, min1, hr, week_day, day, mn, year);
     }
}
 
Last edited:

1) its slower than the real time, is it only in simulaiton?

You have to match it against Proteus time. You can't match it against computer time. It just won't match. Simulation doesn't occur in real time. Basically, to simulate 60 seconds, Proteus takes between 70-75 seconds (maybe more).

All but the very simplest circuits will run slower than real time. So, there will always be a difference between Proteus time and computer time. For simulation, you must use Proteus time. Make it on hardware instead of simulation and you'll see that it's fine.

Go through this:
https://www.edaboard.com/threads/270617/
 

Please edit your last post and wrap your code in code tags. use the # button for code tag.

You said that some buttons are working? How? I have not written the code for buttons.

Why do you need image of my circuit, i have already sent my proteus .dsn file. Is it not opening?

 




the left side button is working and if i press it the day changes from "fri" to "sat" for just a second and then again changes back to "fri" other two are not working,

i have proteus 6.9 and you are using some later version, so i could not open it i want to make it in my own version..
 

The schematic is posted. post your code I will see what is making the button to behave like that.
 

The schematic is posted. post your code I will see what is making the button to behave like that.


Code:
#ifndef DS1307
        #define DS1307 0xD0
#endif

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

sbit LCD_RS_Direction at TRISB2_bit;
sbit LCD_EN_Direction at TRISB3_bit;
sbit LCD_D4_Direction at TRISB4_bit;
sbit LCD_D5_Direction at TRISB5_bit;
sbit LCD_D6_Direction at TRISB6_bit;
sbit LCD_D7_Direction at TRISB7_bit;
// End LCD module connections

unsigned char num,flag;
char b, x, i, sec, min1, hr, week_day, day, mn, year, year1, month1, day1, hours1, mins2, seconds1;
char *txt, tnum[4], time_format[3], sihr[17];
char colon[] = ":";
int cnt, ihr, error, am_pm = 0;

void Zero_Fill(char *value) {
        if (value[1] == 0) {
                value[1] = value[0];
                value[0] = 48;
                value[2] = 0;
        }
}

void Write_Time() {
        I2C1_Start();          // issue start signal
        I2C1_Wr(DS1307);       // address DS1307
        I2C1_Wr(0);            // start from word at address (REG0)
        I2C1_Wr(0x80);         // write $80 to REG0. (pause counter + 0 sec)
        I2C1_Wr(0);            // write 0 to minutes word to (REG1)
        I2C1_Wr(0x17);         // write 17 to hours word (24-hours mode)(REG2)
        I2C1_Wr(0x02);         // write 2 - Monday (REG3)
        I2C1_Wr(0x04);         // write 4 to date word (REG4)
        I2C1_Wr(0x05);         // write 5 (May) to month word (REG5)
        I2C1_Wr(0x01);         // write 01 to year word (REG6)
        I2C1_Stop();           // issue stop signal

        I2C1_Start();          // issue start signal
        I2C1_Wr(0xD0);         // address DS1307
        I2C1_Wr(0);            // start from word at address 0
        I2C1_Wr(0);            // write 0 to REG0 (enable counting + 0 sec)
        I2C1_Stop();           // issue stop signal
}

void Read_Time(char *sec, char *min, char *hr, char *week_day, char *day, char *mn, char *year) {
        I2C1_Start();
        I2C1_Wr(DS1307);
        I2C1_Wr(0);
        I2C1_Repeated_Start();
        I2C1_Wr(0xD1);
        *sec =I2C1_Rd(1);
        *min =I2C1_Rd(1);
        *hr =I2C1_Rd(1);
        *week_day =I2C1_Rd(1);
        *day =I2C1_Rd(1);
        *mn =I2C1_Rd(1);
        *year =I2C1_Rd(0);
        I2C1_Stop();
}

void Transform_Time(char  *sec, char *min, char *hr, char *week_day, char *day, char *mn, char *year) {
        *sec  =  ((*sec & 0x70) >> 4)*10 + (*sec & 0x0F);
        *min  =  ((*min & 0xF0) >> 4)*10 + (*min & 0x0F);
        *hr   =  ((*hr & 0x30) >> 4)*10 + (*hr & 0x0F);
        *week_day =(*week_day & 0x07);
        *day  =  ((*day & 0xF0) >> 4)*10 + (*day & 0x0F);
        *mn   =  ((*mn & 0x10) >> 4)*10 + (*mn & 0x0F);
        *year =  ((*year & 0xF0)>>4)*10+(*year & 0x0F);
}

void Display_Time(char sec, char min, char hr, char week_day, char day, char mn, char year) {



        switch(week_day){
                case 1: txt="Sun"; break;
                case 2: txt="Mon"; break;
                case 3: txt="Tue"; break;
                case 4: txt="Wed"; break;
                case 5: txt="Thu"; break;
                case 6: txt="Fri"; break;
                case 7: txt="Sat"; break;
        }
        Lcd_Out(1,1,txt);
        Lcd_Chr(1,5,(day / 10)   + 48);    // Print tens digit of day variable
        Lcd_Chr(1,6, (day % 10)   + 48);    // Print oness digit of day variable
        Lcd_Chr(1,7,'/');
        Lcd_Chr(1,8,(mn / 10) + 48);
        Lcd_Chr(1,9,(mn % 10) + 48);
        Lcd_Chr(1,10,'/');
        Lcd_Out(1,11,"2");
        Lcd_Out(1,12,"0");
        Lcd_Chr(1,13, (year / 10)  + 48);          // Print year vaiable + 8 (start from year 2008)
        Lcd_Chr(1,14, (year % 10)  + 48);

        if(hr >= 12) {
           Lcd_Out(2,2,"PM");
           am_pm = 1;
        }
        else if(hr < 12) {
           Lcd_Out(2,2,"AM");
           am_pm = 0;
        }

        Lcd_Chr(2,5,(hr / 10)  + 48);
        Lcd_Chr(2,6,(hr % 10)  + 48);
        Lcd_Out(2,7,":");
        Lcd_Chr(2,8,(min / 10) + 48);
        Lcd_Chr(2,9,(min % 10) + 48);
        Lcd_Out(2,10,":");
        Lcd_Chr(2,11,(sec / 10) + 48);
        Lcd_Chr(2,12,(sec % 10) + 48);

}

void main() {

     TRISA = 0b00000111;
     PORTA = 0b00000000;
     TRISB = 0b00000000;
     PORTB = 0b00000000;
     ADCON0 = 0b00000000;
     ADCON1 = 0b10110101;

     cnt = 0;


     Lcd_Init();
     Lcd_Cmd(_LCD_CLEAR);
     Lcd_Cmd(_LCD_CURSOR_OFF);
     Lcd_Out(1,4,"RTC DS1307");
     Delay_ms(3000);
     I2C1_Init(100000);
     Lcd_Cmd(_LCD_CLEAR);

     while(1) {
         //Write_Time();
         Read_Time(&sec,&min1,&hr,&week_day,&day,&mn,&year);
         Transform_Time(&sec,&min1,&hr,&week_day,&day,&mn,&year);
         Display_Time(sec, min1, hr, week_day, day, mn, year);
     }
}
 

There is no code for button in it. Button cannot work on its own without any code. You have to change ADCON0 and ADCON1 register settings if you are using switches. If tere is ANSEL register in PIC16F877 then configure it also.
 

There is no code for button in it. Button cannot work on its own without any code. You have to change ADCON0 and ADCON1 register settings if you are using switches. If tere is ANSEL register in PIC16F877 then configure it also.

previous code is now working 100% correct , its time is also matched with simulation time,,
can you please make some code for buttons, i am new with pic i always used 8051, this is my first project at pic,, and as i told earlier i have only one week which is very less time to understand a new microcontroller, please,,,,, if you can
 

I need some time. can you use 4 buttons or 5 buttons?

yes i can use,, you can use one for seconds, 2nd for minutes, 3rd for hours,4th for day, 5th for year,6th for date, 7th for month etc....

please make it with alarm if possible
 

Status
Not open for further replies.

Similar threads

Cookies are required to use this site. You must accept them to continue using the site. Learn more…