[an error occurred while processing this directive]
перед циклом main() - InitNexttime(), внутри - Nexttime()
(«Телесистемы»: Конференция «Микроконтроллеры и их применение»)

миниатюрный аудио-видеорекордер mAVR

Отправлено alm 18 июля 2005 г. 16:37
В ответ на: Подскажите, как посчитать летнее и зимнее время в устройстве, которое работает от случая к случаю. В выбранном RTC такой функции нет. Оказалось не так тривиально на стыках месяцев. отправлено <font color=gray>oleg&kor</font> 18 июля 2005 г. 16:19


tiCurr,tiPrev - храняться в энергонезависимой памяти

/*------------------------------------------------------------------------------
NEXTTIME.C

Обработка переходов времени
------------------------------------------------------------------------------*/


// признак перехода на сезонное время в текущие сутки
bit fSeason;

// признаки перехода на сезонное время при выключенном состоянии
bit fSummer,fWinter;

// признак работы в активном режиме
bit fActive;

// признаки для запуска локальных задач
bit fProfile,fCurrent;

// признак выдачи команды на программирование модема
bit fSendAT;

void ClearNewTime(void)
{
boNewSec = boNewMin = boNewMnt = boNewHou = boNewDay = boNewMon = boNewYea = boTrue;
}

uchar PrevSoftMnt(void)
{
if (ibSoftMnt > 0) return(ibSoftMnt - 1);
else return(bMINUTES-1);
}

uchar PrevSoftHou(void)
{
if (ibSoftHou > 0) return(0);
else return(1);
}


uint PrevHardHou(void)
{
if (iwHardHou > 0) return(iwHardHou - 1);
else return(wHOURS-1);
}

uchar PrevSoftDay(void)
{
if (ibSoftDay > 0) return(0);
else return(1);
}


uchar PrevHardDay(void)
{
if (ibHardDay > 0) return(ibHardDay - 1);
else return(bDAYS-1);
}

uchar PrevSoftMon(void)
{
if (ibSoftMon > 0) return(0);
else return(1);
}


uchar PrevHardMon(void)
{
if (ibHardMon > 0) return(ibHardMon - 1);
else return(bMONTHS-1);
}

uchar PrevSoftTim(void)
{
if (ibSoftTim > 0) return(0);
else return(1);
}

/*
uint PrevHardTim(void)
{
if (iwHardTim > 0) return(iwHardTim - 1);
else return(wTIMES-1);
}
*/


// возвращает индекс текущего получаса
uchar GetHouIndex(void)
{
return(tiCurr.bHour*2 + tiCurr.bMinute/30);
}


// возвращает индекс на первый получас требуемых суток назад
uint PrevDayIndex(uchar bDay)
{
uchar i;
uint j;

// индекс на первый получас текущих суток
j = (wHOURS+iwHardHou-GetHouIndex()) % wHOURS;

// индексы на первые получасы суток назад
for (i=0; i // индекс на первый получас требуемых суток
return(j);
}

void MakeCurrHouCan(void)
{
uchar i;

for (i=0; i {
if ((GetDigitalDevice(i) != 0) && (GetDigitalDevice(i) != 12))
SetCanInt(mpwImpHouCan[ibSoftHou], i, 0xFFFF);
}
}


void MakeCurrTimPar(void)
{
}

// обработка перехода на следующий интервал
void ProcessNextTim(void)
{
SaveParTim(iwHardTim,ibSoftTim);

if (++iwHardTim >= wTIMES) iwHardTim = 0;
if (++ibSoftTim >= 2) ibSoftTim = 0;

memset(&mpreParBuff[ibSoftTim], '\0', sizeof(real)*wPARAMS);

MakeCurrTimPar();
}


// обработка перехода на следующие три минуты
void ProcessNextMnt(void)
{
memset(&mpwImpMntCan[(ibSoftMnt+1) % bMINUTES], '\0', sizeof(uint)*bCANALS);

ET0 = 0;
memcpy(&mpwImpCurrMntCan, &mpwImpMntCan[ibSoftMnt], sizeof(uint)*bCANALS);
if (++ibSoftMnt >= bMINUTES) ibSoftMnt = 0;
ET0 = 1;

MakeImpulse();

if (boQuickParam == boTrue) ProcessNextTim();
}


// обработка перехода на следующий получас
void ProcessNextHou(void)
{
// состояние: начало нового получаса
InfoTime();

// расчёт максимумов мощности за текущие сутки и месяц
MakeAllMaxPowNow();

// расчёт пределов опроса счётчиков
MakeLimits();

SaveImpHou(0,iwHardHou,ibSoftHou);

if (++iwHardHou >= wHOURS) iwHardHou = 0;
if (++ibSoftHou >= 2) ibSoftHou = 0;

memset(&mpwImpHouCan[ibSoftHou], '\0', sizeof(uint)*bCANALS);

MakeCurrHouCan();

if (boQuickParam == boFalse) ProcessNextTim();
}

// базовая программа обработки переходов времени
void ProcessTime(void)
{
// переход на следующую секунду
if (tiCurr.bSecond != tiPrev.bSecond)
{
if ((fActive == 1) && (enGlobal != GLB_PROGRAM))
{
if ((fProfile == 1) && (cbWaitQuery == 0))
{
if ((tiCurr.bMinute % 30)*60 + tiCurr.bSecond >= cbTimeoutHou)
{
boManual = boFalse;
fProfile = 0;
RunProfile((boControlTime == boTrue) && (ControlTime() == 1));
}
}
}

if ((fActive == 1) && (enGlobal != GLB_PROGRAM))
{
if ((fCurrent == 1) && (cbWaitQuery == 0))
{
if ((tiCurr.bMinute % 3)*60 + tiCurr.bSecond >= cbTimeoutMnt)
{
// fCurrent = 0;

#ifdef POWER
RunCurrent();
#endif
}
}
}
}


// переход на следующую минуту
if (tiCurr.bMinute != tiPrev.bMinute)
{
if (fActive == 1)
fSendAT = 1;

if ((fActive == 1) && (enGlobal == GLB_WORK))
{
if (cbShowTime >= 2)
ShowTimeNow();
else
cbShowTime++;
}
}


// переход на следующие три минуты
if ((tiCurr.bMinute % 3 == 0) && (tiPrev.bMinute % 3 != 0))
{
ProcessNextMnt();

// начало опроса цифровых счётчиков по трём минутам
if (fActive == 1) fCurrent = 1;

/* if ((fActive == 1) && (enGlobal != GLB_PROGRAM))
{
if ((fCurrent == 1) && (cbWaitQuery == 0))
{
// fCurrent = 0;

#ifdef POWER
RunCurrent();
#endif
}
} */
}


// переход на следующий получас
if ((tiCurr.bMinute % 30 == 0) && (tiPrev.bMinute % 30 != 0))
{
// флаг наступления нового получаса
boNewHou = boTrue;

// начало опроса цифровых счётчиков по получасам
if (fActive == 1) fProfile = 1;

if ((tiCurr.bDay == tiSummer.bDay) &&
(tiCurr.bMonth == tiSummer.bMonth) &&
(tiCurr.bHour == 2) && (fSeason == 0))
{
cbSummer++;

if (fActive == 1)
{
tiCurr.bHour = 3;
tiSetRTC = tiCurr;
SetCurrTimeDate();
}
else fSummer = 1;

fSeason = 1;

ProcessNextHou();
ProcessNextHou();
ProcessNextHou();
}
else
if ((tiCurr.bDay == tiWinter.bDay) &&
(tiCurr.bMonth == tiWinter.bMonth) &&
(tiCurr.bHour == 3) && (fSeason == 0))
{
cbWinter++;

if (fActive == 1)
{
tiCurr.bHour = 2;
tiSetRTC = tiCurr;
SetCurrTimeDate();
}
else fWinter = 1;

fSeason = 1;
}
else
if ((tiCurr.bDay == tiWinter.bDay) &&
(tiCurr.bMonth == tiWinter.bMonth) &&
(tiCurr.bHour == 2) && (fSeason == 1))
{ }
else
ProcessNextHou();
}


// переход на следующие сутки
if (tiCurr.bDay != tiPrev.bDay)
{
// флаг наступления новых суток
boNewDay = boTrue;

// программирование модема
ResetSendAT();

// обнуление признака перехода на сезонное времени в текущие сутки
fSeason = 0;

// рассчёт показаний счётчиков по месяцам
MakeCounters();

// рассчёт массивов индексов тарифов для каждого получаса текущих суток для всех блоков (для мощности и энергии)
MakeAllCurrTariffs();

SaveImpDay(0,ibHardDay,ibSoftDay);
SavePowDay(0,ibHardDay,ibSoftDay);

if (++ibHardDay >= bDAYS) ibHardDay = 0;
if (++ibSoftDay >= 2) ibSoftDay = 0;

memset(&mpimDayCan[ibSoftDay], '\0', sizeof(impulse)*bCANALS);
memset(&mppoDayGrp[ibSoftDay], '\0', sizeof(power)*bGROUPS);

// обработка брака по суткам
tiAlt = tiCurr;
MakeDefectDay(0);
}


// переход на следующий месяц
if (tiCurr.bMonth != tiPrev.bMonth)
{
SaveImpMon(0,ibHardMon,ibSoftMon);
SavePowMon(0,ibHardMon,ibSoftMon);
SaveCntMon(0,ibHardMon,ibSoftMon);

if (++ibHardMon >= bMONTHS) ibHardMon = 0;
if (++ibSoftMon >= 2) ibSoftMon = 0;

memset(&mpimMonCan[ibSoftMon], '\0', sizeof(impulse)*bCANALS);
memset(&mppoMonGrp[ibSoftMon], '\0', sizeof(power)*bGROUPS);

// обработка брака по месяцам
tiAlt = tiCurr;
MakeDefectMon(0);

cwPosCorrect = 0;
cwNegCorrect = 0;

// сохраняем признак совмещённых/раздельных суточных тарифных графиков за предыдущий месяц
boPublicPrev = boPublicCurr;
}


// переход на следующий год
if (tiCurr.bYear != tiPrev.bYear)
{
// рассчёт дат перехода на сезонное время
MakeDecret();
}
}

// начальная инициализация индексов
void MakeNexttime(void)
{
ibSoftMnt = 0;

ibSoftHou = 0;
iwHardHou = 0;

ibSoftDay = 0;
ibHardDay = 0;

ibSoftMon = 0;
ibHardMon = (*PGetCurrTimeDate()).bMonth - 1;

ibSoftTim = 0;
iwHardTim = 0;

cbSummer = 0;
cbWinter = 0;

ET0 = 0;
memset(&mpwImpMntCan[ibSoftMnt], '\0', sizeof(uint)*bCANALS);
ET0 = 1;

MakeCurrHouCan();

MakeCurrTimPar();
}

// программа обработки переходов в виртуальном времени
bit NexttimeOff(void)
{
uchar i;

cbWaitQuery = 0;

fProfile = 0;
fCurrent = 0;

fSeason = 0;

if (GetLabelXDATA() == 0)
return(1);
else
{
// увеличиваем счётчик включений питания
cbPowerOn++;
// сохраняем время выключения питания
tiPowerOff = tiCurr;

i = 0;
while (1)
{
ResetWDT();

// чтение текущего времени
tiKey = *PGetCurrTimeDate();
// копируем секунды для последующего сравнения
tiCurr.bSecond = tiKey.bSecond;

// сохраняем время включения питания
tiPowerOn = tiKey;

if (memcmp(&tiCurr, &tiKey, sizeof(time)) == 0)
return(1);

// перевод время в интервалом в минуту
if (++tiCurr.bMinute >= 60)
{
tiCurr.bMinute = 0;
if (++tiCurr.bHour >= 24)
{
tiCurr.bHour = 0;

// предельное время выключения питания
if (++i > 30) return(0);

tiAlt = tiCurr;
if (++tiCurr.bDay > DaysInMonth())
{
tiCurr.bDay = 1;
if (++tiCurr.bMonth > 12)
{
tiCurr.bMonth = 1;
tiCurr.bYear++;
}
}
}
}

// обработка переходов времени
ProcessTime();
/*
sprintf(szHi,"Дата %02bu.%02bu.%02bu",
tiCurr.bDay,
tiCurr.bMonth,
tiCurr.bYear);

sprintf(szLo,"Время %02bu:%02bu:%02bu",
tiCurr.bHour,
tiCurr.bMinute,
tiCurr.bSecond);
*/
sprintf(szHi," %02bu:%02bu %02bu.%02bu.%02bu ",
tiCurr.bHour,
tiCurr.bMinute,
tiCurr.bDay,
tiCurr.bMonth,
tiCurr.bYear);

sprintf(szLo," %02bu:%02bu %02bu.%02bu.%02bu ",
tiKey.bHour,
tiKey.bMinute,
tiKey.bDay,
tiKey.bMonth,
tiKey.bYear);

// запись прошедшего времени
tiPrev = tiCurr;
}
}
}

// программа обработки переходов в виртуальном времени с переходами на сезонное время
void InitNexttime(void)
{
if (GetLabelRTC() == 0) TestError(szBadRTC1);

PGetCurrTimeDate();
if (TrueCurrTimeDate() == 0) // TestError(szBadRTC2);
{
ShowHi(szAlarm);
ShowLo(szBadRTC2); LongBeep(); DelayMsg();
return;
}

fSummer = 0;
fWinter = 0;

NexttimeOff();

if (fSummer == 1)
{
if (++tiCurr.bHour >= 24)
{
tiCurr.bHour = 0;

tiAlt = tiCurr;
if (++tiCurr.bDay > DaysInMonth())
{
tiCurr.bDay = 1;
if (++tiCurr.bMonth > 12)
{
tiCurr.bMonth = 1;
tiCurr.bYear++;
}
}
}

tiSetRTC = tiCurr;
SetCurrTimeDate();
}

if (fWinter == 1)
{
if (tiCurr.bHour > 0)
tiCurr.bHour--;
else
{
tiCurr.bHour = 23;
if (tiCurr.bDay > 1)
tiCurr.bDay--;
else
{
if (tiCurr.bMonth > 1)
tiCurr.bMonth--;
else
{
tiCurr.bMonth = 12;
tiCurr.bYear--;
}

tiAlt = tiCurr;
tiCurr.bDay = DaysInMonth();
}
}

tiSetRTC = tiCurr;
SetCurrTimeDate();
}
}

// программа обработки переходов в реальном времени
void Nexttime(void)
{
if (GetLabelRTC() == 0) return;

PGetCurrTimeDate();
if (TrueCurrTimeDate() == 0) return;

if (tiCurr.bSecond != tiGetRTC.bSecond)
{
// чтение текущего времени
tiCurr = tiGetRTC;

if (enGlobal != GLB_PROGRAM)
{
fActive = 1;
ProcessTime();
}
else
{
fProfile = 0;
fCurrent = 0;

ClearNewTime();
}

// запись прошедшего времени
tiPrev = tiCurr;
}
}

// базовая программа обработки переходов времени
void ProcessTimeMnt(void)
{
// переход на следующие три минуты
if ((tiCurr.bMinute % 3 == 0) && (tiPrev.bMinute % 3 != 0))
ProcessNextMnt();
}


// программа обработки переходов в реальном времени
void NexttimeMnt(void)
{
ResetWDT();
if (GetLabelRTC() == 0) return;

PGetCurrTimeDate();
if (TrueCurrTimeDate() == 0) return;

if (tiCurr.bSecond != tiGetRTC.bSecond)
{
// чтение текущего времени
tiCurr = tiGetRTC;

if (enGlobal != GLB_PROGRAM)
ProcessTimeMnt();

// запись прошедшего времени
tiPrev = tiCurr;
}
}


Составить ответ  |||  Конференция  |||  Архив

Ответы


Отправка ответа

Имя (обязательно): 
Пароль: 
E-mail: 
NoIX ключ Запомнить

Тема (обязательно):
Сообщение:

Ссылка на URL: 
Название ссылки: 

URL изображения: 


Перейти к списку ответов  |||  Конференция  |||  Архив  |||  Главная страница  |||  Содержание  |||  Без кадра

E-mail: info@telesys.ru