|
Злополучная функция 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. Но сделаю это в последнюю очередь. Может быть есть другой способ вычисления дня недели? Какие будут предложения?
|
|
|
|
|
 |
Ответов
|
Jun 6 2008, 19:21
|

Местный
  
Группа: Участник
Сообщений: 355
Регистрация: 27-03-07
Из: Україна, Чуднів
Пользователь №: 26 530

|
Цитата(alux @ Jun 6 2008, 11:11)  Но по какой-то непонятной причине вызов ее приводит к глюкам программы. В частности, при входе в пункт меню невозможно из него выйти, при этом программа реагирует не так как задумано. Должен сказать, что проект использует ОС (scmRTOS) и ОЗУ использовано на 90%. Контроллер Mega324P (2кБ ОЗУ). Отладочными средствами (JTAG) пользоваться не представляется возможным. Это похоже на переполнение стека. Но. Почему это происходит, если вызов достаточно простой функции вставить в начале функции main (до запуска ОС): Код int main() { what_day(2008, 6, 6); ..................... Больше нигде в процессах она не используется. Пробовал менять размеры CSTACK (100...200) и RSTACK (32...64). Не помогло, не в этом причина . из Вашего мэп Код CSTACK DATA 00000100 - 000001FF 100 dse 0 RSTACK DATA 00000200 - 0000023F 40 dse 0 Теперь мысль, может бредовая но всё-же- может Вы запретили компилятору какие-то регистры в которых компилятор хранит остаток от деления? не знаю как ИАР но в код вижине остаток хранится в 26 регистре. Пример для КВ Код //========================================================= void prog3(char ch) { ch=ch+2; ch=ch/3; ch=ch%3; } void prog4(char ch) { ch=ch/3; ch=ch%3; }
??? Лишние инструкции ??? Оптимальнее было-бы так - _prog3: LD R30,Y SUBI R30,-LOW(2) ST Y,R30 _prog4: LD R26,Y LDI R30,LOW(3) RCALL __DIVB21U ST Y,R30 LD R26,Y LDI R30,LOW(3) RCALL __MODB21U ST Y,R30 ADIW R28,1 RET
--------------------
нельзя недооценивать предсказуемость глупости
|
|
|
|
|
Jun 6 2008, 21:19
|
Знающий
   
Группа: Свой
Сообщений: 589
Регистрация: 24-04-05
Пользователь №: 4 447

|
Цитата(sKWO @ Jun 6 2008, 22:21)  Не помогло, не в этом причина . из Вашего мэп Код CSTACK DATA 00000100 - 000001FF 100 dse 0 RSTACK DATA 00000200 - 0000023F 40 dse 0 Не понял. Что Вы имели в виду? Цитата(sKWO @ Jun 6 2008, 22:21)  Теперь мысль, может бредовая но всё-же- может Вы запретили компилятору какие-то регистры в которых компилятор хранит остаток от деления? Регистры я не трогаю. Заменил в функции операцию % 7 на -= 7: Код day = a + year + c + day;// % 7; while(day >= 7) day -= 7; return day; Проблема решилась частично: если вызвать эту функцию из main() , то глюк пропал. Но если вызвать ее из другой функции rtc_set_time(), то глюк имеет место быть... Не знаю что и думать. Варианты исчерпались. Пойду-ка я спать. PS2. Все! Наконец-то поборол глюк. Переписал в очередной раз функцию. Прям целая коллекция функций получилась  Код unsigned char what_day(unsigned int year, unsigned int month, unsigned int date) { signed int c=0; unsigned char day; if((date>=1)&&(date<=31)&&(month>=1)&&(month<=12)&&(year>=1582)&&(year<=4903)) { if(month < 3) { month += 10; // Месяц январь или февраль? year -= 1; } else { month -= 2; // Остальные месяцы while(year >= 100) { c++; // Вычисляем столетие year -= 100; // Находим год в столетии } day = (unsigned char)((26*month-2)/10 + date + (year>>2) + year + (c>>2) - 2*c); while(day >= 7) day -= 7; // Вычисляем день недели } } return day; } Сейчас все работает как положено. Хотя неприятный осадок остался... Нет ответов на вопросы - почему такое произошло?
Сообщение отредактировал alux - Jun 6 2008, 22:58
|
|
|
|
Сообщений в этой теме
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 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 defunct зато теперь у вас
1. целая коллекция рабочих и н... Jul 5 2008, 23:42 alux Вот еще один пример до кучи. Вариация на тему ... Jul 10 2008, 16:22 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
|
|
|