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

 
 
4 страниц V  < 1 2 3 4 >  
Reply to this topicStart new topic
> Злополучная функция what_day(), Вычисление дня недели
alux
сообщение Jun 7 2008, 23:21
Сообщение #31


Знающий
****

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



Цитата(GetSmart @ Jun 8 2008, 00:48) *
Тогда выкладывайте HEX-файл...Может файл линковки неправильный. Тоже выложите посмотреть.

Выкладываю файлы линковки, list, map и hex варианта с глюком. В настройках проекта Configure system using dialogы (not in XCL) стоит галка.
В функции what_day() , которую выкладывал ранее, закралась маленькая ошибка, не имеющая никакого отношения к глюку - после else нужно убрать пару фигурных скобок.
Прикрепленные файлы
Прикрепленный файл  gluk.rar ( 76.3 килобайт ) Кол-во скачиваний: 40
 
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Jun 8 2008, 09:49
Сообщение #32


.
******

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



Так и не понял косяк. Со стеком не может быть проблемы точно. В RSTACK требуется всего 2 вызова, то есть 4 байта. В CSTACK тоже минимум - 6 байт. Портит регистры R0,R1,R17-R21,R30,R31 (не восстанавливаются в прологе/эпилоге). Посмотрел получше. R16-R21 можно портить, в них передаются параметры и возвращается результат. Ну а R0,R1,R30,R31 кажется полюбому можно портить. Кстати, CSTACK - это похоже стек данных, а RSTACK - вызовов.

Кажется глюки вообще не от этой злополучной процедуры.

PS. Не всё она правильно считает. 1 января 2000 года = 6 (суббота). 1 января 2004 неправильно посчитала. 1 января 2008 правильно = 2 (вторник). Результат похоже не нужно увеличивать на 1.

Сообщение отредактировал GetSmart - Jun 8 2008, 10:27


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


Знающий
****

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



Цитата(GetSmart @ Jun 8 2008, 12:49) *
Кажется глюки вообще не от этой злополучной процедуры.
Когда не остается версий, остается одно - валить все на компилятор wink.gif

Я смирился с глюком. Вышел из положения как говорил - вместо вызова функции вставил само тело. Что от этого изменилось - не понятно. Работает (пусть пока) - ну и ладно. Как сказал один умный человек (Билл Гейтс кажется), компьютер (микроконтроллер, компилятор, ...) настолько сложная штука, что не понятно, каким образом это все работает smile.gif

Цитата(GetSmart @ Jun 8 2008, 12:49) *
Не всё она правильно считает. 1 января 2000 года = 6 (суббота). 1 января 2004 неправильно посчитала. 1 января 2008 правильно = 2 (вторник). Результат похоже не нужно увеличивать на 1.
Действительно, 1 января 2004 неправильно посчитало. Алгоритм переписал с
Turbo Pascal
. А единицу нужно прибавить, потому-что у DS1338 Sunday=1, Monday=2 ,... и т.д.
Go to the top of the page
 
+Quote Post
sKWO
сообщение Jun 8 2008, 19:36
Сообщение #34


Местный
***

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



Цитата(alux @ Jun 8 2008, 03:21) *
Выкладываю файлы линковки, list, map и hex варианта с глюком. В настройках проекта Configure system using dialogы (not in XCL) стоит галка.
В функции what_day() , которую выкладывал ранее, закралась маленькая ошибка, не имеющая никакого отношения к глюку - после else нужно убрать пару фигурных скобок.

Если я ещё не надоел, то в общем есть предложение переменную day сделать беззнаковой итежер
ну и тоже самое возвращаемое значение беззнаковый итежер функции what_day() .
при вычислении остатка от деления исспользуется макро US_DIVMOD_L02 - файл стандартный библиотеки ИАР I02.s90. Там происходит вот такое
'short' (i.e. 16 bit) unsigned division and modulo
Может поэтому результат возвращается не совсем корректно через беззнаковый чар хотя его размера и достаточно?


--------------------
нельзя недооценивать предсказуемость глупости
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Jun 8 2008, 21:53
Сообщение #35


.
******

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



Ещё как вариант, нужно сравнить два листинга с процедурой в которой наблюдаются глюки при вызове what_day(), припоминаю что это было в меню. Первый листинг скомпилированный с вызовом процедуры what_day(), в котором наблюдаются глюки. Второй листинг без этой процедуры и без глюков.

Можно даже смело включить в процедуру what_day() нахождение остатка через %. Это та же процедура деления и в ней ничего страшного нет.


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


Знающий
****

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



Цитата(sKWO @ Jun 8 2008, 22:36) *
Если я ещё не надоел, то в общем есть предложение переменную day сделать беззнаковой итежер
ну и тоже самое возвращаемое значение беззнаковый итежер функции what_day() .
Там же вычисления проводятся с int. К unsigned char day приводится лишь результат. Ну проверил на всякий случай... Не в этом дело.

Цитата(GetSmart @ Jun 9 2008, 00:53) *
Ещё как вариант, нужно сравнить два листинга с процедурой в которой наблюдаются глюки при вызове what_day(), припоминаю что это было в меню. Первый листинг скомпилированный с вызовом процедуры what_day(), в котором наблюдаются глюки. Второй листинг без этой процедуры и без глюков.
Листинги чего? Меню? Дело в том, что программа состоит из десятков файлов. Тем более это все работает под управлением ОС... Вкратце это выглядит так: обработка клавиатуры и получение скан-кода вынесено в высокоприоритетный процесс. Действие, необходимое при нажатии кнопки, зависит от текущего режима: если MainMenu- то навигация по пунктам меню, если EditValue - то редактирование параметров, и т.д....
Код
OS_PROCESS void TKeyScan::Exec()    //TProc1
{
  for(;;)
  {
      PCInt3.Wait();
    
    Sleep(20);        // Задержка 10*2=20мсек для устранения дребезга контактов
    
    scan_key();
  
    if(key_code.scan & KEY_PRESSED)
    {
      key_code.scan &= ~KEY_PRESSED;   // Clear MSB of scan_code (key_pressed)
    
      switch(key_code.scan)      
      {
         case UP:     //k_right
              CurrentMode->Up();  
              break;
              
         case DOWN:   //k_left
              CurrentMode->Down();
              break;
              
         case LEFT:   //k_esc
              CurrentMode->Left();
              break;
              
         case RIGHT:  //k_enter
              CurrentMode->Right();
              break;
              
         default:     // 0...9
              CurrentMode->Numeric();
              break;
      }
    }
  }
}


PS. Функцию вычисления дня недели заменил на предыдущую (Сергея Фролова). Она вычисляет правильно. По крайней мере мне не удалось найти "неправилные" дни. Причем вызов ее не приводит к глюку. Но стоит добавить что-нибудь, например, проверку валидности данных:
Код
if((date>=1)&&(date<=31)&&(month>=1)&&(month<=12)&&(year>=1996)&&(year<=2100))

или хотя бы просто :
Код
i2c_write(year-2000);
... сразу вылазит глюк...
Go to the top of the page
 
+Quote Post
alux
сообщение Jun 11 2008, 15:03
Сообщение #37


Знающий
****

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



Этот глюк выпил достаточно моей крови... smile3046.gif Решил досконально разобраться с этой проблемой. И выяснил следующее:
каким-то образом портится скан-код нажатой клавиши. За основу программы keymatrix взял апнот Atmel avr243. Проблема исчезает, если убрать #define ALTKEYS (см. avr243). В программе используется следующая структура данных:
Код
union _key_code
{
    unsigned int complete;            // Access all 16 bits
    
    struct
    {
    union
    {
        unsigned char flags;        // Access flag status only
            
        struct
        {
        unsigned char altKey0 : 1;    // Access the flags separately
        unsigned char altKey1 : 1;
        unsigned char altKey2 : 1;
        unsigned char altKey3 : 1;
        unsigned char lckKey0 : 1;
        unsigned char lckKey1 : 1;
        unsigned char lckKey2 : 1;
        };
    };
        
    union
    {
        unsigned char scan;            // Access scancode
            
        struct
        {
            unsigned char col : 3;        // Access column of keypress
        unsigned char row : 3;        // Access row of keypress
                
        unsigned char unused : 2;
        };
    };
    };
};
extern volatile union _key_code key_code;   // Scan result structure
extern volatile unsigned char key_altState; // Current alternation flags
Так как в отдельный момент времени в памяти может находиться только один из указанных при объявлении объединения типов, то при вызове key_processAltKeys(), в которой осуществляется доступ к переменной key_altState, портится key_code.scan нажатой кнопки со всеми вытекающими последствиями. Т.е. изначально проблема была не в функции what_day(), а в драйвере клавиатуры. Внешне это выглядело довольно странно: скан-код портился выборочно при определенных условиях и на завершающей стадии проекта.
Осталось придумать, как решить эту проблему. smile.gif

PS. Насколько я понимаю, этого не должно быть. Ведь эти переменные относятся к разным union, которые являются членами общей структуры, которая в свою очередь является членом объединения. Или я ошибаюсь?
Прикрепленные файлы
Прикрепленный файл  AVR243.zip ( 7.83 килобайт ) Кол-во скачиваний: 36
 
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Jun 11 2008, 23:15
Сообщение #38


.
******

Группа: Участник
Сообщений: 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
Сообщение #39


Знающий
****

Группа: Свой
Сообщений: 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
GetSmart
сообщение Jun 12 2008, 11:10
Сообщение #40


.
******

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



Цитата(alux)
Не понял на счет глюка, я же прерывания настроил именно на эти выводы, к которым подключена клавиатура:

Вне зависимости от того, на что настроены прерывания, в процедуре переполнения таймера 0 формируется 6-битный скан-код. И если на портах C и D помимо клавиатуры что-то подключено (хоть на вход, хоть на выход) скан-коды будут "левые". Особенно, если для клавиатуры на одном порте используется старшая половина полубайта:
Код
    /* Init ports */
    KEYMATRIX_ROW_DDR &= 0x0f;    // Set row lines to input  
    KEYMATRIX_ROW_PORT |= 0xf0;    // Pull row lines high
Как я понял, здесь на битах 4..7 висит клавиатура, а на младших что-то ещё. Прерывание по таймеру сканирует биты от младшего к старшему и найдя еденичный бит в младших битах перестанет дальше сканировать. Даже когда для клавиатуры используются две младших половинки в двух разных портах, то может произойти прерывание по отжатию кнопки, при этом на старших битах порта столбцов будет посторонний нулевой сигнал, то он засчитается за нажатую клавишу. Чтобы всех этих проблем не происходило нужно подправить в файле keymatrix.c процедуру сканирования портов клавиатуры timer0OVFISR().


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


Знающий
****

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



Цитата(GetSmart @ Jun 12 2008, 14:10) *
Чтобы всех этих проблем не происходило нужно подправить в файле keymatrix.c процедуру сканирования портов клавиатуры timer0OVFISR().

Ну это само собой разумеется. Конечно, я переписал этот keymatrix.c для моего случая:
Код
//#############################################################################
//  Вычисление скан-кода нажатой кнопки
//_____________________________________________________________________________
void scan_key(void)
{
  TCritSect cs;
  
  /* Local variables */
  unsigned char lineResult;    // Resulting column and row lines
  unsigned char tempScan;    // Temporary scancode


  /* Find row of keypress */
  lineResult = KEYMATRIX_ROW_PIN&0xf0;  // Get row lines    
            
  if(lineResult != 0xf0)    // Any row lines low ?
  {
    /* Invert port directions */
    KEYMATRIX_COL_PORT |= 0x0f;    // Drive all col lines high                      
    KEYMATRIX_COL_DDR &= 0xf0;    // Set col lines to input, already pulled up
                                                
    KEYMATRIX_ROW_PORT &= 0x0f; // Disable pull-up on row lines
    KEYMATRIX_ROW_DDR |= 0xf0;  // Set row lines to output, already driven low        

    tempScan = 0;            // Init temp scan code
        
    while(lineResult & 0x10)    // Loop while row line high
    {
      lineResult >>= 1;            // Next row line into LSB
      tempScan += 8;        // Increment row part of scancode
    }
        
    /* Find col of keypress */
    lineResult = KEYMATRIX_COL_PIN&0x0f;  // Get col lines        

    /* Set original port directions */    
    KEYMATRIX_ROW_PORT |= 0xf0; // Drive all row lines high
    KEYMATRIX_ROW_DDR &= 0x0f;    // Set row lines to input, already pulled up,
                                                  
    KEYMATRIX_COL_PORT &= 0xf0; // Disable pull-up on col lines
    KEYMATRIX_COL_DDR |= 0x0f;  // Set col lines to output, alreay driven low            
        

    if(lineResult != 0x0f)    // Any col lines low ?
    {
      while(lineResult & 0x01)  // Loop while col line high
      {
    lineResult >>= 1;       // Next col line into LSB
    tempScan ++;            // Increment col part of scancode
      }
            
      /* Process scancode */
      tempScan |= KEY_PRESSED;  // Set MSB of scan_code (key pressed)
      key_code.scan = tempScan; // Save scancode

      #ifdef ALTKEYS
          key_processAltKeys(); // Process alternation keys if implemented
      #endif            
    }
    else
      key_code.scan = 0;    // Indicate no keys pressed 0x00
  }
  else
    key_code.scan = 0;            // Indicate no keys pressed 0x00
    
    /* Prepare external interrupt */
    ENABLE_PCINT3;        // Reenable pin change interrupt
}
Эта функция вызывается не в прерывании таймера, а в процессе OS_PROCESS void TKeyScan::Exec() с использованием флагов сообщений ОС. Код я приводил в предыдущем посте.

PS. Для эксперимента заменил key_code.scan на обычную глобальную volatile unsigned char scan. Не помогло. Все равно портится те же 4 скан-кода кнопок. sad.gif Т.е. проблема не в использовании union. Версий пока больше нет...

PS2. Все! Наконецто локализовал проблему. Надеюсь в последний раз smile.gif.
Скан-код портит функция convertKey();
Код
char __flash characters[4][32] = {        
                   { '1', '2', '3', 0, 0, 0, 0, 0,            // No alternation
                             '4', '5', '6', 0, 0, 0, 0, 0,
                             '7', '8', '9', 0, 0, 0, 0, 0,
                             '.', '0', '#', 0, 0, 0, 0, 0 },

                           { 'a', 'd', 'g', 0,   'а', 'г', 'є', 'ъ',    // First character
                             'j', 'm', 'p', 0,   'и', 'й', 'м', 'ы',
                             's', 'v', 'y', 0,   'п', 'т', 'х', 0,
                             '*', '*', '#', 0,   'ш', 'ю', 0, 0 },

                           { 'b', 'e', 'h', 0,   'б', 'д', 'ж', 0,    // Second character
                             'k', 'n', 'q', 0,   'і', 'к', 'н', 0,
                             't', 'w', 'z', 0,   'р', 'у', 'ц', 0,
                             '*', '?', '#', 0,   'щ', 'я', 0, 0 },

                           { 'c', 'f', 'i', 0,   'в', 'е', 'з', 0,    // Third character
                             'l', 'o', 'r', 0,   'ї', 'л', 'о', 0,
                             'u', 'x', '-', 0,   'с', 'ф', 'ч', 0,
                             '*', '!', '#', 0,   'ь', 0, 0, 0 }
                         };

/*** Convert scancode to character ***/
char convertKey(void)
{
  char tempChar;

    if(key_code.altKey0)                // First char ?
        tempChar = characters[1][key_code.scan+4];
    else
        if(key_code.altKey1)                    // Second char ?
       tempChar = characters[2][key_code.scan+4];
    else
            if(key_code.altKey2)            // Third char ?
           tempChar = characters[3][key_code.scan+4];
        else                            // No alternation ?
            tempChar = characters[0][key_code.scan];

    if(key_code.altKey3)                // Uppercase if caps lock
        tempChar = toupper(tempChar);
    
    return tempChar;
}
Если заменить многомерный массив одномерным, то все нормально. А почему?

Сообщение отредактировал alux - Jun 13 2008, 08:15
Go to the top of the page
 
+Quote Post
alux
сообщение Jun 13 2008, 08:04
Сообщение #42


Знающий
****

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



...И вновь продолжается бой. smile.gif
Ребята, извините, пожалуйста, если достал уже этой проблемой. Напомню, что глюк проявляет себя в том, что портит скан-код четырех кнопок. Причем одинаково: кнопка "3" вместо скан-кода 2 дает 1, кнопка "ESC" вместо скан-кода 3 дает 1, кнопка "6" вместо скан-кода 10 дает 9, кнопка "UP" вместо скан-кода 11 дает 10. Может эта информация как-то наведет на мысли.
Глюк появляется при входе в пункт меню ("Редактирование"). Вроде нашел причину: в функции convertKey() если заменить многомерный массив одномерным, то глюк пропадает. Ну, бог с ним, с многомерным массивом. Но следующее выходит за рамки моего понимания: если раскомментировать #define ALTKEYS , т.е. вызвать функцию void key_processAltKeys() , в которой просто XORятся биты флага, снова появляется этот злосчастный глюк.
Код
#ifdef ALTKEYS

void key_processAltKeys()
{
    if     (flags & ALTKEY0) flags ^= ALTKEY0;  
    else if(flags & ALTKEY1) flags ^= ALTKEY1;  
    else if(flags & ALTKEY2) flags ^= ALTKEY2;  
    else if(flags & ALTKEY3) flags ^= ALTKEY3;  
}
#endif
Причем, для чистоты эксперимента переменные scan (скан-код) и flags сделал глобальными volatile unsigned char. Функцию scan_key() приводил в предыдущем посте. Воздействие ОС на глюк исключается,- функция вызывается в критической секции (TCritSect cs) help.gif
Go to the top of the page
 
+Quote Post
sKWO
сообщение Jun 13 2008, 08:57
Сообщение #43


Местный
***

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



Цитата(alux @ Jun 13 2008, 12:04) *
Код
    else if(flags & ALTKEY1) flags ^= ALTKEY1;  
    else if(flags & ALTKEY2) flags ^= ALTKEY2;

Так бегло
alux а зачем инвертировать флаг в флаговом регистре ничего при этом не делая и не проверяя сканкод
Выдержка из оригинала
Код
if     ( key_code.scan == ALTKEY0 ) key_altState ^= (1<<0);
    else if( key_code.scan == ALTKEY1 ) key_altState ^= (1<<1);
    else if( key_code.scan == ALTKEY2 ) key_altState ^= (1<<2);
    else if( key_code.scan == ALTKEY3 ) key_altState ^= (1<<3);
    else if( key_code.scan == LCKKEY0 ) key_altState ^= (1<<4);
    else if( key_code.scan == LCKKEY1 ) key_altState ^= (1<<5);
    else if( key_code.scan == LCKKEY2 ) key_altState ^= (1<<6);
    else                                        // Not alternation key ?
    {
        key_altState &= ALTLOCKMASK;                // Clear one-shot key flags
    }

ALTKEY как у Вас определены, може всё завязано на битовых сдвигах?


--------------------
нельзя недооценивать предсказуемость глупости
Go to the top of the page
 
+Quote Post
alux
сообщение Jun 13 2008, 09:39
Сообщение #44


Знающий
****

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



Код
// Alternation key code
#define ALTKEY   26            // '#' on test keypad

#define ALT0   0x01    
#define ALT1   0x02            
#define ALT2   0x04            
#define ALT3   0x08


Проблема возникает если просто :
Код
void key_processAltKeys()
{
    if(scan == ALTKEY)  flags ^= ALT0;
}
Что здесь не так? Не вижу криминала.

PS. Меня не покидает чувство, что виноват все-таки компилятор (v.5.10A). Где-то на форуме проскакивало сообщение, что компилятор 5.10 не правильно определяет CSTACK >= 0xC0.
Уже качаю IAR v.5.11B.
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Jun 13 2008, 17:42
Сообщение #45


.
******

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



Цитата(alux @ Jun 13 2008, 14:04) *
Код
#ifdef ALTKEYS

void key_processAltKeys()
{
    if     (flags & ALTKEY0) flags ^= ALTKEY0;  
    else if(flags & ALTKEY1) flags ^= ALTKEY1;  
    else if(flags & ALTKEY2) flags ^= ALTKEY2;  
    else if(flags & ALTKEY3) flags ^= ALTKEY3;  
}
#endif
Это что за ерунда такая? Раньше эта процедура сравнивала скан код нажатой клавиши с кодами альтернативных клавиш и устанавливала бит в key_altState. Даже если key_altState теперь называется flags, то ерунда тут. Исключающее ИЛИ с кодом клавиши? Зачем? В flags лежат коды клавиш?

ЗЫ. Больше не буду искать ошибки, когда на обозрение выкладываются какие-то левые исходники, а потом оказывается что в реале что-то где-то поменяно и вообще хз что скомпилено.


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 21st July 2025 - 09:27
Рейтинг@Mail.ru


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