ArduinoUNO에서 PS/2 키보드를 사용한 메모
ArduinoUNO에서 PS/2 키보드 사용
옛 PC용 키보드는 동기 시리얼 통신이므로 AVR이라면 쉽게 연결할 수 있다고 생각해 보았다.
연결
일반적으로 동기 통신으로 8O1 (시작 비트 1, 데이터 8, 홀수 패리티, 정지 비트 1
Data, Clock 모두 오픈 콜렉터로 4.7KΩ으로 풀업되고 있다
키보드와 ArduinoUNO 연결
데이터 -> PIN0 (RX)
시계 -> PIN4 (XCK)
전원을 잊지 않고
키보드에서 수신
처음에 성실하게 레지스터를 설정했지만, Serial.begin에서 초기 설정 후에 동기 통신으로 변경하는 것만으로 수신 인터럽트도 포함해 사용할 수 있다.
Serial.begin(9600, SERIAL_8O1); //初期設定はおまかせして
UCSR0C |= (1 << UMSEL00); //同期通信モードへ変更
/*
ワイヤードOR接続のおまじない、Input時はハイインピーダンス
Output時はLOWになる
*/
pinMode(0, INPUT);
pinMode(4, INPUT);
digitalWrite(0, LOW);
digitalWrite(4, LOW);
읽기는 보통 Serial.Read()를 사용할 수 있으며, 데이터는 키 톱에 인쇄된 문자가 아니라 스캔 코드라고 불리는 데이터, 용도에 따라 변환이 필요
uint8_t get_usart() {
uint8_t c;
while (Serial.available() == 0)
;
c = (0x00ff & Serial.read());
return c;
}
키보드로 보내기
파워 온 리셋 이외로 리셋하는 경우나, 키보드의 LED를 컨트롤 하는 경우는 USART를 무효 유효 전환하거나 조금 번거로운 수속이 필요.
키보드에 대한 명령(일부)
1
2
3
재설정
0xFF
리셋
LED
0xED
다음 데이터로 LED 전도 소등 bit2=CapsLock,bit1=NumLock,bit0=ScrollLock
주요 답장 코드
1
2
3
Ack
0xFA
정상 수신
Resend
0xFE
데이터 재전송 요청
#define CLK_LO pinMode(4,OUTPUT);
#define CLK_HI pinMode(4,INPUT);
#define DATA_LO pinMode(0,OUTPUT);
#define DATA_HI pinMode(0,INPUT);
#define WAIT_CLK_LO while(digitalRead(4) == HIGH);
#define WAIT_CLK_HI while(digitalRead(4) == LOW);
#define DELAY 50
uint8_t send_data(uint8_t data) {
int shift = 1;
uint8_t parity = 0;
uint8_t rcv;
WAIT_CLK_HI; //busy?
delayMicroseconds(DELAY);
TIMSK1 &= ~(1 << OCIE1A); //timer off
UCSR0B &= ~(1 << RXEN0); //usart off
UCSR0C &= ~(1 << UMSEL00);
CLK_LO; //RTS
delayMicroseconds(DELAY);
DATA_LO; //start bit
delayMicroseconds(DELAY);
CLK_HI;
WAIT_CLK_LO; //キーボード発生のクロック待ち
delayMicroseconds(DELAY / 2);
while (shift != 0x100) {
if (data & shift) {
DATA_HI; //bit = 1
parity++;
} else {
DATA_LO //bit = 0
}
WAIT_CLK_LO;
WAIT_CLK_HI;
delayMicroseconds(DELAY / 2);
shift <<= 1;
}
//parity
if (parity & 0x01) {
DATA_LO; //bit = 1
} else {
DATA_HI; //bit = 0
}
WAIT_CLK_LO;
WAIT_CLK_HI;
delayMicroseconds(DELAY/2);
DATA_HI; //stop bit
WAIT_CLK_LO;
WAIT_CLK_HI;
WAIT_CLK_LO;
WAIT_CLK_HI;
UCSR0B &= ~(1 << RXCIE0); // intrrupt off
UCSR0B |= (1 << RXEN0); //usart on
UCSR0C |= (1 << UMSEL00);
while (!(UCSR0A & (1 << RXC0))); //キーボードから応答待ち
rcv = UDR0;
UCSR0B |= (1 << RXCIE0); // intrrupt on
TIMSK1 |= (1 << OCIE1A);
return rcv;
}
요약
수신만이라면 Serial.begin에 한 줄 추가하는 것만으로 간단하게 할 수 있는, 읽기 데이터가 스캔 코드이므로 조금 버릇이 있지만 키수가 많은 간단 입력 디바이스로서, 약간의 공작이나 실험에는 편리.
참고로 한 사이트
htp://이오이오입니다. 웨 b. FC2. 작은 m/PS2/PS2. HTML
Reference
이 문제에 관하여(ArduinoUNO에서 PS/2 키보드를 사용한 메모), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/Shigosen/items/58a5ba65a307e6046b1b텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)