Цитата(KmUa @ Sep 14 2005, 22:49)
Не подскажете, где можно найти примеры сопряжения (програмная реализация) МК состандартной PS/2 (AT) клавиатурой. Желательно на ASM51.
Информация необходима для реализации проекта "Бегущая строка", а так как опыт программирования МК у меня очень невелик прошу вашей помощи и поддержки в данном направлении (возможно уже есть ресурс на эту тему?)
PS_O_Data
PS_O_Clk - отдельные порты для тянущих к земле транзисторов
PS_DATA - любой порт - вход
WR_FIFO(dan); - делайте с кодом что хотите
//----------------------------------------------------------------------------------
-------------------------------------
static void
interrupt //прерывание
INT0 - высокий приоритет
prer(void)
{
unsigned char dan; //принятый байт
if(Gl_Wr_KB) //если нужна
передача
{
if(Gl_Bufer_WR & 0b0000000000000001) PS_O_Data=0; //передача бита - 1
else PS_O_Data=1; //передача бита - 0
Gl_Bufer_WR=Gl_Bufer_WR >> 1; //сдвиг буфера
Gl_Scet_Bit_WR++; //посчитали этот бит
if(Gl_Scet_Bit_WR >= 11) //если переданы все
биты
{
Gl_Scet_Bit_WR=0; //сброс счетчика
Gl_Wr_KB=0; //сброс флага
передачи
PS_O_Data=0; //data отпущен
Gl_Scet_Bit=0; //сброс счетчика
клавы - это для синхронизации приема следующего кода
Gl_Bufer=0; //сброс буфера клавы
}
}
else //просто прием
данных
{
if(PS_DATA) Gl_Bufer=Gl_Bufer | 0b1000000000000000; //прием бита - 1
else Gl_Bufer=Gl_Bufer & 0b0111111111111111; //прием бита - 0
Gl_Bufer=Gl_Bufer >> 1; //сдвиг буфера
Gl_Scet_Bit++; //посчитали этот бит
if(Gl_Scet_Bit >= 11) //если приняты все
биты
{
dan=Gl_Bufer >> 5; //получим сам байт
WR_FIFO(dan); //запись кода
клавиатуры в буфер
Gl_Scet_Bit=0; //сброс счетчика
Gl_Bufer=0; //сброс буфера
}
}
INT0IF=0; //сброс флага
прерывания
}
//----------------------------------------------------------------------------------
-------------------------------------
void Write_KB(unsigned char
dan) //запись в
клавиатуру
{
unsigned char i; //просто переменная
unsigned char chetn; //счетчик четности
unsigned char buf; //буфер для сдвига
данных
if(Gl_Wr_KB == 0) //если запись не
идет
{
buf=dan; //данные в буфер
chetn=1; //предположим что
четность есть
for(i=1;i<=8;i++) //переберем все биты
{
if(buf & 0b00000001) //если младший бит
равен 1
{
if(chetn) chetn=0; //суммирование
получится побитное
else chetn=1;
}
buf=buf >> 1; //сдвинем на
следующий бит
}
Gl_Scet_Bit_WR=0; //сброс счетчика
битов для передачи по PS/2
if(chetn) Gl_Bufer_WR=0b0000001100000000; //начальное
значение Gl_Bufer_WR - четность есть
else Gl_Bufer_WR=0b0000001000000000; //начальное
значение Gl_Bufer_WR - четности нет
Gl_Bufer_WR=Gl_Bufer_WR | dan; //подготовка блока
битов
PS_O_Clk=1; //clk к 0-лю
for(i=1;i<=50;i++) asm("nop"); //100 мкС
PS_O_Data=1; //data к 0-лю
Gl_Wr_KB=1; //выставили флаг
записи
PS_O_Clk=0; //clk отпущен -
условие записи выполнено
DelayMs(20); //время на запись
}
}
//----------------------------------------------------------------------------------
-------------------------------------
void Set_Status_KB
(void) //уста
новка статуса клавы
{
unsigned char stat; //статус клавы
stat=0b00000000; //все биты сброшены
if(Gl_Num_lock) stat=stat | 0b00000010; //установка бита
Num_lock
if(Gl_Caps_lock) stat=stat | 0b00000100; //установка бита
Caps_lock
if(Gl_ScrollLock) stat=stat | 0b00000001; //установка бита
Gl_ScrollLock
Write_KB(0xED); //команда установки
лампочек
Write_KB(stat); //запись статуса в
клаву
Write_KB(0xF3); //команда установки
времени повтора
Write_KB(0x70);