Цитата(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 скан-кода кнопок.

Т.е. проблема не в использовании
union. Версий пока больше нет...
PS2. Все! Наконецто локализовал проблему. Надеюсь в последний раз

.
Скан-код портит функция 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;
}
Если заменить многомерный массив одномерным, то все нормально. А почему?