Easyelectronics.ru

Электроника для всех
Текущее время: 24 апр 2018, 02:11

Часовой пояс: UTC + 5 часов



    • JLCPCB - Платы прототипов всего за 2$ c бесплатной доставкой (при первом заказе)
    • 10 PCBs за $2 для 2 слоев, $15 для 4 слойной, $74 для 6 слойной платы.
    • Крупнейший китайский производитель прототипных плат. 290000+ клиентов & 8000+ заказов в день!
    • LCSC - Крупнейший китайский онлайн магазин радиодеталей.

Начать новую тему Ответить на тему  [ Сообщений: 6 ] 
Автор Сообщение
 Заголовок сообщения: Считать время по пройденным миллисекундам.
СообщениеДобавлено: 04 дек 2017, 14:45 
Заглядывает иногда

Зарегистрирован: 17 фев 2016, 17:31
Сообщения: 197
В системе нет RTC.
Я подумал сделать так. В начале логирования я ввожу стартовое реальное время и включаю счетчик миллисекунд.
Во время логирования, помимо данных, я сохраняю временную метку - пройденные миллисекунды.
И в конце логирования я могу вычислить реальное время по пройденным милисекундам.
Код:
uint32_t MillisecsToSeconds (uint32_t millisecs)
{
    return ( millisecs / 1000);
}

uint32_t MillisecsToMinutes (uint32_t millisecs)
{
    return ( millisecs / 60000); 
}

uint32_t MillisecsToHours (uint32_t millisecs)
{
    return ( millisecs / 3600000);   
}

uint32_t MillisecsToDays (uint32_t millisecs)
{
    return ( millisecs / 86400000);   
}

void ElapsedDate(sRTC start_date, uint32_t millisecs, sRTC *elapsed_date)
{
    elapsed_date->rtcSec = start_date.rtcSec + MillisecsToSeconds(millisecs)
    elapsed_date->rtcMin = start_date.rtcMin + MillisecsToMinutes(millisecs);
    elapsed_date->rtcHour = start_date.rtcHour + MillisecsToHours(millisecs);
    elapsed_date->rtcDay = start_date.rtcDay + MillisecsToDays(millisecs);
}


Но потом я заметил что функция не учитывает переполнение секунд, минут, дней. И вот тут я туплю - как оптимальней это сделать?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Считать время по пройденным миллисекундам.
СообщениеДобавлено: 04 дек 2017, 15:06 
Старожил

Зарегистрирован: 16 ноя 2012, 07:47
Сообщения: 2558
Например так:
Код:
#define JD0                  2451911         // дней до 01 янв 2001 ПН

typedef struct {
         uint8_t      Sec;            //Секунды
         uint8_t      Min;            //Минуты
         uint8_t      Hours;            //Часы
         uint8_t      Day;            //День недели (1-7)
         uint8_t      Date;            //День
         uint8_t      Month;            //Месяц
         uint8_t      Year;            //Год
         int8_t      Temp_Int;         //Температура (целая часть) (-127-127)
         uint8_t      Temp_Fract;         //Дробная часть (0-3), каждая единица - 0.25°С
   List_RTC_Stat      Status;            //Статус часов
} _RTC_DATA_STRUCT;

uint32_t   TimeToCounter(_RTC_DATA_STRUCT * ftime)
{
   uint32_t   JDN;
   uint16_t   y;
   uint8_t      m, a;

   // Вычисление необходимых коэффициентов
   a = (14 - ftime->Month)/12;
   y = ftime->Year +2000 + 4800 - a;            //2000 т.к. у нас дата идет от 0 до 99
   m = ftime->Month + (12*a) - 3;
   // Вычисляем значение текущего Юлианского дня
   JDN = ftime->Date;
   JDN+= (153*m + 2)/5;
   JDN+= 365*y;
   JDN+= y/4;
   JDN+= -y/100;
   JDN+= y/400;
   JDN-= 32045;
   JDN-= JD0;                              // так как счетчик у нас нерезиновый, уберем дни которые прошли до 01 янв 2001
   JDN*= 86400;                           // переводим дни в секунды
   JDN+= (ftime->Hours*3600);                  // и дополняем его секундами текущего дня
   JDN+= (ftime->Min*60);
   JDN+= (ftime->Sec);
   // итого имеем количество секунд с 00-00 01 янв 2001
   return JDN;
}
void   CounterToTime(uint32_t counter,_RTC_DATA_STRUCT* ftime)
{
   uint32_t ace;
   uint8_t b,d,m;

   ace = (counter/86400) + 32044 + JD0;
   b = (4*ace + 3)/146097;
   ace = ace - ((146097*b)/4);
   d = (4*ace + 3)/1461;
   ace = ace - ((1461*d)/4);
   m = (5*ace + 2)/153;

   ftime->Date = ace - ((153*m+2)/5) + 1;
   ftime->Month = m + 3 - (12*(m/10));
   ftime->Year = 100*b + d-4800 + (m/10) - 2000;
   ftime->Hours = (counter/3600)%24;
   ftime->Min = (counter/60)%60;
   ftime->Sec = (counter%60);
}

Сначала инициализируем счетчик через TimeToCounter, затем берем текущую дату/время через CounterToTime. Счетчика секунд uin32_t хватит на 100+ лет. Вам надо лишь мс добавить.
У себя использую вместе с RTC для замера продолжительности процесса, что-то вроде:
Инициализация счетчика (стартовое время процесса)
Код:
FirstStdData.StartTimeSec   = TimeToCounter(&RTC_Data);   // Текущее время - время старта

Код:
         if ( AutoWorkData.Stat != AUTO_WORK_MODE_STOP )   // автоматика работает
         {
            // Прошло времени
            uint32_t temp = TimeToCounter(&RTC_Data) - FirstStdData.StartTimeSec;
            FirstStdData.ExpTime.Hours   = (temp/3600);
            FirstStdData.ExpTime.Min   = (temp/60)%60;
            FirstStdData.ExpTime.Sec   = (temp%60);

            hItem = WM_GetDialogItem(pMsg->hWin, ID_TEXT_2);
            sprintf((char *)TempBuf, "%02u:%02u:%02u",FirstStdData.ExpTime.Hours,FirstStdData.ExpTime.Min,FirstStdData.ExpTime.Sec);
            TEXT_SetText(hItem, (char const *)TempBuf);
         }

Т.к. счетчик берет отсчет с 2001 года, можно не боятся отрицательной суммы, разница всегда положительная.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Считать время по пройденным миллисекундам.
СообщениеДобавлено: 04 дек 2017, 15:54 
Заглядывает иногда

Зарегистрирован: 17 фев 2016, 17:31
Сообщения: 197
Hold писал(а):
Например так:

спасибо.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Считать время по пройденным миллисекундам.
СообщениеДобавлено: 04 дек 2017, 18:11 
Старожил
Аватара пользователя

Зарегистрирован: 14 апр 2014, 11:06
Сообщения: 1176
Откуда: Курск
Сделайте на юникстайм. Один счётчик. Никаких переполнений


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Считать время по пройденным миллисекундам.
СообщениеДобавлено: 04 дек 2017, 18:51 
Старожил
Аватара пользователя

Зарегистрирован: 22 июл 2017, 11:48
Сообщения: 1474
Операции деления для каждой единицы измерения будут занимать немало времени, особенно если нет аппаратного делителя.
Вычислять единицу "год" в системе без резервного батарейного питания - практически никогда не пригодится.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Считать время по пройденным миллисекундам.
СообщениеДобавлено: 05 дек 2017, 11:36 
Старожил

Зарегистрирован: 16 ноя 2012, 07:47
Сообщения: 2558
Ну, если у автора не F0, где нет аппаратного деления, то деление и остаток деления все же целочисленные операции и выполняются быстро.


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 6 ] 

Часовой пояс: UTC + 5 часов


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  

Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
Русская поддержка phpBB