Цитата(mak007 @ Aug 27 2008, 20:59)

Частота МК 4мгц
Все записывается в EEPROM.
оригинальненько-с.... А зачем делать записть в eeprom внутри обработчика прерывания ?!? именно ожидание готовности eeprom и не позволяет принять и обработать все прерывания - большая часть из них теряется.
Вот код для меги16, который правильно работает, принимая данные с AT-клавиатуры (у меня для IAR - для вас надо адаптировать). Кстати какая клавиатура имеется в виду ? современная AT-клавиатура передает до 5 или 6 байт за одно нажатие/отпускание кнопки. А вовсе не 11 бит.
struct AT_KEYB_Data {
BYTE BitCount; // счетчик принятых бит (0 - стартовый, 1...8 - биты данных, 9 - бит паритета, 10 - стоп-бит
BYTE LastStartTICK; // младший байт системного тика в момент последнего стартового бита для контроля таймаута
BYTE TmpData;
BYTE DataCount;
BYTE Data[6];
} KEYB;
#pragma vector=INT0_vect
__interrupt void EXTERNAL_INT0(void) // по отрицательному фронту KEYB_CLOCK
{
// проверка таймаута
BYTE tick = (BYTE)_TICK;
if ((tick-KEYB.LastStartTICK) > 2) { // таймаут - это старт-бит
KEYB.BitCount = 0;
}
BYTE bc = KEYB.BitCount;
if (bc==0) { // старт-бит
if (GET_PIN(KEYB_DATA)) return; // неверный старт-бит
KEYB.LastStartTICK = tick;
bc++; KEYB.BitCount=bc;
} else if (bc<9) { // бит данных
BYTE d = KEYB.TmpData >> 1;
if (GET_PIN(KEYB_DATA)) d |= 0x80;
KEYB.TmpData = d;
bc++; KEYB.BitCount=bc;
} else if (bc==9) { // бит контроля на нечетность
bc++; KEYB.BitCount=bc;
} else { // стоп-бит
KEYB.BitCount=0;
if (GET_PIN(KEYB_DATA)==0) return; // неверный стоп-бит
// запоминаем принятые данные
BYTE dc = KEYB.DataCount;
if (dc < sizeof(KEYB.Data)) {
KEYB.Data[dc] = KEYB.TmpData;
dc++; KEYB.DataCount = dc;
}
}
}
Инициализация в MAIN:
// включаем прерывание по отрицательному фронту INT0 (KEYB_iCLOCK)
MCUCR |= (1<<ISC01); GICR |= (1<<INT0);
Да, _TICK - это глобальная системная переменная. в которой считаются миллисекунды по таймеру.
Сообщение отредактировал Олег Хохлов - Aug 27 2008, 18:39