Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: ATMEGA16 +PC Клавиатура
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > AVR
mak007
При подключении клавиатуры к avr клавиатура передает 6 бит вместо 11 и всегда одно и тоже. Помогите кто может!
zhevak
1. Осциллографом не пробовали смотреть?
2. Опубликуйте текст программы.
3. Укажите тактовую частоту.
mak007
Частота МК 4мгц
Все записывается в EEPROM.
zhevak
Скажите, уважаемый mak007, зачем Вы это делаете?
Код
interrupt [EXT_INT0] void ext_int0_isr(void)
{
  PORTB++;
  data = PIND.4;
  EEPROM_write(Address, data);                     //  <-- Здесь теряете время
  Address++;
}


Время записи в ЕЕПРОМ составляет 3-5 мс. Предполагаю, что Мега просто не успевает за внешними событиями (INT0) и пропускает часть из них.

И вообще, немного не понятно, что должна делать программа у Вас.
mak007
Счас переделаю, это тестовая программа.
OlegH
Цитата(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 - это глобальная системная переменная. в которой считаются миллисекунды по таймеру.
mak007
Спасибо всем . действительно проблемма из за записи в EEPROM.
clawham
Уважаемые , такой вопрос - у меня мега работает на 16 мегагерцах, мне очень крайне сильно нежелательно использовать прерывание, кто нибудь сможет помочь подкинуть клаву к аппаратному СПИ меги? разве у СПИ нету режима слейв? есть! к тому же частоты там нормальные, и не тормозится весь контроллер прерываниями тактового генератора клавиатуры! а самое интересное - это то что мне клаву настраивать надо, тоесть посылать ей команды! Тоесть клавиатура же может лампочками моргать, может и не сигнализировать об отпускании кнопки, может и не автоповторять, может же и накапливать нажатия в буферке встроенном(последние 8-мь действий) мне важна скорость....тоесть невозможно использовать прерывания - это слишком тупо....прерывать проц по тысяче раз в секунду всё время дае когда ввод с клавы и не нужен...так...да....раз в пол секунды проверить есть ли чтото - заполнить переменную и потом, когда будет свободного времени - отработать действие, вывести на экран менюшку и прервать выполнение программы например.....вот.... никто не заморачивался?
manul78
Цитата(clawham @ Nov 10 2008, 11:36) *
мне важна скорость....тоесть невозможно использовать прерывания - это слишком тупо....прерывать проц по тысяче раз в секунду всё время дае когда ввод с клавы и не нужен...


По тактовой - да хоть 16ГГц, с клавы-то DATA читаем по фронту CLOCK...

И зачем постоянно её опрашивать-то ? Привязал внешнее IRQ к CLOCK, считал байт, загнал в буфер
кольцевой "первым пришел - последним вышел" 16 байт на информацию, 2 байта (16 бит) на флаги
обработки буфера, буфер переполнился - читать не перестаем, а вот в буфер уже не пишем, а даем
через "биппер" писк, короче как в компе... А еще я изголялся, отдавал на девайсе, где main MPU
Atmega32, всю заботу о клавиатуре и прочей тихоходной переферии slave MPU Atiny2313, вот он пусть
её и занимается, а спросить с него всегда можно хошь по TWI (I2C), хошь по SPI, хошь по 232-му,
если не торопишься... biggrin.gif

Переферийные порты, кстати до сих пор делаю на I82C55A (КР580ВВ55А. 5.руб штука. ) отличная вещь,
3 порта по 8 бит, очень удачная микруха, её INTERSILL до сих пор производит, а ей ведь почти 30 лет...
Правда наш аналог N-mos технология, жрет много, зато стоит мало. А I82c55A - CMOS + несколько новых
функций (standBy например) цена около 100 руб. На них половина американской военщины 80-95 годов
работает...
espectro
Цитата(Олег Хохлов @ Aug 27 2008, 21:29) *
Кстати какая клавиатура имеется в виду ? современная AT-клавиатура передает до 5 или 6 байт за одно нажатие/отпускание кнопки. А вовсе не 11 бит.

5-6 байтов за одно нажатие - это, как я понимаю, для клавиш Shift, home etc, а обычные клавиши ввода символов пережают эти самые 11 бит. Или я не прав?
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.