реклама на сайте
подробности

 
 
> Алгоритм перехода на летнее время.
SpiritDance
сообщение Mar 31 2008, 05:19
Сообщение #1


Дух погибшего транзистора
****

Группа: Свой
Сообщений: 877
Регистрация: 6-09-05
Из: Москва
Пользователь №: 8 288



Во-первых поздравляю всех с переходом на летнее время. Хорошего всем самочувствия.

Вопрос в следующем, кто-нибудь собственно алгоритм перехода на летнее время и обратно для часов встроенных систем? Если да то помогите либо подробным алгоритмом, либо исходниками пжалста. Надеюсь это не коммерческая тайна. smile.gif


--------------------
Yes, there are two paths you can go by But in the long run Theres still time to change the road youre on.
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
umup
сообщение Apr 2 2008, 20:11
Сообщение #2


Местный
***

Группа: Свой
Сообщений: 226
Регистрация: 2-06-06
Пользователь №: 17 720



я делал (в программных часах на Меге 8) просто таблицу чисел марта/октября, соответствующих переходу (с 2000 по 203x год - всего 64 байта, думаю само вычисление числа займет больше).

Функция rtc_increment вызывается каждую секунду в обработчике прерывания часового кварца.
Флаги flag_rtc_sec_pass, flag_rtc_min_pass, flag_rtc_hr_pass используются в других частях программы для синхронизации с секундными, минутными, часовыми событиями (в конце основного цикла обнуляются).
Флаги flag_rtc_corrected и flag_rtc_corrected_forw - для улавливания события коррекции.

ul_rtc.h :

Код
/** \addtogroup group_rtc RTC structure/functions (структура и функции для работы с часами реального времени)
  */

#if ((!defined(ul_c_rtc_included)) || (defined __DOXYGEN__))

#define ul_c_rtc_included 1    /**< \brief module inclusion flag<br />флаг включения модуля \ingroup group_rtc */

#include "ul_misc.h"         /*include misc definitions/functions types*/

/** \brief RTC structure<br />структура часов \ingroup group_rtc */
typedef struct
{u8 sec;      /**< \brief seconds (0..59)   <br />секунды (0..59)       \ingroup group_rtc */
u8 min;      /**< \brief minutes (0..59)   <br />минуты (0..59)        \ingroup group_rtc */
u8 hr;       /**< \brief hours (0..23)     <br />часы (0..23)          \ingroup group_rtc */
u8 date;     /**< \brief date (1..31)      <br />дата (1..31)          \ingroup group_rtc */
u8 month;    /**< \brief month (1..12)     <br />месяц (1..12)         \ingroup group_rtc */
u16 year;    /**< \brief year (1900..2100) <br />год (1900..2100)      \ingroup group_rtc */
u8 flags;    /**< \brief RTC flags         <br />флаги RTC             \ingroup group_rtc */
u16 crc;     /**< \brief crc of structure  <br />контр.сумма структуры \ingroup group_rtc */
}struct_rtc;

#define flag_rtc_sec_pass       0x01 /**< \brief =1 every second passed <br />=1 каждую секунду \ingroup group_rtc */
#define flag_rtc_min_pass       0x02 /**< \brief =1 every minute passed <br />=1 каждую минуту \ingroup group_rtc */
#define flag_rtc_hr_pass        0x04 /**< \brief =1 every hour passed   <br />=1 каждый час \ingroup group_rtc */
#define flag_rtc_corrected      0x20 /**< \brief =1 if was time correction <br />=1 если была коррекция на летнее/зимнее время \ingroup group_rtc */
#define flag_rtc_corrected_forw 0x40 /**< \brief =1 if was hour-forward time correction (otherwise hour-backward)<br />=1 если была коррекция на час вперед (иначе на час назад) \ingroup group_rtc */
#define flag_rtc_correction     0x80 /**< \brief =1 for auto-correction <br />=1 для автоматического перехода на зимнее/летнее время \ingroup group_rtc */

/** \brief increment time of RTC structure by 1 second<br />увеличить время в структуре часов на 1 секунду \ingroup group_rtc */
inline void rtc_increment(void *rtc_data);

#endif



ul_rtc.c :

Код
#include "ul_rtc.h"  /*include RTC header*/

#if (defined(ul_c_use_gccavr))
#include <avr/pgmspace.h>     /*Program memory usage for AVR-GCC*/
#endif

#if (!defined(rtc_corr_dates_table))
#if (defined(ul_c_use_gccavr))
  u8 rtc_corr_dates_table[][32] PROGMEM = {{29,28,27,26,31,30,29,28,26,25,31,30,28,27,26,25,30,29,28,27,25,31,30,29,27,26,
25,31,29,28,27,26},
  {26,25,31,30,28,27,26,25,30,29,28,27,25,31,30,29,27,26,25,31,29,28,27,26,31
,30,29,28,26,25,31,30}
};
#else
  u8 rtc_corr_dates_table[][32]         = {{29,28,27,26,31,30,29,28,26,25,31,30,28,27,26,25,30,29,28,27,25,31,30,29,27,26,
25,31,29,28,27,26},
  {26,25,31,30,28,27,26,25,30,29,28,27,25,31,30,29,27,26,25,31,29,28,27,26,31
,30,29,28,26,25,31,30}
};
#endif
#endif

inline void rtc_increment(void *rtc_data)
{u8 u8_01, u8_02;
u8_01 = (*((struct_rtc *)rtc_data)).month;
u8_02 = (*((struct_rtc *)rtc_data)).date;
(*((struct_rtc *)rtc_data)).flags |= flag_rtc_sec_pass;  /*set second passed flag*/
if (++((*((struct_rtc *)rtc_data)).sec) == 60)          /*process seconds overflow*/
{(*((struct_rtc *)rtc_data)).sec = 0;
  (*((struct_rtc *)rtc_data)).flags |= flag_rtc_min_pass; /*set minute passed flag*/
  if (++((*((struct_rtc *)rtc_data)).min) == 60)         /*process minutes overflow*/
  {(*((struct_rtc *)rtc_data)).min = 0;
   (*((struct_rtc *)rtc_data)).flags |= flag_rtc_hr_pass; /*set hour passed flag*/
   if (++((*((struct_rtc *)rtc_data)).hr) == 24)         /*process hours overflow*/
   {(*((struct_rtc *)rtc_data)).hr = 0;
    u8_02++; /*calculate next date*/
    if (u8_02 == 32) {u8_01++; u8_02 = 1;}
    else if (u8_02 == 31)
    {if ((u8_01 == 4) || (u8_01 == 6) || (u8_01 == 9) || (u8_01 == 11))
     {u8_01++;
      u8_02 = 1;
     }
    }else if (u8_02 == 30)
     {if (u8_01==2) {u8_01++; u8_02 = 1;}
     }else if (u8_02 == 29)
      {if ((u8_01 == 2) && (((*((struct_rtc *)rtc_data)).year) & 3))
       {u8_01++;
        u8_02 = 1;
       }
      }
    /*month overflow*/
    if (u8_01 == 13)
    {u8_01 = 1;
     ((*((struct_rtc *)rtc_data)).year)++;
    }
   }
  }
}
(*((struct_rtc *)rtc_data)).month = u8_01;
(*((struct_rtc *)rtc_data)).date = u8_02;

/*if needed, do time auto correction*/
if ((*((struct_rtc *)rtc_data)).flags & flag_rtc_correction)
{/*every last sunday of march (hour++) and october (hour--) at 4 a.m.*/
  if (((u8_01 == 10) || (u8_01 == 3)) && (u8_02 > 24) &&
      ((*((struct_rtc *)rtc_data)).hr == 4) && ((*((struct_rtc *)rtc_data)).min == 0) &&
      ((*((struct_rtc *)rtc_data)).sec == 0))
  {u8 u8_03;
   /*get correction date*/
   u8_03 = ((u8)((*((struct_rtc *)rtc_data)).year)) & 0x1f; /*table index*/
   #if (defined(ul_c_use_gccavr))
    u8_03 = pgm_read_byte(&(rtc_corr_dates_table[u8_01 & 1][u8_03]));
   #else
    u8_03 = rtc_corr_dates_table[u8_01 & 1][u8_03];
   #endif
   /*if date is correct, do time correction*/
   if (u8_02 == u8_03)
   {(*((struct_rtc *)rtc_data)).flags |= flag_rtc_corrected; /*set correction flag*/
    if (u8_01 == 3)
    {(*((struct_rtc *)rtc_data)).hr++;
     (*((struct_rtc *)rtc_data)).flags |= flag_rtc_corrected_forw; /*forward correction*/
    }else (*((struct_rtc *)rtc_data)).hr--;
   }
  }
}
}


Сообщение отредактировал umup - Apr 2 2008, 20:36
Go to the top of the page
 
+Quote Post



Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 24th June 2025 - 15:59
Рейтинг@Mail.ru


Страница сгенерированна за 0.01401 секунд с 7
ELECTRONIX ©2004-2016