|
Злополучная функция what_day(), Вычисление дня недели |
|
|
|
Jun 6 2008, 07:11
|
Знающий
   
Группа: Свой
Сообщений: 589
Регистрация: 24-04-05
Пользователь №: 4 447

|
Для инициализации Real Time Clock возникла необходимость вычисления дня недели по дате. Функция достаточно простая: Код //---------------------------------------------------------------------------- // Вычисления дня недели по дате // Все деления целочисленные (остаток отбрасывается). // Результат: 0 — воскресенье, 1 — понедельник и т. д. //---------------------------------------------------------------------------- unsigned char what_day(unsigned int year, unsigned char month, unsigned char date) { unsigned char a = (14 - month) / 12; unsigned int y = year - a; unsigned char m = month + 12*a - 2; return (7000 + (date + y + y/4 - y/100 + y/400 + (31*m)/12 ))% 7; } Но по какой-то непонятной причине вызов ее приводит к глюкам программы. В частности, при входе в пункт меню невозможно из него выйти, при этом программа реагирует не так как задумано. Должен сказать, что проект использует ОС (scmRTOS) и ОЗУ использовано на 90%. Контроллер Mega324P (2кБ ОЗУ). Отладочными средствами (JTAG) пользоваться не представляется возможным. Это похоже на переполнение стека. Но. Почему это происходит, если вызов достаточно простой функции вставить в начале функции main (до запуска ОС): Код int main() { what_day(2008, 6, 6); ..................... Больше нигде в процессах она не используется. Пробовал менять размеры CSTACK (100...200) и RSTACK (32...64). Не помогло. Думаю менять контроллер на AT90USB1287. Но сделаю это в последнюю очередь. Может быть есть другой способ вычисления дня недели? Какие будут предложения?
|
|
|
|
|
 |
Ответов
|
Jul 10 2008, 16:22
|
Знающий
   
Группа: Свой
Сообщений: 589
Регистрация: 24-04-05
Пользователь №: 4 447

|
Вот еще один пример до кучи. Вариация на тему "Вычисление дня недели". Найдено на microchip.com. Код __flash const unsigned char Table[13]={0,0,3,3,6,1,4,6,2,5,0,3,5}; unsigned int CurrentYear; unsigned char Month, Day;
/********************************************************* * Test Program for the routine GetDayofWeek() *********************************************************/ void main(void) { char Temp; CurrentYear = 1998; //Date : 21 September 1998 Month = 9; Day = 21; Temp = GetDayofWeek();// Result stored in Temp do{} while(1); }
/**************************************************************** * GetDayofWeek * This routine calculate the Day(Sunday, Monday,...Saturday) of * week when a Date(year, Month, Day) is given. * Input : Year, Month and Day which in this routine is used * as global variable. * Output Variable : 0 to 6(which correspond to Sunday to Saturdaday * respectively) if the input is acceptable, else a value 8 is return *****************************************************************/ unsigned char GetDayofWeek(void) { unsigned int TempYear; unsigned char AccValue; if(CheckValidInput(CurrentYear)!= OK) // Return Error if input not Valid return Error; TempYear = 1990; //Comparation start with year 1990 AccValue = 0; //Init AccValue to 0 // If TempYear is a leap year AccValue +2, else AccValue+1 while(TempYear != CurrentYear) { AccValue++; if(IsLeapYear(TempYear)) AccValue++; TempYear++; } if(Month > 2) { if(IsLeapYear(TempYear)==1) AccValue++; } AccValue += Table[Month]; AccValue += Day; AccValue= AccValue%7; return(AccValue); } /************************************************************************* * CheckValidInput * Return a '1' if the input is within the required range. Else * return a '0'. * * Input Variable : 16Bit Unsigned Int * Output Varible : '1' if input ranges between 1990 & 2099 inclusively ***************************************************************************/ unsigned char CheckValidInput(unsigned int Input) { if(Input >= 1990 && Input <= 2099) return OK; else return !OK; }
/************************************************************************* * IsLeapYear * Return a '1' if the input is a leap year. Else return a '0' * * Input Variable : 16Bit Unsigned Int * Output Varible : '1' if is a leap year, else '0'. ***************************************************************************/ unsigned char IsLeapYear(unsigned int Year) { Year=Year&0x0003; if(Year==0) return 1; else return 0; } /*************************************************************************/
|
|
|
|
Сообщений в этой теме
alux Злополучная функция what_day() Jun 6 2008, 07:11 MrYuran интересно, а куда она возвращает результат?
Кодint... Jun 6 2008, 08:08 alux Цитата(MrYuran @ Jun 6 2008, 11:08) интер... Jun 6 2008, 08:41 GetSmart Листинг кода посмотрите, в MAP-файле должен указыв... Jun 6 2008, 08:52 alux Цитата(GetSmart @ Jun 6 2008, 11:52) Лист... Jun 6 2008, 09:47 GetSmart В листинге нет процедуры ??what_day. Дайте листинг... Jun 6 2008, 10:02 alux Цитата(GetSmart @ Jun 6 2008, 13:02) Я не... Jun 6 2008, 10:23 GetSmart Прерывания запретите перед вызовом этой процедуры.... Jun 6 2008, 10:33 alux Вызов идет в начале main(). Естественно, прерывани... Jun 6 2008, 10:45 MrYuran Насколько я понимаю, 0х8f это не совсем 100, верне... Jun 6 2008, 10:53 alux Цитата(MrYuran @ Jun 6 2008, 13:53) 0х8f ... Jun 6 2008, 11:16 IgorKossak ЦитатаОтладочными средствами (JTAG) пользоваться н... Jun 6 2008, 11:38 vet Коллеги, какая нехватка ОЗУ? три параметра, три пе... Jun 6 2008, 11:41 alux Цитата(vet @ Jun 6 2008, 14:41) Чип помен... Jun 6 2008, 12:08  rezident Цитата(alux @ Jun 6 2008, 18:08) Изначаль... Jun 6 2008, 12:20 rezident Совет из области паранойи, но все же попробуйте пр... Jun 6 2008, 11:47 alux Если это хоть как-то наведет на мысли... Глюк проя... Jun 6 2008, 12:41 alux Это выходит за всякие рамки понимания и попахивает... Jun 6 2008, 15:52 sKWO Цитата(alux @ Jun 6 2008, 11:11) Но по ка... Jun 6 2008, 19:21 alux Цитата(sKWO @ Jun 6 2008, 22:21) Не помог... Jun 6 2008, 21:19  sKWO Цитата(alux @ Jun 7 2008, 01:19) Не понял... Jun 7 2008, 06:02 Flasher Недавно в яре натолкнулся под авр использовал функ... Jun 6 2008, 19:38 Andreas1 Цитата(Flasher @ Jun 6 2008, 23:38) Недав... Jun 7 2008, 13:40 vet Посмотрите, какие регистры использует подпрограмма... Jun 7 2008, 04:51 AlexG Если у вас scmRTOS, то размеры каких стеков вы кру... Jun 7 2008, 13:24 GetSmart Цитата(alux)Проблема решилась частично: если вызва... Jun 7 2008, 14:00 alux Цитата(GetSmart @ Jun 7 2008, 17:00) Нуже... Jun 7 2008, 15:55 GetSmart Вызов функции деления до сих пор присутствует.
Ещ... Jun 7 2008, 17:55 alux Цитата(GetSmart @ Jun 7 2008, 20:55) Вызо... Jun 7 2008, 21:09 GetSmart Тогда выкладывайте HEX-файл. Функция деления - она... Jun 7 2008, 21:48 alux Цитата(GetSmart @ Jun 8 2008, 00:48) Тогд... Jun 7 2008, 23:21  sKWO Цитата(alux @ Jun 8 2008, 03:21) Выкладыв... Jun 8 2008, 19:36   alux Цитата(sKWO @ Jun 8 2008, 22:36) Если я е... Jun 9 2008, 08:18 GetSmart Так и не понял косяк. Со стеком не может быть проб... Jun 8 2008, 09:49 alux Цитата(GetSmart @ Jun 8 2008, 12:49) Каже... Jun 8 2008, 19:29 GetSmart Ещё как вариант, нужно сравнить два листинга с про... Jun 8 2008, 21:53 alux Этот глюк выпил достаточно моей крови... Решил д... Jun 11 2008, 15:03 GetSmart Цитата(alux)Так как в отдельный момент времени в п... Jun 11 2008, 23:15 alux Цитата(GetSmart @ Jun 12 2008, 02:15) Кла... Jun 12 2008, 06:30 GetSmart Цитата(alux)Не понял на счет глюка, я же прерывани... Jun 12 2008, 11:10 alux Цитата(GetSmart @ Jun 12 2008, 14:10) Что... Jun 12 2008, 11:31 alux ...И вновь продолжается бой.
Ребята, извините, п... Jun 13 2008, 08:04 sKWO Цитата(alux @ Jun 13 2008, 12:04) Код els... Jun 13 2008, 08:57 GetSmart Цитата(alux @ Jun 13 2008, 14:04) Код#ifd... Jun 13 2008, 17:42  alux Цитата(GetSmart @ Jun 13 2008, 20:42) Ран... Jun 13 2008, 18:45 alux Код// Alternation key code
#define ALTKEY 26 /... Jun 13 2008, 09:39 sensor_ua Тогда ещё один вариант
Код //Regra de Zeller
unsig... Jul 12 2008, 04:56 GetSmart Цитата(sensor_ua)Кодreturn( nWDay < 0 ? ... Jul 12 2008, 10:32 sensor_ua ЦитатаМожно я упрощу?
это к автору - Regra de Zell... Jul 12 2008, 10:45
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|