реклама на сайте
подробности

 
 
> Злополучная функция what_day(), Вычисление дня недели
alux
сообщение Jun 6 2008, 07:11
Сообщение #1


Знающий
****

Группа: Свой
Сообщений: 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. Но сделаю это в последнюю очередь. Может быть есть другой способ вычисления дня недели? Какие будут предложения?
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
GetSmart
сообщение Jun 11 2008, 23:15
Сообщение #2


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



Цитата(alux)
Так как в отдельный момент времени в памяти может находиться только один из указанных при объявлении объединения типов, то при вызове key_processAltKeys(), в которой осуществляется доступ к переменной key_altState, портится key_code.scan нажатой кнопки со всеми вытекающими последствиями.
Вряд ли key_code.scan портится в key_processAltKeys(). В объявлении union _key_code тоже вроде бы всё "чисто". Клавиатура сканируется на двух полных портах C и D и получается 6-битный скан-код. Если на этих портах ещё что-нибудь висит, хотя бы один пин используется не для клавиатуры, то будут глюки. Особенно учитывая, что в процедуре convertKey() индекс в массиве символов используется 5-битный, а скан-код 6-битный. То есть можно залететь в следующую кодовую страницу. Запись в PORTA сначала ~key_altState, а потом сразу же кода символа не очень понятна. Если там светодиоды, то на них будет отображаться именно код символа.

Ещё одна маловероятная идея. В коде:
Код
/*** Global variables ***/
volatile unsigned char key_altState;            // Holding current alternation flags
volatile union _key_code key_code;                // Scan result structure
Поменяйте местами две этих переменных. Объявляйте key_code перед объявлением key_altState. Может что изменится. А вообще, если какая-нить часть проги портит память с этими переменными, то может в этом дело.


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
alux
сообщение Jun 12 2008, 06:30
Сообщение #3


Знающий
****

Группа: Свой
Сообщений: 589
Регистрация: 24-04-05
Пользователь №: 4 447



Цитата(GetSmart @ Jun 12 2008, 02:15) *
Клавиатура сканируется на двух полных портах C и D и получается 6-битный скан-код. Если на этих портах ещё что-нибудь висит, хотя бы один пин используется не для клавиатуры, то будут глюки. Особенно учитывая, что в процедуре convertKey() индекс в массиве символов используется 5-битный, а скан-код 6-битный. То есть можно залететь в следующую кодовую страницу.

Да, выводы мк использованы все. Для клавиатуры пришлось разнести строки и столбцы в разные порты. Не понял на счет глюка, я же прерывания настроил именно на эти выводы, к которым подключена клавиатура:
Код
// Ports
#define KEYMATRIX_COL_PORT  PORTB        // Command Output Register
#define KEYMATRIX_COL_DDR   DDRB        // Data Direction Register for KeymatrixPort
#define KEYMATRIX_COL_PIN   PINB        // PIN Register for KeymatrixPort

#define KEYMATRIX_ROW_PORT  PORTD        // Command Output Register
#define KEYMATRIX_ROW_DDR   DDRD        // Data Direction Register for KeymatrixPort
#define KEYMATRIX_ROW_PIN   PIND        // PIN Register for KeymatrixPort

// pins PCINT28..31->PCI3
#define ENABLE_PCINT3   {PCIFR |= (1<<PCIF3); PCICR |= (1<<PCIE3);}// Clear interrupt status flag, Enable pin change interrupt PCINT3
#define DISABLE_PCINT3  PCICR &= ~(1<<PCIE3)    // Disable pin change interrupt PCINT3
..........................
void key_Init(void)
{
    /* Init global variables */
    key_altState = 0;        // Clear alternation flags
    key_code.complete = 0;    // Clear scan result

    /* Init ports */
    KEYMATRIX_ROW_DDR &= 0x0f;    // Set row lines to input  
    KEYMATRIX_ROW_PORT |= 0xf0;    // Pull row lines high    
        
    KEYMATRIX_COL_DDR |= 0x0f;  // Set column lines to output  
    KEYMATRIX_COL_PORT &= 0xf0; // Drive all column lines low      
    
    /* Enable external interrupt */
//    PCIFR |= (1<<PCIF3);   //Очистить флаги внешних прерываний
    PCMSK3 = (1<<PCINT31)|(1<<PCINT30)|(1<<PCINT29)|(1<<PCINT28); //Настроить  прерывания на выводах PD4...PD7    
    ENABLE_PCINT3;      // Enable pin change interrupt PCINT3
}

Цитата(GetSmart @ Jun 12 2008, 02:15) *
Запись в PORTA сначала ~key_altState, а потом сразу же кода символа не очень понятна. Если там светодиоды, то на них будет отображаться именно код символа.
Это только для демонстрации скан-кода. В моей программе этого нет.
Цитата(GetSmart @ Jun 12 2008, 02:15) *
Особенно учитывая, что в процедуре convertKey() индекс в массиве символов используется 5-битный, а скан-код 6-битный. То есть можно залететь в следующую кодовую страницу.

Скан-код тоже 5-битный - от 0 до 31. Матрица 4х4.
Цитата(GetSmart @ Jun 12 2008, 02:15) *
Вряд ли key_code.scan портится в key_processAltKeys().

На начальном этапе проекта (до применения ОС) тоже долго не мог понять почему портился скан-код. Тогда случайно обнаружил, что проблема была связана с key_processAltKeys(). Уже не помню, что я тогда изменил (кажется я копировал скан-код в отдельную переменную). Сейчас история повторяется. Действительно, проблема осталась! Сначала после удаления #define ALTKEYS проблема исчезла, о чем я поспешил сообщить. Но после изменения/добавления пунктов меню - снова появилась! Это меня уже достало. cranky.gif
Go to the top of the page
 
+Quote Post

Сообщений в этой теме
- 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 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


Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 30th July 2025 - 11:30
Рейтинг@Mail.ru


Страница сгенерированна за 0.01412 секунд с 7
ELECTRONIX ©2004-2016