|
STM32 RTC->календарь, как сделать из счетчика полноценный календарь? |
|
|
|
Dec 21 2010, 09:30
|
Знающий
   
Группа: Участник
Сообщений: 537
Регистрация: 22-02-06
Пользователь №: 14 594

|
В общем камень STM32 и требуется организовать часы реального времени на его RTC, пока надо час:мин:сек, это не сложно, но в перспективе надо получить полноценный календарь. Нужны будут 2 функции, которые 1. Из 32 битного счетчика секунд получала бы структуру с секундами, минутами, часами .... годом. 2. Из стандартного времени - секунд, минут, часов... получать количество секунд. было бы идеально, если бы отсчетное время (стартовое) для этих часов можно было бы задавать макросом.
Я думаю, многим пригодится.
|
|
|
|
|
 |
Ответов
|
Dec 21 2010, 10:49
|
Знающий
   
Группа: Участник
Сообщений: 537
Регистрация: 22-02-06
Пользователь №: 14 594

|
QUOTE (zltigo @ Dec 21 2010, 15:47)  Для начала нужно понять, что к ARM Ваш вопрос отношения не имеет. А потом таки ознакомиться со стандартной сишной библиотекой. Узнаете много интересного и не только о времени. К ARM может и не имеет, а к STM32 все таки имеет :-) как в других чипах сделано RTC не знаю да, что то не догадался в time.h посмотреть. Вроде даже могло бы и работать, если бы оно не требовало heap (если я правильно понял): gmtime. И второе что не хорошо, что начало отсчета берется в 1980г... Вот один вариант накопал без данных минусов - вроде работает, но вопрос в том - не всплывет ли какая ошибка со временем. Хотелось бы проверенный рекомендованный вариант CODE #include <Time.h>
#define YEAR 2010 const int days[12]={31,28,31,30,31,30,31,31,30,31,30,31}; /******************************************************************************* * Function Name : isLeapYear * Description : ÅжÏÊÇ·ñΪÈòÄê * Input : Äê·Ý * Output : None * Return : ÅжϽá¹û *******************************************************************************/ unsigned char isLeapYear(unsigned short year) { if( ( (year%4==0) && (year%100!=0) ) || (year%400==0) ) { return 1; }
return 0; }
/******************************************************************************* * Function Name : Date2Sec * Description : ÈÕÆÚʱ¼äת³É2000Äê1ÔÂ1ÈÕÆðʼµÄÃëÊý (ÓÐЧʱ¼äΪ2000¡«2135Äê) * Input : ÈÕÆÚʱ¼ä½á¹¹Ìå * Output : * Return : ÃëÊý *******************************************************************************/ unsigned long Calendar_Date2Sec(tm d) { unsigned long sum = 0; //×ÜÃëÊý unsigned short i;
//ÀÛ¼ÆÒÔÍù¸÷ÄêµÄÌìÊý for(i=YEAR; i<d.tm_year; i++) { sum += 365; if(isLeapYear(i)) {//ÈòÄê¶àÒ»Ìì sum += 1; } }
//ÀۼƵ±ÄêÒÔÍù¸÷ÔµÄÌìÊý for(i=1; i<d.tm_mon; i++) { sum += days[i-1]; }
if(d.tm_mon>2) { if(isLeapYear(d.tm_year)) {//ÈòÄê¶àÒ»Ìì sum += 1; } }
//ÀۼƵ±Äêµ±ÔµÄÕûÌìÊý sum += d.tm_mday-1;
//ת»»³ÉÃë sum = sum*24*60*60; //¼Óµ±ÌìµÄСʱ£¬·ÖÖÓ£¬Ãë sum += d.tm_hour*60*60 + d.tm_min*60 + d.tm_sec;
//·µ»Ø×ÜÃëÊý return sum; }
/******************************************************************************* * Function Name : Sec2Date * Description : 2000Äê1ÔÂ1ÈÕÆðÃëÊýת³ÉÈÕÆÚʱ¼ä (ÓÐЧʱ¼äΪ2000¡«2135Äê) * ʱ¼ä×ßµ½2136-02-07 06:28:15»á·µ»Ø2000ÄêÆðʼʱ¼ä * Input : ÃëÊý * Output : ÈÕÆÚʱ¼ä½á¹¹Ìå * Return : *******************************************************************************/ tm Calendar_Sec2Date(unsigned long sec) { tm d={YEAR,1,1,0,0,0}; unsigned short ds,sum;
ds=sec/(24*60*60); //¾¹ýµÄÌìÊý
sec-=ds*(24*60*60); //²»¹»1ÌìµÄÃëÊý d.tm_hour=sec/(60*60); //Сʱ
sec-=d.tm_hour*(60*60); d.tm_min=sec/60; //·ÖÖÓ
sec-=d.tm_min*60; d.tm_sec=sec; //ÃëÖÓ
//¼ÆËãÓжàÉÙÄê while(1) { sum=365;
if(isLeapYear(d.tm_year)) {//ÈòÄê¶àÒ»Ìì sum+=1; }
if(ds<sum) {//²»×ãÒ»ÄêÁË break; }
d.tm_year++; ds-=sum; }
//¼ÆËãÓжàÉÙÔ while(1) { sum=days[d.tm_mon-1];
if(d.tm_mon==2) { if(isLeapYear(d.tm_year)) {//ÈòÄê¶àÒ»Ìì sum += 1; } }
//if(ds+1<sum) 2009/7/17Ð޸ģ¬Ôµ×ÌìÊýÒç³ö»á³ö´í if(ds < sum) {//²»×ãÒ»ÔÂÁË d.tm_mday+=ds; break; }
d.tm_mon++; ds-=sum; }
//¼ÆËãÐÇÆÚ¼¸ 0-ÐÇÆÚÈÕ,...,6-ÐÇÆÚÁù if (d.tm_mon==1 || d.tm_mon==2)
d.tm_wday = (d.tm_mday + 2*(d.tm_mon+12) + 3*(d.tm_mon+13)/5 + d.tm_year + ((d.tm_year-1)/4) - (d.tm_year-1)/100 + (d.tm_year-1)/400) % 7;
else
d.tm_wday = (d.tm_mday + 1 + 2*d.tm_mon + 3*(d.tm_mon+1)/5 + d.tm_year + (d.tm_year/4) - d.tm_year/100 + d.tm_year/400) % 7;
return d; } комменты на непонятном языке и непонятной кодировке - не мое
|
|
|
|
|
Dec 21 2010, 11:28
|
Знающий
   
Группа: Участник
Сообщений: 537
Регистрация: 22-02-06
Пользователь №: 14 594

|
Цитата(zltigo @ Dec 21 2010, 17:00)  Ну так дайте хипу памяти, что-бы struct tm влезла. Или подправьте пару строк в библиотечном вариант под работу со статической структурой. У меня rtos и 4к памяти (32F100C4), не разгуляешься, а gmtime потребовала какое то безумное количество байт выделить:-) если не сложно, дайте ссылку на исходник gmtime. Цитата(zksystem @ Dec 21 2010, 16:12)  [attachment=51390:rtc.rar] Спасибо!
|
|
|
|
|
Jan 4 2011, 15:00
|

embedder
  
Группа: Свой
Сообщений: 264
Регистрация: 11-05-05
Из: Казань
Пользователь №: 4 911

|
Цитата(kan35 @ Jan 3 2011, 19:44)  Если ставить стартовый год 2010 - не работает корректно перевод календаря в счетчик. Если 2000г, то все хорошо. Это так критично?
--------------------
Мечты стареют куда быстрее мечтателей… Стивен Кинг. "Ловец снов"
|
|
|
|
|
Jan 11 2011, 03:04
|
Знающий
   
Группа: Участник
Сообщений: 537
Регистрация: 22-02-06
Пользователь №: 14 594

|
Цитата(zksystem @ Jan 4 2011, 21:00)  Это так критично? во первых, может быть я не прав и делал что то не так ну а если это действительно так - то чтобы это было известно
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|