Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: STM32 RTC->календарь
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
kan35
В общем камень STM32 и требуется организовать часы реального времени на его RTC, пока надо час:мин:сек, это не сложно, но в перспективе надо получить полноценный календарь.
Нужны будут 2 функции, которые
1. Из 32 битного счетчика секунд получала бы структуру с секундами, минутами, часами .... годом.
2. Из стандартного времени - секунд, минут, часов... получать количество секунд.
было бы идеально, если бы отсчетное время (стартовое) для этих часов можно было бы задавать макросом.

Я думаю, многим пригодится.
zltigo
QUOTE (kan35 @ Dec 21 2010, 15:30) *
Я думаю, многим пригодится.

Для начала нужно понять, что к ARM Ваш вопрос отношения не имеет. А потом таки ознакомиться со стандартной сишной библиотекой. Узнаете много интересного и не только о времени.

zksystem
Цитата(kan35 @ Dec 21 2010, 15:30) *
В общем камень STM32 и требуется организовать часы реального времени на его RTC, пока надо час:мин:сек, это не сложно, но в перспективе надо получить полноценный календарь.


Нажмите для просмотра прикрепленного файла

...
#include "rtc.h"

...

int main (void)
{
...

RTC_t rtc;
...

rtc_init();
rtc_gettime(&rtc);

printf("System date/time:\x1b[37m %0.2d/%0.2d/%d %0.2d:%0.2d:%0.2d\r\n", rtc.mday, rtc.month, rtc.year, rtc.hour, rtc.min, rtc.sec);

...
}






topkin
Цитата(kan35 @ Dec 21 2010, 15:30) *
В общем камень STM32 и требуется организовать часы реального времени на его RTC, пока надо час:мин:сек, это не сложно, но в перспективе надо получить полноценный календарь.
Нужны будут 2 функции, которые
1. Из 32 битного счетчика секунд получала бы структуру с секундами, минутами, часами .... годом.
2. Из стандартного времени - секунд, минут, часов... получать количество секунд.
было бы идеально, если бы отсчетное время (стартовое) для этих часов можно было бы задавать макросом.

Я думаю, многим пригодится.

Есть стандартная от ST, но что то она громоздкая. Сам не пользовал, надеюсь получше написана, чем драйвера периферии от ST. Ну вообще то поиском пользоваться нужно уметь! Брать ТУТ

Цитата(zksystem @ Dec 21 2010, 16:12) *

Интересно, спасибо!
kan35
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;
}

комменты на непонятном языке и непонятной кодировке - не мое
zltigo
QUOTE (kan35 @ Dec 21 2010, 16:49) *
Вроде даже могло бы и работать, если бы оно не требовало heap (если я правильно понял)

Ну так дайте хипу памяти, что-бы struct tm влезла. Или подправьте пару строк в библиотечном вариант под работу со статической структурой.




kan35
Цитата(zltigo @ Dec 21 2010, 17:00) *
Ну так дайте хипу памяти, что-бы struct tm влезла. Или подправьте пару строк в библиотечном вариант под работу со статической структурой.

У меня rtos и 4к памяти (32F100C4), не разгуляешься, а gmtime потребовала какое то безумное количество байт выделить:-)
если не сложно, дайте ссылку на исходник gmtime.

Цитата(zksystem @ Dec 21 2010, 16:12) *

Спасибо!
kan35
Если ставить стартовый год 2010 - не работает корректно перевод календаря в счетчик.
Если 2000г, то все хорошо.
KnightIgor
Цитата(kan35 @ Jan 3 2011, 17:44) *
Если ставить стартовый год 2010 - не работает корректно перевод календаря в счетчик.
Если 2000г, то все хорошо.

Я тут под впечатлением этой темы покрутил свою отладочную MCBSTM32 и накропал поддержку календаря с использованием счетчика RTC. У меня проблем с годом нет.

Аппаратно-независимая часть выделена мной в HAL_Calender.*, что и прилагаю. Разработано с использованием time.h из RTL библиотеки KEIL.
Ориентировано на немецкие дни недели и европейский счет дней с понедельника. Установить #define LOCALE_US, чтобы полагать, что первый день недели - это воскресенье, или можно переработать нафиг всё под свой вкус.
zksystem
Цитата(kan35 @ Jan 3 2011, 19:44) *
Если ставить стартовый год 2010 - не работает корректно перевод календаря в счетчик.
Если 2000г, то все хорошо.

Это так критично?
KnightIgor
Цитата(KnightIgor @ Jan 4 2011, 18:03) *
Аппаратно-независимая часть выделена мной в HAL_Calender.*, что и прилагаю. Разработано с использованием time.h из RTL библиотеки KEIL.


Глянул и обнаружил, что уже 9 скачиваний архива с поддержкой календаря. Работает?
kan35
Цитата(zksystem @ Jan 4 2011, 21:00) *
Это так критично?

во первых, может быть я не прав и делал что то не так
ну а если это действительно так - то чтобы это было известно
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.