Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

[AVR] How to use RTC in microcontrollers?

Status
Not open for further replies.
Is it ok if I give you mikroC code. Can you port it to CodeVisionAVR code ?

- - - Updated - - -

I have not tested this code. You have to initially write 0 to eeprom address 0x01 and 0x02. Adjust Trial Limit duration by changing
Code:
#define TRIAL_LIMIT
value.

There should be power for 24 hours and only then the day is counted. Can be modified so that minutes and hours values are written to eeprom and from this day value can be calculated.

This is how I do in my projects.


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
char halfSec = 0, sec = 0, minutes = 0, hours = 0;
unsigned int days = 0;
 
#define TRIAL_LIMIT 180
 
//Timer1 Prescaler = 64; Preload = 31249; Actual Interrupt Time = 500 ms
 
//Place/Copy this part in declaration section
void InitTimer1() {
    SREG_I_bit = 1;
    TCCR1A = 0x80;
    TCCR1B = 0x0B;
    OCR1AH = 0x7A;
    OCR1AL = 0x11;
    OCIE1A_bit = 1;
}
 
void Timer1Overflow_ISR() org IVT_ADDR_TIMER1_COMPA {
    //Enter your code here
    if(++halfSec == 2) {
        if(++sec == 60) {
              if(++minutes == 60) {
                    if(++hours == 24) {
                           ++days;
                           EEPROM_Write(0x01, days);
                           EEPROM_Write(0x02, (days >> 8));
                    }
                    minutes = 0;
              }
              sec = 0;
        }
        halfSec = 0;
    }
}
 
void main() {
 
     DDRB = 0b00111111;
     DDRC = 0xFF;
     DDRD = 0xFF;
     
     days = EEPROM_Read(0x02);
     days <<= 8;
     Delay_ms(20);
     days |= EEPROM_Read(0x01);
     Delay_ms(20);
     
     InitTimer1();
     
     while(1) {
     
            if(days < TRIAL_LIMIT) {
                   PORTB.B0 = !PORTB.B0;
                   Delay_ms(500);
            }
     }
}

 
  • Like
Reactions: abdi110

    V

    Points: 2
    Helpful Answer Positive Rating

    abdi110

    Points: 2
    Helpful Answer Positive Rating
Is it ok if I give you mikroC code. Can you port it to CodeVisionAVR code ?

- - - Updated - - -

I have not tested this code. You have to initially write 0 to eeprom address 0x01 and 0x02. Adjust Trial Limit duration by changing
Code:
#define TRIAL_LIMIT
value.

There should be power for 24 hours and only then the day is counted. Can be modified so that minutes and hours values are written to eeprom and from this day value can be calculated.

This is how I do in my projects.


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
char halfSec = 0, sec = 0, minutes = 0, hours = 0;
unsigned int days = 0;
 
#define TRIAL_LIMIT 180
 
//Timer1 Prescaler = 64; Preload = 31249; Actual Interrupt Time = 500 ms
 
//Place/Copy this part in declaration section
void InitTimer1() {
    SREG_I_bit = 1;
    TCCR1A = 0x80;
    TCCR1B = 0x0B;
    OCR1AH = 0x7A;
    OCR1AL = 0x11;
    OCIE1A_bit = 1;
}
 
void Timer1Overflow_ISR() org IVT_ADDR_TIMER1_COMPA {
    //Enter your code here
    if(++halfSec == 2) {
        if(++sec == 60) {
              if(++minutes == 60) {
                    if(++hours == 24) {
                           ++days;
                           EEPROM_Write(0x01, days);
                           EEPROM_Write(0x02, (days >> 8));
                    }
                    minutes = 0;
              }
              sec = 0;
        }
        halfSec = 0;
    }
}
 
void main() {
 
     DDRB = 0b00111111;
     DDRC = 0xFF;
     DDRD = 0xFF;
     
     days = EEPROM_Read(0x02);
     days <<= 8;
     Delay_ms(20);
     days |= EEPROM_Read(0x01);
     Delay_ms(20);
     
     InitTimer1();
     
     while(1) {
     
            if(days < TRIAL_LIMIT) {
                   PORTB.B0 = !PORTB.B0;
                   Delay_ms(500);
            }
     }
}

Dear Milan
Thank you very much for your code it is amazing. I will try it.
I didn't understand why we need two eeprom addresses and why to "OR" them?
 

The idea of using eeprom for date sounds cool. I never heard of a concept like this. Will this work?
 

@hobbyckts

I use similar code with mikroC PRO PIC projects and they work fine. I create Trial Limits of 30, 180 and 360 days.

@abdi110

If char type is used for days then it can hold max value 255. So I have used unsigned int type for days which will be two bytes wide and can have a max value of 65535 for days and hence two bytes are stored in eeprom. Initial values of eeprom will be 0xFF and it should be set to 0.
 
Thanks for sharing the valuable information Milan. I will take a note of it will be useful for me in my future projects.
 

There should be power for 24 hours and only then the day is counted. Can be modified so that minutes and hours values are written to eeprom and from this day value can be calculated.



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
char halfSec = 0, sec = 0, minutes = 0, hours = 0;
unsigned int days = 0;
 
#define TRIAL_LIMIT 180
 
//Timer1 Prescaler = 64; Preload = 31249; Actual Interrupt Time = 500 ms
 
//Place/Copy this part in declaration section
void InitTimer1() {
    SREG_I_bit = 1;
    TCCR1A = 0x80;
    TCCR1B = 0x0B;
    OCR1AH = 0x7A;
    OCR1AL = 0x11;
    OCIE1A_bit = 1;
}
 
void Timer1Overflow_ISR() org IVT_ADDR_TIMER1_COMPA {
    //Enter your code here
    if(++halfSec == 2) {
        if(++sec == 60) {
              if(++minutes == 60) {
                    if(++hours == 24) {
                           ++days;
                           EEPROM_Write(0x01, days);
                           EEPROM_Write(0x02, (days >> 8));
                    }
                    minutes = 0;
              }
              sec = 0;
        }
        halfSec = 0;
    }
}
 
void main() {
 
     DDRB = 0b00111111;
     DDRC = 0xFF;
     DDRD = 0xFF;
     
     days = EEPROM_Read(0x02);
     days <<= 8;
     Delay_ms(20);
     days |= EEPROM_Read(0x01);
     Delay_ms(20);
     
     InitTimer1();
     
     while(1) {
     
            if(days < TRIAL_LIMIT) {
                   PORTB.B0 = !PORTB.B0;
                   Delay_ms(500);
            }
     }
}


An issue I see with this tactic is how many individuals leave a device powered up for days on end. Typically, individuals turn on a device, utilize it and then power down the device, especially if the device is battery powered. I suppose in some applications such a tactic would work if the device was intended to be powered up days on end.

The reason the bytes are logically OR'd is to recombine the single bytes back into a two byte integer type. You'll notice the value is first shifted to the right eight bits before store the most significant byte (MSB), then shifted to the left before OR'ing and recombining them back into the count integer type variable.


BigDog
 
Dear Milan I got it thank you so much. It is so useful for my project.

- - - Updated - - -

An issue I see with this tactic is how many individuals leave a device powered up for days on end. Typically, individuals turn on a device, utilize it and then power down the device, especially if the device is battery powered. I suppose in some applications such a tactic would work if the device was intended to be powered up days on end.

The reason the bytes are logically OR'd is to recombine the single bytes back into a two byte integer type. You'll notice the value is first shifted to the right eight bits before store the most significant byte (MSB), then shifted to the left before OR'ing and recombining them back into the count integer type variable.


BigDog
Yes it is thanks dear friend.
 

You could certainly reduce the time interval as suggested by Milan, from days, to hours or to minutes, however that will present a few more issues.

1. The time interval counted must be shorter than the typical time interval the device is powered up and utilized before being powered down again.

2. Suppose you decide to count minutes, at that point the potential customer is no longer demoing it for a set number of days, but for a set number of minutes. If the device is powered up for only ten minutes a day, you would hardly set the cutoff at 30 days x 24 hours x 60 minutes = 43200 minutes, which would last the user 4320 days, instead of the intended 30 day trial period.

3. As the time interval decreases the potential task load of microcontroller increases.


BigDog
 
You could certainly reduce the time interval as suggested by Milan, from days, to hours or to minutes, however that will present a few more issues.

1. The time interval counted must be shorter than the typical time interval the device is powered up and utilized before being powered down again.

2. Suppose you decide to count minutes, at that point the potential customer is no longer demoing it for a set number of days, but for a set number of minutes. If the device is powered up for only ten minutes a day, you would hardly set the cutoff at 30 days x 24 hours x 60 minutes = 43200 minutes, which would last the user 4320 days, instead of the intended 30 day trial period.

3. As the time interval decreases the potential task load of microcontroller increases.


BigDog
Yes you are completely right.
I think the method of Milan is useful for systems in them the potential customers have to use them 24th 7days , isn't it?
 

I think the method of Milan is useful for systems in them the potential customers have to use them 24th 7days , isn't it?

Perhaps, although I would probably count the number of power ups and shorten the time interval counted.

The technique certainly has its possibilities, however you must learn to think as someone whom is attempting to circumvent that strategy.

BigDog
 
Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top