PDA

Просмотр полной версии : Универсальный контроллер PS/2 клавиатуры для компьютеров с матричными клавиатурами.



Страницы : 1 [2]

solonoid
13.12.2023, 17:28
Уважаемый Xrust, хотел попросить вас доработать программу и вывести на свободные ноги Атмеги два сигнала , сброс при нажатии ctrl, alt , del ,и nmi при нажатии какой нибудь функциональной клавиши.

Xrust
25.02.2024, 20:41
Набросал сегодня на скорую руку прошивку для УКНЦ.

//UKNZ
#include <PS2KeyRaw.h>
#define AX0 4
#define AX1 5
#define AX2 6
#define AX3 7
#define AY0 8
#define AY1 9
#define AY2 10
#define RSTMT 14
#define CSMT 15
#define DATMT 16
#define STBMT 17
#define DATAPIN 2
#define IRQPIN 3
#define LAT 0
#define EXT 1
#define RUS 2

volatile boolean d = HIGH;
volatile uint8_t lang = LAT;
volatile uint8_t e = lang;
uint8_t table[3][132] = {{127,116,127,8,5,3,4,127,127,11,100,117,7,17,0,12 7,
127,65,64,127,33,50,19,127,127,127,106,68,53,52,20 ,127,
127,35,72,42,22,6,21,127,127,70,90,34,71,55,23,127 ,
127,39,57,105,40,51,24,127,127,127,69,18,36,9,10,1 27,
127,74,37,54,56,121,122,127,127,88,118,41,2,38,67, 127,
127,127,58,127,25,120,127,127,66,49,102,26,127,89, 127,127,
127,127,127,127,127,127,85,127,127,82,127,83,80,12 7,127,127,
81,97,98,99,115,96,1,127,127,84,114,16,84,112,127, 127,
127,127,127,101},
{127,127,127,127,127,127,127,127,127,127,127,127,1 27,127,127,127,
127,49,127,127,33,127,127,127,127,127,127,127,127, 127,127,127,
127,127,127,127,127,127,127,127,127,127,127,127,12 7,127,127,127,
127,127,127,127,127,127,127,127,127,127,127,127,12 7,127,127,127,
127,127,127,127,127,127,127,127,127,127,119,127,12 7,127,127,127,
127,127,127,127,127,127,127,127,127,127,113,127,12 7,127,127,127,
127,127,127,127,127,127,127,127,127,127,127,73,127 ,127,127,127,
127,127,87,127,86,103,127,127,127,127,127,127,127, 127,127,127,
127,127,127,127},
{127,116,127,8,5,3,4,127,127,127,100,117,7,17,127, 127,
127,65,64,127,33,18,19,127,127,127,50,51,34,35,20, 127,
127,68,67,52,36,6,21,127,127,70,69,53,22,37,23,127 ,
127,71,54,55,38,39,24,127,127,127,72,56,40,9,10,12 7,
127,57,41,25,26,121,122,127,127,58,119,42,90,106,6 7,127,
127,127,89,127,105,120,127,127,66,49,102,104,127,1 27,127,127,
127,127,127,127,127,127,85,127,127,82,127,83,80,12 7,127,127,
81,97,98,99,115,96,1,127,127,127,114,16,84,112,127 ,127,
127,127,127,101}};
PS2KeyRaw keyboard;
void setup() {
//Инициализация портов
pinMode(AX0, OUTPUT); //AX0
pinMode(AX1, OUTPUT); //AX1
pinMode(AX2, OUTPUT); //AX2
pinMode(AX3, OUTPUT); //AX3
pinMode(AY0, OUTPUT); //AY0
pinMode(AY1, OUTPUT); //AY1
pinMode(AY2, OUTPUT); //AY2
pinMode(RSTMT, OUTPUT); //RES
pinMode(CSMT, OUTPUT); //CS
pinMode(DATMT, OUTPUT); //DAT
pinMode(STBMT, OUTPUT); //STB
//Инициализация клавиатуры
keyboard.begin( DATAPIN, IRQPIN );
//Инициализация MT8816
SetAddr(0);
digitalWrite(RSTMT, LOW);
digitalWrite(CSMT, LOW);
digitalWrite(DATMT, LOW);
digitalWrite(STBMT, LOW);
InitMt();
}
//Сброс MT
void InitMt() {
digitalWrite(STBMT, HIGH); //инициализация
digitalWrite(CSMT, HIGH); //выбор чипа
digitalWrite(RSTMT, HIGH);
digitalWrite(RSTMT, LOW); //сброс
digitalWrite(CSMT, LOW);
digitalWrite(STBMT, LOW);
}
//Установка адреса MT
void SetAddr(uint8_t addr) {
digitalWrite(AX0,bitRead(addr,0));
digitalWrite(AX1,bitRead(addr,1));
digitalWrite(AX2,bitRead(addr,2));
digitalWrite(AX3,bitRead(addr,3));
digitalWrite(AY0,bitRead(addr,4));
digitalWrite(AY1,bitRead(addr,5));
digitalWrite(AY2,bitRead(addr,6));
}
//Установка ключа MT
void SetKey(boolean data){
digitalWrite(CSMT, HIGH); //выбор чипа
digitalWrite(STBMT, HIGH); //строб on
digitalWrite(DATMT, data); //данные
digitalWrite(STBMT, LOW); //строб off
digitalWrite(CSMT, LOW);
}
void loop()
{
if( keyboard.available() ){
int c = keyboard.read(); //чтение кода
switch (c) {
case 0xE1: //Если считался префикс 0xE1 сброс MK
InitMt();
break;
case 0xE0: //Если считался префикс 0xE0
e = EXT; //тогда код будет из table[1]
break;
case 0xF0: //Если считался префикс 0xF0 (отпускание клавиши)
d = LOW; //тогда готовимся записывать "0" в MT
break;
case 0x78: //Если считался код 0x78 [F11]
lang = RUS; //переключаемся на русскую раскладку
e = lang;
d = HIGH; //помним о 0xF0 при отпускании [F11],
break; //фактически раскладка переключается дважды.
case 0x07: //Если считался код 0x07 [F12]
lang = LAT; //переключаемся на латинскую раскладку
e = lang;
d = HIGH; //помним о 0xF0 при отпускании [F12]
break;
default:
SetAddr(table[e][c]); //получаем адрес ключа из текущей таблицы
SetKey(d); //переключаем ключ в состояние d
d = HIGH; //если было отжатие ключа, принудительно переводим в нажатие
e = lang; //если был код из table[1], возвращаем на текущую раскладку
}
}
}

Переключение раскладок: F11-русская F12-латинская.
Кое-что еще требует доработки, кое-какие клавиши, наверное, стоит переназначить. Клавиши ПОМ УСТ ИСП СБРОС соответствуют F6 F7 F8 F9, чтобы было удобнее в Турбо Бейсике. Клавиша СТОП пока не реализована, ее надо отдельно делать.

Arseny
25.02.2024, 22:34
Набросал сегодня на скорую руку прошивку для УКНЦ.
Сильно на скорую. Не реализована клавиша ФИКС, на сколько я понимаю. Значит CAPS придется реализовывать зажатым Shift'ом. Да и РУС/ЛАТ не пойми как будут работать - они тоже ФИКС'ом фиксируются.

Xrust
27.02.2024, 10:37
Не реализована клавиша ФИКС, на сколько я понимаю.
Неправильно понимаете. Реализованы все клавиши, кроме СТОП.

Arseny
27.02.2024, 11:06
Неправильно понимаете. Реализованы все клавиши, кроме СТОП.
Надо, короче, пробовать и смотреть как работает...

Xrust
01.03.2024, 19:03
Доработал немного прошивку под УКНЦ. Добавил сброс MT клавишей [Break] и пофиксил ошибки.

P.S. Победил и [STOP]. Полностью все клавиши работают. Если только какие-то мелкие замечания устранить.

Схема подключения:
J2(8..1) контроллера >> XS3(8..1) УКНЦ, J3(12..1) контроллера >> XS4(12..1) УКНЦ, J3(13) контроллера >> XS3(9) УКНЦ.

Ну и, естественно, контроллер с этой прошивкой можно подключить и к Ориону-128, к которому так же подключали клавиатуру МС7007.

Xrust
24.03.2024, 13:44
Новая версия прошивки для Спектрум 128
Добавлен сброс матрицы клавишей [Pause Break].

#include <PS2KeyRaw.h>
#define AX0 4
#define AX1 5
#define AX2 6
#define AX3 7
#define AY0 8
#define AY1 9
#define AY2 10
#define RSTMT 14
#define CSMT 15
#define DATMT 16
#define STBMT 17
#define DATAPIN 2
#define IRQPIN 3

volatile boolean d = HIGH;

uint8_t table[128] = {127,127,127,127,127,127,127,127,127,127,127,127,1 27,127,127,127,127,127,0,127,127,32,48,127,127,127 ,1,17,16,33,49,127,
127,3,2,18,34,51,50,127,127,112,4,19,36,35,52,127, 127,115,116,100,20,84,68,127,127,127,114,99,83,67, 66,127,
127,127,98,82,81,64,65,127,127,127,127,97,127,80,1 27,127,127,127,127,127,127,127,127,127,127,113,96, 127,127,127,127,127,
127,127,127,127,127,127,64,127,127,127,127,52,127, 127,127,127,127,127,127,127,127,127,127,127,127,12 7,127,127,127,127,127,127};

PS2KeyRaw keyboard;
void setup() {
//Инициализация портов
pinMode(AX0, OUTPUT); //AX0
pinMode(AX1, OUTPUT); //AX1
pinMode(AX2, OUTPUT); //AX2
pinMode(AX3, OUTPUT); //AX3
pinMode(AY0, OUTPUT); //AY0
pinMode(AY1, OUTPUT); //AY1
pinMode(AY2, OUTPUT); //AY2
pinMode(RSTMT, OUTPUT); //RES
pinMode(CSMT, OUTPUT); //CS
pinMode(DATMT, OUTPUT); //DAT
pinMode(STBMT, OUTPUT); //STB
//Инициализация клавиатуры
keyboard.begin( DATAPIN, IRQPIN );
//Инициализация MT8816
SetAddr(0);
digitalWrite(RSTMT, LOW);
digitalWrite(CSMT, LOW);
digitalWrite(DATMT, LOW);
digitalWrite(STBMT, LOW);
InitMt();
}
//Сброс MT
void InitMt() {
digitalWrite(STBMT, HIGH); //инициализация
digitalWrite(CSMT, HIGH); //выбор чипа
digitalWrite(RSTMT, HIGH);
digitalWrite(RSTMT, LOW); //сброс
digitalWrite(CSMT, LOW);
digitalWrite(STBMT, LOW);
}
void SetAddr(uint8_t addr) {
digitalWrite(AX0,bitRead(addr,0));
digitalWrite(AX1,bitRead(addr,1));
digitalWrite(AX2,bitRead(addr,2));
digitalWrite(AX3,bitRead(addr,3));
digitalWrite(AY0,bitRead(addr,4));
digitalWrite(AY1,bitRead(addr,5));
digitalWrite(AY2,bitRead(addr,6));
}
void SetKey(boolean data){
digitalWrite(CSMT, HIGH); //выбор чипа
digitalWrite(STBMT, HIGH); //строб on
digitalWrite(DATMT, data); //данные
digitalWrite(STBMT, LOW); //строб off
digitalWrite(CSMT, LOW);
}
void loop()
{
if( keyboard.available() ){
int c = keyboard.read(); //чтение кода
switch (c) {
case 0xE1: //Если считался префикс 0xE1 сброс MK
InitMt();
break;
case 0xE0: //если считался префикс 0xE0
break;
case 0xF0: //если считался префикс 0xF0 (отпускание клавиши)
d = LOW;
break;
case 0x66: //если считался код 0x66 [BS]
SetAddr(table[0x12]);
SetKey(d);
SetAddr(table[0x45]);
SetKey(d);
d = HIGH;
break;
case 0x6B: //если считался код 0x6B [Left]
SetAddr(table[0x12]);
SetKey(d);
SetAddr(table[0x2E]);
SetKey(d);
d = HIGH;
break;
case 0x72: //если считался код 0x72 [Down]
SetAddr(table[0x12]);
SetKey(d);
SetAddr(table[0x36]);
SetKey(d);
d = HIGH;
break;
case 0x75: //если считался код 0x75 [Up]
SetAddr(table[0x12]);
SetKey(d);
SetAddr(table[0x3D]);
SetKey(d);
d = HIGH;
break;
case 0x74: //если считался код 0x74 [Right]
SetAddr(table[0x12]);
SetKey(d);
SetAddr(table[0x3E]);
SetKey(d);
d = HIGH;
break;
case 0x76: //если считался код 0x76 [Edit]
SetAddr(table[0x12]);
SetKey(d);
SetAddr(table[0x16]);
SetKey(d);
d = HIGH;
break;
case 0x58: //если считался код 0x58 [Caps lock]
SetAddr(table[0x12]);
SetKey(d);
SetAddr(table[0x1E]);
SetKey(d);
d = HIGH;
break;
case 0x0D: //если считался код 0x0D [Ext mode]
SetAddr(table[0x12]);
SetKey(d);
SetAddr(table[0x59]);
SetKey(d);
d = HIGH;
break;
case 0x41: //если считался код 0x41 [,]
SetAddr(table[0x59]);
SetKey(d);
SetAddr(table[0x31]);
SetKey(d);
d = HIGH;
break;
case 0x49: //если считался код 0x49 [.]
SetAddr(table[0x59]);
SetKey(d);
SetAddr(table[0x3A]);
SetKey(d);
d = HIGH;
break;
case 0x4C: //если считался код 0x4C [;]
SetAddr(table[0x59]);
SetKey(d);
SetAddr(table[0x44]);
SetKey(d);
d = HIGH;
break;
case 0x52: //если считался код 0x52 ["]
SetAddr(table[0x59]);
SetKey(d);
SetAddr(table[0x4D]);
SetKey(d);
d = HIGH;
break;
default:
SetAddr(table[c]);
SetKey(d);
d = HIGH;
}
}
}

solonoid
28.03.2024, 21:12
Что значит сброс матрицы? Какое действие он производит?

Xrust
04.04.2024, 19:29
Что значит сброс матрицы? Какое действие он производит?

Производит инициализацию матрицы. Если вдруг какие-то ключи "залипли", чтобы долго не искать.

Improver
28.05.2024, 11:32
Сделал прошивку под Вектор-06ц (она же подходит и для ПК-6128ц -- там клавиатуры одинаковые). Для показа состояния индикатора "РУС" использовал на клавиатуре индикатор ScrollLock, для индикатора "СЕТЬ" -- NumLock. Для того, чтобы задействовать эти индикаторы пришлось перейти с библиотеки PS2KeyRaw на PS2KeyboardHost (https://github.com/SteveBenz/PS2KeyboardHost) (есть в библиотеке ArduinoIDE).


// Вектор-06ц / ПК-6128ц
#include "ps2_Keyboard.h"
#include "ps2_NullDiagnostics.h"

#define AX0 4
#define AX1 5
#define AX2 6
#define AX3 7
#define AY0 8
#define AY1 9
#define AY2 10
#define SS 11 // J1:4
#define US 12 // J1:1
#define RUS 13 // J1:3
#define VVD 1 // H2:TX
#define SBR 0 // H2:RX
#define IRUS 18 // вывод 27
#define RSTMT 14
#define CSMT 15
#define DATMT 16
#define STBMT 17
#define DATAPIN 2
#define IRQPIN 3

// J2 -- PB
// J3 -- PA

typedef ps2::NullDiagnostics Diagnostics_;
static Diagnostics_ diagnostics;
static ps2::Keyboard<DATAPIN, IRQPIN, 1, Diagnostics_> ps2Keyboard(diagnostics);
static ps2::KeyboardLeds lastLedSent = ps2::KeyboardLeds::none;

volatile boolean d = HIGH;
volatile boolean OldRUS;
volatile boolean extkey = LOW;
const uint8_t table[128] = {0xFF, 0xFF, 0xFF, 0x71, 0x51, 0x31, 0x41, 0xFF, // 0 00 - - - F5 F3 F1 F2 - (код клавиши PB PA)
0xFF, 0xFF, 0xFF, 0xFF, 0x61, 0x00, 0x33, 0xFF, // 8 08 - - - - F4 TB ; -
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x25, 0x12, 0xFF, // 16 10 - - - - - J 1 -
0xFF, 0xFF, 0x16, 0x17, 0x64, 0x34, 0x22, 0xFF, // 24 18 - - Q Y F C 2 -
0xFF, 0x36, 0x67, 0x76, 0x56, 0x42, 0x32, 0xFF, // 32 20 - S ^ W U 4 3 -
0xFF, 0x77, 0x55, 0x14, 0x54, 0x35, 0x52, 0xFF, // 40 28 - _ M A E K 5 -
0xFF, 0x46, 0x15, 0x26, 0x06, 0x65, 0x62, 0xFF, // 48 30 - T I R P N 6 -
0xFF, 0xFF, 0x07, 0x75, 0x74, 0x72, 0x03, 0xFF, // 56 38 - - X O G 7 8 -
0xFF, 0x24, 0x45, 0x37, 0x57, 0x02, 0x13, 0xFF, // 64 40 - B L [ ] 0 9 -
0xFF, 0x04, 0x43, 0x44, 0x66, 0x27, 0x53, 0xFF, // 72 48 - @ , D V Z = -
0xFF, 0xFF, 0x47, 0xFF, 0x05, 0x73, 0xFF, 0xFF, // 80 50 - - \ - H / - -
0xFF, 0x10, 0x20, 0x23, 0xFF, 0x63, 0xFF, 0xFF, // 88 58 - ПС ВК : - . - -
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x30, 0xFF, // 96 60 - - - - - - ЗБ -
0xFF, 0xFF, 0xFF, 0x40, 0x01, 0xFF, 0xFF, 0xFF, // 104 68 - - - < HM - - -
0xFF, 0xFF, 0x70, 0xFF, 0x60, 0x50, 0x21, 0xFF, // 112 70 - - v - > ^ А2 -
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x11, 0xFF, 0xFF // 120 78 - - - - - СТ - -
};

void setup() {
//Инициализация портов
pinMode(AX0, OUTPUT); //AX0
pinMode(AX1, OUTPUT); //AX1
pinMode(AX2, OUTPUT); //AX2
pinMode(AX3, OUTPUT); //AX3
pinMode(AY0, OUTPUT); //AY0
pinMode(AY1, OUTPUT); //AY1
pinMode(AY2, OUTPUT); //AY2
pinMode(SS, OUTPUT); //SS
pinMode(US, OUTPUT); //US
pinMode(RUS, OUTPUT); //RUS
pinMode(IRUS, INPUT_PULLUP); //индикатор RUS
pinMode(VVD, OUTPUT); //ВВОД
pinMode(SBR, OUTPUT); //СБРОС
pinMode(RSTMT, OUTPUT); //RES
pinMode(CSMT, OUTPUT); //CS
pinMode(DATMT, OUTPUT); //DAT
pinMode(STBMT, OUTPUT); //STB

OldRUS = digitalRead(IRUS);

//Инициализация клавиатуры
ps2Keyboard.begin();
ps2Keyboard.awaitStartup();

if ( OldRUS == HIGH ) {
ps2Keyboard.sendLedStatus(ps2::KeyboardLeds::numLo ck);
lastLedSent = ps2::KeyboardLeds::numLock;
}
else {
ps2Keyboard.sendLedStatus(ps2::KeyboardLeds::numLo ck | ps2::KeyboardLeds::scrollLock);
lastLedSent == (ps2::KeyboardLeds::numLock | ps2::KeyboardLeds::scrollLock);
}

digitalWrite(SS, HIGH);
digitalWrite(US, HIGH);
digitalWrite(RUS, HIGH);
digitalWrite(VVD, HIGH);
digitalWrite(SBR, HIGH);

//Инициализация MT8816
SetAddr(0);
digitalWrite(RSTMT, LOW);
digitalWrite(CSMT, LOW);
digitalWrite(DATMT, LOW);
digitalWrite(STBMT, LOW); //инициализация
digitalWrite(STBMT, HIGH); //инициализация
digitalWrite(CSMT, HIGH); //выбор чипа
digitalWrite(RSTMT, HIGH);
digitalWrite(RSTMT, LOW); //сброс
digitalWrite(CSMT, LOW);
digitalWrite(STBMT, LOW);

}
void SetAddr(uint8_t addr) {
digitalWrite(AX0, bitRead(addr, 0));
digitalWrite(AX1, bitRead(addr, 1));
digitalWrite(AX2, bitRead(addr, 2));
digitalWrite(AX3, bitRead(addr, 3));
digitalWrite(AY0, bitRead(addr, 4));
digitalWrite(AY1, bitRead(addr, 5));
digitalWrite(AY2, bitRead(addr, 6));
}
void SetKey(boolean data) {
digitalWrite(CSMT, HIGH); //выбор чипа
digitalWrite(STBMT, HIGH); //строб on
digitalWrite(DATMT, data); //данные
digitalWrite(STBMT, LOW); //строб off
digitalWrite(CSMT, LOW);
}
void loop()
{
//чтение кода
ps2::KeyboardOutput scanCode = ps2Keyboard.readScanCode();

if ( scanCode != ps2::KeyboardOutput::none ) {
switch (scanCode) {
case ps2::KeyboardOutput::unmake: { //если считался префикс 0xF0 (отпускание клавиши)
d = LOW;
break;
}
case ps2::KeyboardOutput::extend: { //если считался префикс 0xE0 -- игнорим
extkey = HIGH;
break;
}
case ps2::KeyboardOutput::sc2_leftShift: { //если считался код 0x12 SS (Shift)
if ( extkey == LOW) { // если был код с префиксом 0xE0, то игнорируем нажатие
digitalWrite(SS, !d);
}
extkey = LOW;
d = HIGH;
break;
}
case ps2::KeyboardOutput::sc2_leftCtrl: { //если считался код 0x14 RUS (Ctrl)
digitalWrite(RUS, !d);
d = HIGH;
extkey = LOW;
break;
}
case ps2::KeyboardOutput::sc2_capsLock: { //если считался код 0x58 US (CapsLock)
digitalWrite(US, !d);
d = HIGH;
break;
}
case ps2::KeyboardOutput::sc2_f11: { //если считался код 0x78 VVD (F11)
digitalWrite(VVD, !d);
}
case ps2::KeyboardOutput::sc2_f12: { //если считался код 0x07 SBR (F12)
digitalWrite(SBR, !d);
d = HIGH;
break;
}
default: {
byte c = (byte)scanCode;
if ( c < 128 ) { // скан-код может быть больше!
if ( table[c] != 0xFF ) {
SetAddr(table[c]);
SetKey(d);
}
}
extkey = LOW;
d = HIGH;
}
}
}
else {
if (digitalRead(IRUS) == LOW) { //проверяем состояние индикатора РУС
if ( OldRUS == HIGH ) {
ps2Keyboard.sendLedStatus(ps2::KeyboardLeds::numLo ck | ps2::KeyboardLeds::scrollLock);
lastLedSent == (ps2::KeyboardLeds::numLock | ps2::KeyboardLeds::scrollLock);
OldRUS = LOW;
}
}
else {
if ( OldRUS == LOW ) {
ps2Keyboard.sendLedStatus(ps2::KeyboardLeds::numLo ck);
lastLedSent == ps2::KeyboardLeds::numLock;
OldRUS = HIGH;
}
}
}
}
Подключение к Вектору:
J2 -- порт PB
J3 -- порт PA
J1:4 -- PC5 (кнопка СС)
J1:1 -- PC6 (кнопка УС)
J1:3 -- PC7 (кнопка РУС)
H2:TX -- сигнал ВВОД
H2:RX -- сигнал СБРОС
Сигнал индикатора РУС следует подпаять к выводу 27 чипа ATMEGA168 на плате. Удобнее было бы использовать выводы под кварц, но они что-то не заработали...

Важный момент: для нормальной работы клавиатуры требуется подтяжка линий порта РВ (резисторы R35..R42, RP43) и установка диодов (VD3..VD8, VD12, VD13) в линии порта РА в соответствии со схемой клавиатуры Вектора (https://github.com/ImproverX/Vector-KBD/blob/main/kbd_circuit.png).

https://s1.hostingkartinok.com/uploads/thumbs/2024/05/d58493d81690e014edfb336d53c8e43c.png (https://hostingkartinok.com/show-image.php?id=d58493d81690e014edfb336d53c8e43c) https://s1.hostingkartinok.com/uploads/thumbs/2024/05/e333693a123deecd5938ccf4ef46dc22.png (https://hostingkartinok.com/show-image.php?id=e333693a123deecd5938ccf4ef46dc22)

eugenine
13.06.2024, 23:09
Сегодня закончил ПО для подключения клавиатуры PS/2 к РАДИО-86РК с использованием этого контроллера.
Выложил сюда. https://disk.yandex.ru/d/628eTBNh7pVRIQ

ПО для подключения PS/2 клавиатуры к компьютеру Радио-86РК с использованием "Универсального контроллера
PS/2 клавиатуры для компьютеров с матричными клавиатурами", купленного мной у Xrust по адресу:
https://zx-pk.com/forum/viewtopic.php?f=7&t=18766
(далее Контроллер).

Схема подключения Контроллера в архиве.

1. Символы соответствуют клавишам на стандартной клавиатуре (101 клавиша);
2. Клавиши Shift (правый и левый) соответствуют клавише СС клавиатуры Радио-86РК;
3. Клавиши Ctrl (правый и левый) соответствуют клавише УС клавиатуры Радио-86РК;
4. Клавиши Alt (правый и левый) соответствуют клавише Рус/Лат клавиатуры Радио-86РК. Состояние светодиода
Рус/Лат отображается светодиодом ScrolLock. Эмуляция светодиода клавиатуры не полная - переключение его
состояния происходит только после нажатия какой-либо клавиши (мигание при вводе с ленты видно не будет);
5. Клавиши "~" на основной клавиатуре и "Inset" на дополнительной соответствуют клавише СТР клавиатуры Радио-86РК;
6. Клавиши "Home" на дополнительной и "7/Home" на цифровой клавиатуре соответствуют стрелке вверх и влево клавиатуры Радио-86РК;
7. Клавишей "NumLock" осуществляется переключение состояния ввода на цифровой клавиатуре - либо цифры (NumLock = on),
либо управляющие коды стрелок. Состояние NumLock запоминается в энергонезависимой памяти и отображается соответствующим
светодиодом на клавиатуре.
8. Клавишей "CapsLock" осуществляется фиксация нажатия Shift и отображается соответствующим светодиодом на клавиатуре.
9. Клавиша "Esc" соответствуют клавише АР2 клавиатуры Радио-86РК.

При написании кода использовались 3 библиотеки, которые возможно использовать и не для эмуляции клавиатуры Радио-86РК:
1. Библиотека Timers.h - таймеры на мили и микросекунды
2. Библиотека ps2kbdraw.h - библиотека низкоуровневой работы с клавиатурой ps/2;
3. Библиотека cps2kbd.h - библиотека высокоуровневой работы с клавиатурой ps/2;

Для того, чтобы контроллер перезагружался одновременно с компьютером на его вход #RESET - 5 нога разъёма J1 должен быть подан 0.
Если происходят ошибки при работе с клавиатурой (рассинхронизация или её извлечение из разъёма) происходит перезагрузка Контроллера.

С уважением.
Нечитайлов Евгений.