안녕하세요. 오늘은 UART TO HID칩에 대해 알아보겠습니다.
사용할칩은 WCH사의 CH9329입니다.
CH9329는 UART통신을 통해서 HID신호로 키보드, 마우스, 커스텀HID를 보낼 수 있습니다.
동작모드는 키보드+마우스+커스텀HID용(모드0), 키보드용(모드1) 등등있는데 여기서는 디폴트모드인 모드0을 사용해서 키보드신호만 보내보겠습니다.
사용할모듈에는 회로구성이 되어있고 디폴트모드를 사용할것이므로 따로 바꿀건 없습니다.
MODE0(2), MODE1(3), CFG0(4), CFG1(5)을 통해서 모드 설정을하고 RXD(7),TXD(8)을 통해서 UART신호를 주고받습니다.
UART통신을 하는 장비로는 MCU를 사용해도되고 usb to uart모듈을 사용해도 됩니다. 이 글에서는 usb to uart를 사용하고 C#을 이용해서 CH9329랑 통신하겠습니다. CH9329의 기본 bps는 9600입니다.
통신프로토콜은 아래와 같습니다.
HEAD | ADDR | CMD | LEN | DATA | SUM |
2바이트 | 1바이트 | 1바이트 | 1바이트 | N바이트(0~64) | 1바이트 |
HEAD는 0x57, 0xAB로 고정입니다.
ADDR는 디폴트로 0x00입니다.
CMD는 모드에따라서 설정을 하면 됩니다. 키보드신호를 보내는건 0x02입니다.
LEN: DATA의 길이입니다.
SUM : HEAD+ADDR+CMD+LEN의 합이고 하위1바이트를 사용합니다.
키보드로 A를 보내려면 0x57, 0xab, 0x00, 0x02, 0x08, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10을 보내면 됩니다. 여기서 중요한건 DATA인데 8바이트를 보냈고 빨강글씨와 같습니다. 해당 8바이트는 프로토콜은 키보드 프로토콜입니다. [ Modifier | Reserved | Keycode 1 | Keycode 2 | Keycode 3 | Keycode 4 | Keycode 5 | Keycode 6 ]와 같은 형태이고 Modifier 은 Shift, Ctrl, Alt와 같은 키를 나타내고 Keycode 1~6은 키를 눌렀을때 나타내는 바이트입니다. USB HID 문서에 키보드의 키를 바이트로 나타낸 약속이 나와있습니다.
실제 키보드의 데이터를 나타낸 사진입니다. a를 눌렀을때 DATA필드에 (00,00,04,00,00,00,00,00)로 인식된걸 볼 수 있습니다. 해당데이터는 키를 press한거고 release할때 (00,00,00,00,00,00,00,00)을 보내줘야합니다. release 신호를 안보내주면 키가 계속 눌려있다고 인식합니다.
Modifier가 02면 SHIFT입니다
A,B,C를 누르면 Keycode에 하나씩 채워지는걸 볼 수 있습니다.
이제 다시 CH9329 프로토콜로 돌아와보면 a를 보낼때 { 0x57, 0xab, 0x00, 0x02, 0x08, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10}를 보내고 릴리즈로 { 0x57, 0xab, 0x00, 0x02, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C}를 보내면 됩니다.
여기서 중요한게 a를 보내고 몇초후에 릴리즈를 보낼건지 타이밍을 맞춰야합니다.
CH9329는 키 커맨드를 받고나서 해당 데이터를 보내줍니다. {0x57, 0xab, 0x00, 0x82, 0x01, 0x00, 0x85} 해당데이터는 실행이 됐다는 의미입니다.
그래서 결론적으로 a를 보내는 순서입니다
1. CH9329에게 데이터 전달 {0x57, 0xab, 0x00, 0x02, 0x08, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10}
2. CH9329에게 데이터 수신 {0x57, 0xab, 0x00, 0x82, 0x01, 0x00, 0x85}
3. CH9329에게 데이터 전달 {0x57, 0xab, 0x00, 0x02, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C}
4. CH9329에게 데이터 수신 {0x57, 0xab, 0x00, 0x82, 0x01, 0x00, 0x85}
그래서 파형이 아래처럼 나오면 됩니다. 데이터를 전달하고 데이터를 수신할때까지 기다렸다가 수신하면 다음 데이터를 보내는 방식으로 한다면 CH9329에게 데이터를 잘 인식시킬수 있습니다.
Winform으로 아래와 같은 UI로 구성했습니다. Data receive Box는 CH9329에게로부터 받은 데이터를 보여줍니다.
Send Box는 CH9329에게 보낼 데이터입니다. Test Box는 메모장 역할입니다. SEND 버튼을 누르면 2초후에 Send Box안에 있는 내용들을 CH9329에게 전달하는 방식입니다.
해당프로그램을 만들면서 고민한부분 몇개만 적어보겠습니다.
1. Textbox에서 문자열을 읽고 1바이트씩 데이터를 보내는 방식
아스키코드순서로 배열을 만들고 문자를 배열에 매칭시키는 방식으로 사용했습니다.
코드에서 _asciimap 배열에 아스키값과 키보드프로토콜의 값이 매칭되어있습니다. 예를들어 a는 97번이고 _asciimap 배열의 97번째항목에 0x04가 저장되어있습니다.
2. a는 0x04이고 대문자A를 인식하는 방식
Caps Lock의 상태에 따라서 0x04를 보낼때 a로 입력될때가있고 A로 입력될때가 있습니다. 해당프로그램에서는 Caps Lock을 해제했다는 가정으로 만들었습니다. 그래서 a면 0x04를 보내고 A면 SHIFT(0x02) + a(0x04)를 보내는 방식으로 했습니다.
3. 데이터를 보내고 수신한 데이터를 인식하는 방식
UART 데이터 리시브함수에서 수신버퍼에있는 바이트수를 읽고 수신버퍼에있는 개수로 데이터를 읽어서 배열에 저장했습니다. 그리고 저장한 데이터가 7개라면 올바른 데이터인지 비교한다음에 맞으면 다음데이터를 보내는 방식으로 했습니다.
4. 테스트 방식
문자열이 입력되는 방식이라 SEND버튼을 누르고 2초후에 CH9329에게 데이터를 보내는 방식으로 했습니다. 그래서 Test Box를 따로 만들었고 SEND버튼을 누르고 Test Box에 입력되게 했습니다.
소스코드 github
https://github.com/yhunterr/CH9329_control_csharp
'각종IC' 카테고리의 다른 글
74HC573 알아보기 (0) | 2024.10.20 |
---|---|
SN74HC04N IC 알아보기 (0) | 2023.03.26 |
PCF8574 IC 알아보기 (0) | 2022.09.24 |
74HC595 알아보기입니다. (1) | 2017.05.17 |