Форум РадиоКот https://radiokot.ru/forum/ |
|
stm32f030. как считать день недели ? https://radiokot.ru/forum/viewtopic.php?f=59&t=144211 |
Страница 1 из 1 |
Автор: | OlegEk [ Вт апр 11, 2017 23:20:47 ] |
Заголовок сообщения: | stm32f030. как считать день недели ? |
Здравствуйте уважаемые коты! устройство: таймер с различным поведением по будням и выходным встроенная клавиатура и дисплей проблемы с конфигурацией и запуском нет всё хорошо настраивается и работает секунды, минуты, часы, дни, месяцы и годы изменяются автоматически как положено и даже дни недели но вот с этими днями у меня и возникла засада дни недели не привязаны к дате, их нужно настраивать вручную т.е. можно в настройках указать что сегодня среда, а если хочется, то и пятница и дальше эти дни будут тикать как и положено а хочется получить функционал как в любых самых примитивных электронных часах с датой: меняешь дату - день недели меняется автоматически кроме того, хочется защитится от тупых ошибок ввода даты типа 29/02/17 для сотой серии вроде всё проще, там ртц имеет одну большую чиселку, с которой как мне кажется проще работать даже дату можно увеличить просто увеличив эту чиселку, и она преобразуется корректно а вот в 030 серии всё это хранится отдельными значениями подозреваю что я не первый столкнулся с такой задачей, но поиск к сожалению не дал ответов Буду благодарен если подскажите решения, или хотя бы направления куда смотреть Использую HAL, но другие решения тоже рассматриваю ![]() |
Автор: | Reflector [ Ср апр 12, 2017 00:46:30 ] |
Заголовок сообщения: | Re: stm32f030. как считать день недели ? |
Преобразовываешь дату в количество дней относительно начала какого-то года, если 1 января было понедельником, остается лишь взять остаток от деления на 7... |
Автор: | OlegEk [ Ср апр 12, 2017 07:20:27 ] |
Заголовок сообщения: | Re: stm32f030. как считать день недели ? |
Решение очевидное, но как это сделать с учётом високосных годов ? Да и просто учесть что в разных месяцах разное количество дней ? |
Автор: | RoboC [ Ср апр 12, 2017 08:25:50 ] |
Заголовок сообщения: | Re: stm32f030. как считать день недели ? |
Насколько мне помнится в формуле учтен высокосный год. Гуглится на ура.. // формула для вычисления дня недели по дате (ru.wikipedia.org) // a = (14 - месяц) / 12 // y = год - a // m = месяц + 12 * a - 2 //ДеньНедели = (7000 + (день + y + y / 4 - y / 100 + y / 400 + (31 * m) / 12)) ОСТАТОК 7 Вот еще одна формула вычисления дня недели. dayOfWeek = (year+(int)(year4)+ mounth + day) % 7; где - dayOfWeek - число от нуля до 7, соответсвует дню недели (0 - вс,1-пн, ...) year - год (int)(year/4) - целая часть от четверти года(математики, простите за int) mounth - число, соответствующее месяцу январь - 4(високосный) 5(невисокосный) февраль - 0(високосный) 1(невисокосный) март - 1 апрель - 4 май - 6 июнь - 2 июль - 4 август - 0 сентябрь - 3 октябрь - 5 ноябрь - 1 декабрь - 3 day - число дня в месяце Итак, в моем примере dayOfWeek = (1980 + 495 + 0 + 17 ) % 7 = 0(воскресенье) |
Автор: | OlegEk [ Ср апр 12, 2017 08:34:54 ] |
Заголовок сообщения: | Re: stm32f030. как считать день недели ? |
RoboC писал(а): январь - 4(високосный) 5(невисокосный) февраль - 0(високосный) 1(невисокосный) А как это учитывать? По таблице ? |
Автор: | RoboC [ Ср апр 12, 2017 09:04:33 ] |
Заголовок сообщения: | Re: stm32f030. как считать день недели ? |
В первой формуле он учтен. Как узнать что год высокосный? Или по таблице ![]() |
Автор: | alair [ Вт май 02, 2017 10:37:44 ] |
Заголовок сообщения: | Re: stm32f030. как считать день недели ? |
#define SEC_A_DAY 86400 typedef struct { uint16_t year; uint8_t mon; uint8_t mday; uint8_t hour; uint8_t min; uint8_t sec; uint8_t wday; } RTC_cal; // Функция переводит счетный регистр RTC в дату и время void timer_to_cal (uint32_t timer, RTC_cal * RTC_time) { uint32_t a; uint8_t b; uint8_t c; uint8_t d; uint32_t time; time = timer%SEC_A_DAY; // секунд с начала суток a = ((timer+43200)/(86400>>1)) + (2440587<<1) + 1; // 86400 - сек в сутках a>>=1; // а - кол-во суток от 1970г + 2440587.5 RTC_time->wday = a%7; a+=32044; // а - кол-во суток от 1970г + 2472631.5 b=(4*a+3)/146097; // 146097 - кол-во суток за 400 лет. b - кол-во веков от 1 марта -4800 года a=a-(146097*b)/4; c=(4*a+3)/1461; // c - лет после 1 марта 1900-го года, 2100-го и др невисокосных Григ. a=a-(1461*c)/4; // 1461 - кол-во дней за 4 года. a - кол-во дней с 1-го марта d=(5*a+2)/153; // месяц, начиная с марта RTC_time->mday=a-(153*d+2)/5+1; RTC_time->mon=d+3-12*(d/10); RTC_time->year=100*b+c-4800+(d/10); RTC_time->hour=time/3600; RTC_time->min=(time%3600)/60; RTC_time->sec=(time%3600)%60; } // Аргументы: дата и время, результат - в счетный регистр RTC uint32_t cal_to_timer (RTC_cal * RTC_time) // учесть пояс и летнее время { uint8_t a; uint16_t y; uint8_t m; uint32_t Uday; uint32_t time; a=((14-RTC_time->mon)/12); y=RTC_time->year+4800-a; m=RTC_time->mon+(12*a)-3; Uday=(RTC_time->mday+((153*m+2)/5)+365*y+(y/4)-(y/100)+(y/400)-32045)-2440588; time=Uday*86400; time+=RTC_time->sec+RTC_time->min*60+RTC_time->hour*3600; return time; } //************************************************************************** Да, большая чиселка, как в 100-й серии гораздо удобнее. Но имея набор отдельных минут, часов итд, как в stm32f030 или ds3107 итп, можно используя данные функции, конвертнуть эти данные в большую чиселку (uint32_t) и обратно и на выходе у вас будет правильный день недели. Проверено - работает. |
Автор: | DMITRIY C++ [ Пт фев 02, 2018 06:22:50 ] |
Заголовок сообщения: | Re: stm32f030. как считать день недели ? |
В функции: void timer_to_cal (uint32_t timer, RTC_cal * RTC_time) Точно нет ошибки вычисления дня недели? Вчера решил применить ее в будильнике который должен сробатывать только по будням но утром обнаружил, что он перепрыгнул с четверга на субботу. Я вечером еще конечно проверю у себя код. |
Автор: | DMITRIY C++ [ Пт фев 02, 2018 07:00:05 ] |
Заголовок сообщения: | Re: stm32f030. как считать день недели ? |
Извиняюсь ошибка была у меня )) функция работает правильно. |
Страница 1 из 1 | Часовой пояс: UTC + 3 часа |
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group http://www.phpbb.com/ |