[51] rtc ds1307 with 8051 can't update date & time after mains power switch on

Status
Not open for further replies.

aviraje8

Newbie level 5
Joined
Nov 21, 2013
Messages
9
Helped
0
Reputation
0
Reaction score
0
Trophy points
1
Visit site
Activity points
119
here is the code
when power on the system it start displaying date & time,but when I turns power off then again turn on the power it displays initial value not updated value




Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
#include<reg51.h>
 
void _nop_(void);
 
#define delay_us _nop_(); //generates 1 microsecond
 
#define LCD P0
 
sbit RS=P2^0; 
 
sbit EN=P2^1; 
 
sbit SCK=P2^3; //serial clock pin
 
sbit SDA=P2^4; //serial data pin
 
 
#define SCKHIGH  SCK=1;
 
#define SCKLOW   SCK=0;
 
#define SDAHIGH  SDA=1;
 
#define SDALOW   SDA=0;
 
 
void integer_lcd(int);
 
void init_lcd(void);
 
void cmd_lcd(unsigned char);
 
void write_lcd(unsigned char);
 
void display_lcd(unsigned char *);
 
void delay_ms(unsigned int);
 
void SDelay_ms(unsigned int);
void MDelay_ms(unsigned int);
void T0Delay(void);
 
void start(void);
 
void stop(void);
 
void send_byte(unsigned char);
 
unsigned char receive_byte(unsigned char);
 
void write_i2c(unsigned char,unsigned char,unsigned char);
 
unsigned char read_i2c(unsigned char,unsigned char);
 
 
void sys_init(void);
 
//clock[]={seconds,minutes,hours,day_of_week,date,month,year};
 
unsigned char clock[]={0x00,0x59,0x23,0x02,0x31,0x12,0x15};
 
unsigned char *s[]={"SUN","MON","TUE","WED","THU","FRI","SAT"};
 
unsigned char slave_ack,add=0,c,k,p,q,r,t,u,v;
 
unsigned int num,m;
        
            // Real Time Clock Mode
 
void main(void)
{
init_lcd();
 
 
while(add<=6)   //update real time clock
 
                        {
 
                        write_i2c(0xd0,add,clock[add]);
 
                        add++;
 
                        }
 
 
         sys_init();
 
           
}
 
void sys_init()
 {  
      
 
while(1)
{
                       p=read_i2c(0xd0,0x02);//read hours register and display on LCD
 
                        write_lcd((p/16)+48);
 
                        write_lcd((p%16)+48);
 
                        write_lcd(':');
 
                       
                        q=read_i2c(0xd0,0x01);//read minutes register and display on LCD
 
                        write_lcd((q/16)+48);
 
                        write_lcd((q%16)+48);
 
                        write_lcd(':');
 
                         
                        delay_ms(10);
 
                        r=read_i2c(0xd0,0x00);//read seconds register and display on LCD
 
                        write_lcd((r/16)+48);
 
                        write_lcd((r%16)+48);
 
                        write_lcd(' ');
 
                       
                        display_lcd(s[read_i2c(0xd0,0x03)]);//read day register and display
                       
 
                        cmd_lcd(0xc0);
 
                        t=read_i2c(0xd0,0x04);//read date register and display on LCD
 
                        write_lcd((t/16)+48);
 
                        write_lcd((t%16)+48);
 
                        write_lcd('/');
                      
 
                        u=read_i2c(0xd0,0x05);//read month register and display on LCD
 
                        write_lcd((u/16)+48);
 
                        write_lcd((u%16)+48);
 
                        write_lcd('/');
 
                       
                        write_lcd('2');
 
                        write_lcd('0');
 
                        v=read_i2c(0xd0,0x06);//read year register and display on LCD
 
                        write_lcd((v/16)+48);
 
                        write_lcd((v%16)+48);
                       
 
                        delay_ms(100);
 
                        cmd_lcd(0x01);
 
                        if(p>=23 && q>=0x59 && r>=0x59 && t>=31 && u>=12 && v>=15)
                        {
                        delay_ms(100);
                        P1=0X00;
                        }
 
}                            
                                             
 }
 
                     
//starts i2c, if both SCK & SDA are idle
 
void start(void)
 
{ 
 
            if(SCK==0) //check SCK. if SCK busy, return else SCK idle
 
                        return;
 
            if(SDA==0) //check SDA. if SDA busy, return else SDA idle
 
                        return;
 
SDALOW //data low
 
delay_us
 
SCKLOW  //clock low   
 
delay_us
 
}          
 
//stops i2c, releasing the bus
 
void stop(void)
 
{        
 
SDALOW //data low
 
SCKHIGH //clock high
 
delay_us
 
SDAHIGH //data high
 
delay_us
 
}
 
 
//transmits one byte of data to i2c bus
 
void send_byte(unsigned char c)
 
{
 
unsigned mask=0x80;
 
            do  //transmits 8 bits
 
            {
 
                        if(c&mask) //set data line accordingly(0 or 1)
 
                                    SDAHIGH //data high
 
                        else
 
                                    SDALOW //data low
 
                        SCKHIGH   //clock high
 
                        delay_us
 
                        SCKLOW   //clock low
 
                        delay_us
 
                        mask/=2;  //shift mask
 
            }while(mask>0);
 
SDAHIGH  //release data line for acknowledge
 
SCKHIGH  //send clock for acknowledge
 
delay_us
 
slave_ack=SDA; //read data pin for acknowledge
 
SCKLOW  //clock low
 
delay_us
 
}      
 
 
 
//receives one byte of data from i2c bus
 
unsigned char receive_byte(unsigned char master_ack)
 
{
 
unsigned char c=0,mask=0x80;
 
            do  //receive 8 bits
 
            {
 
                        SCKHIGH //clock high
 
                        delay_us
 
                                    if(SDA==1) //read data
 
                                                c|=mask;  //store data
 
                        SCKLOW  //clock low
 
                        delay_us
 
                        mask/=2; //shift mask
 
            }while(mask>0);
 
            if(master_ack==1)
 
                        SDAHIGH //don't acknowledge
 
            else
 
                        SDALOW //acknowledge
 
SCKHIGH //clock high
 
delay_us
 
SCKLOW //clock low
 
delay_us
 
SDAHIGH //data high
 
return c;
 
}
 
 
 
 
 
 
 
//writes one byte of data(c) to slave device(device_id) at given address(location)
 
void write_i2c(unsigned char device_id,unsigned char location,unsigned char c)
 
{
 
            do
 
            {
 
                        start();      //starts i2c bus
 
                        send_byte(device_id); //select slave device
 
                        if(slave_ack==1)  //if acknowledge not received, stop i2c bus
 
                                    stop();
 
            }while(slave_ack==1); //loop until acknowledge is received
 
send_byte(location); //send address location
 
send_byte(c); //send data to i2c bus
 
stop(); //stop i2c bus
 
delay_ms(4);
 
}      
 
 
 
//reads one byte of data(c) from slave device(device_id) at given address(location)
 
unsigned char read_i2c(unsigned char device_id,unsigned char location)
 
{
 
unsigned char c;
 
            do
 
            {
 
                        start();   //starts i2c bus  
 
                        send_byte(device_id); //select slave device
 
                        if(slave_ack==1) //if acknowledge not received, stop i2c bus
 
                                    stop();
 
            }while(slave_ack==1); //loop until acknowledge is received
 
send_byte(location);  //send address location     
 
stop(); //stop i2c bus
 
start(); //starts i2c bus  
 
send_byte(device_id+1); //select slave device in read mode
 
c=receive_byte(1); //receive data from i2c bus
 
stop(); //stop i2c bus
 
return c;
 
}      
 
 
 
/*display of 16bit(integers) values on LCD
 
void integer_lcd(int n)
 
{
 
unsigned char c[6];
 
unsigned int i=0;
 
  if(n<0)
 
  {
 
    write_lcd('-');
 
    n=-n;
 
  }
 
  if(n==0)
 
    write_lcd('0');
 
  while(n>0)//Split integer to 2 bytes and send on 8bit line.
 
  {
 
    c[i++]=(n%10)+48;
 
    n/=10;
 
  }
 
  while(i-->=1)
 
    write_lcd(c[i]);
 
}*/
 
 
 
//initialize lcd
 
void init_lcd(void)
 
{                           
 
delay_ms(10); //delay 10 milliseconds
 
cmd_lcd(0x0e); //lcd on, cursor on
 
delay_ms(10);
 
cmd_lcd(0x38); //8 bit initialize, 5x7 character font, 16x2 display
 
delay_ms(10);
 
cmd_lcd(0x06); //right shift cursor automatically after each character is displayed
 
delay_ms(10);
 
cmd_lcd(0x01); //clear lcd
 
delay_ms(10);
 
cmd_lcd (0x80);
 
}
 
 
 
//transmit command or instruction to lcd
 
void cmd_lcd(unsigned char c)
 
{
 
EN=1;
 
RS=0; //clear register select pin
 
LCD=c; //load 8 bit data
 
EN=0; //clear enable pin
 
delay_ms(2); //delay 2 milliseconds
 
}
 
 
 
//transmit a character to be displayed on lcd
 
void write_lcd(unsigned char c)
 
{
 
EN=1; //set enable pin
 
RS=1; //set register select pin
 
LCD=c;  //load 8 bit data
 
EN=0; //clear enable pin
 
delay_ms(2); //delay 2 milliseconds           
 
}
 
 
 
//transmit a string to be displayed on lcd
 
void display_lcd(unsigned char *s)
 
{
 
while(*s)
 
write_lcd(*s++);
 
}
 
 
 
//generates delay in milli seconds
 
void delay_ms(unsigned int i)
 
{
 
unsigned int j;
 
            while(i-->0)
 
            {
 
                        for(j=0;j<500;j++)
 
                        {
 
                                    ;
 
                        }
 
            }
 
} 
 
void T0Delay()
{
TMOD=0X50;
TL0=0XB0;
TH0=0X3C;
TR0=1;
while(TF0==0);
TR0=0;
TF0=0;
}
 
void MDelay_ms(unsigned int i)
{
unsigned int j;
while(i-->0)
{
for(j=0;j<7000;j++)
{
    ;
}
}
}
 
void SDelay_ms(unsigned int m)
{
unsigned int z;
 m=m*200;
 
for(z=0;z<=m;z++)
{
T0Delay();
}
}

 
Last edited by a moderator:

if it is loosing information when the power is removed have you checked the backup battery circuit is operating correctly?

does the SRAM loose data s well?
 

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…