Search code examples
cmicrocontroller8051keil

8051 microcontroller setting on elapse year


i have one question on setting on date, mon and year. we know that every 4 year February is equal to 29 days and the rest is 28 days. So i'm try to code something to let the program know which year of February is equal to 28 or 29 days.

Below is my code what i'm trying to ask is, is there any more simple and short method to do it?

void Timer(void) interrupt 1
{
if(start_timer == 1)
{
TF0 = 0;
TH0 = 0xB1;
TL0 = 0XE0;
msec++;

if(msec==100)
{
    sec++;
    msec=0;
}
if(sec==60)
{
    min++;
    sec=0;          
}
if(min==60)
{
    hour++;
    min=0;  
}
if(hour==24)
{
    date++;
    hour=0;
}
if(date== 30 && mon == 2 ( && year == 2016 || year == 2020 || year == 2024 ))
{
    mon++;
    date=1;
}
if(date== 29 && mon == 2 ( && year == 2015 || year == 2017 || year == 2018 || year == 2019|| year == 2021 || year == 2022 || year == 2023))
{
    mon++;
    date=1;
}
if(date==32 ( && mon == 1 || mon == 3 || mon == 5 || mon == 7 || mon == 9 || mon == 11))
{
    mon++;
    date=1;
}
if(date==31 ( && mon == 4 || mon == 6 || mon == 8 || mon == 10 || mon == 12))
{
    mon++;
    date=1;
}
if(mon==13)
{
    sec = 0;
    min = 0;
    hour = 0;
    date = 1;
    mon = 1;
    year = year++;
}
}
}

Updated:

void Timer(void) interrupt 1 {
    static const int daymon[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
    int daysinmon, leapyear;
    if (start_timer == 1) {
        TF0 = 0;
        TH0 = 0xB1;
        TL0 = 0XE0;
        msec++;
        if (msec >= 100)   {              
            msec -= 100;
            if (++sec >= 60) {
                sec -= 60;          
                if (++min >= 60) {
                    min -= 60;  
                    if (++hour >= 24) {     
                        hour -= 24;
                        daysinmon = daymon[mon-1];
                        if (mon == 2) {     // months 1-based
                            if (year % 4 == 0)
                                leapyear = 1;
                            else if (year % 100 != 0)
                                leapyear = 0;
                            else if (year % 400 == 0)
                                leapyear = 1;
                            else leapyear = 0;

                            if (leapyear == 1)
                                daysinmon++;
                        }

                        if (++date > daysinmon) {
                            date = 1;                 // days 1-based
                            if (++mon > 12) {
                                mon = 1;
                                year++;
                            }
                        }
                    }
                }
            }
        }
    }
}

Solution

  • You have given the interrupt handler far too much work to do, checking everything at every interrupt. I have made some other changes too, not perhaps necessary but more robust, to check the adjustment when each element wraps. A future modification to the code might see the interrupt function interrupt itself, or be delayed by higher priority interrupts.

    EDIT The date and the month are now 1-based to save confusion.

    void Timer(void) interrupt 1 {
        static const int daymon[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
        int daysinmon, leapyear;
        if (start_timer == 1) {
            TF0 = 0;
            TH0 = 0xB1;
            TL0 = 0XE0;
        msec++;
        // and now you could re-enable interrupts to make it re-entrant
        if (msec >= 1000)   {               // altered to 1000, and the conditional test
            msec -= 1000;
            if (++sec >= 60) {
                sec -= 60;          
                if (++min >= 60) {
                    min -= 60;  
                    if (++hour >= 24) {     // the last time we adjust rather than zero
                        hour -= 24;
                        daysinmon = daymon [mon];
                        if (mon == 2) {
                            if (year % 400 == 0)
                                leapyear = 1;
                            else if (year % 100 == 0)
                                leapyear = 0;
                            else if (year % 4 == 0)
                                leapyear = 1;
                            else leapyear = 0;
                            if (leapyear)
                                daysinmon++;
                        }
                        if (++date > daysinmon) {
                            date = 1;
                            if (++mon > 12) {
                                mon = 1;
                                year++;
                            }
                        }
                    }
                }
            }
        }
    

    Sample test output:

    27  2 2000
    28  2 2000
    29  2 2000
     1  3 2000