Bài 18: Lập trình STM32 USB HID Keyboard bàn phím máy tính

stm32 usb hid keyboard

Ở bài trước chúng ta đã làm quen với USB HID để tạo 1 con chuột máy tính, ở bài này chúng ta sẽ sử dụng STM32 USB HID Keyboard để chế tạo 1 chiếc bàn phím đơn giản, giao tiếp với máy tính nhé.

Bài 18 trong Serie Lập trình STM32 từ A tới Z

Bàn phím máy tính hoạt động như thế nào?

Lý thuyết quét phím ma trận

Về mặt phần cứng, bàn phím (Keyboard) là tập hợp các nút nhấn được thiết kế theo dạng ma trận phím, nghĩa là các nút được nối chung hàng và cột. Vi điều khiển sẽ quét hàng hoặc cột theo một chu kì cố định để tìm kiếm sự thay đổi về trạng thái nút, sau đó gửi lên máy tính thông qua chuẩn USB HID.

quét phím
quét phím ma trận 4×3

Ví dụ: trong hình trên chúng ta có 1 ma trận phím 4×3.

Để đọc được phím nhấn, vi điều khiển sẽ lần lượt đưa tín hiệu quét vào các chân hàng 2, 7, 6, 4 (quét hàng), sau đó đọc giá trị từ 3 chân cột 3, 1, 5.
Nếu khi quét chân 2 mà chân 3 nhận được tín hiệu => nút 1 được nhấn.

Tương tự với các nút còn lại. Bạn cứ hình dung giống như điểm danh trong lớp: gọi lần lượt từng hàng ghế, hàng nào đang được gọi mà có bạn giơ tay ở cột nào thì biết ngay vị trí bạn đó.

Khi vi điều khiển biết được nút nào được nhấn, nó sẽ gửi 1 gói tin lên máy tính chứa mã của phím đó, để máy tính hiểu rằng phím đã được nhấn.

Để hiểu rõ hơn về bàn phím các bạn đọc bài viết: Lập trình STM32 giao tiếp ma trận bàn phím 3×4

Bàn phím thực tế

Trong thực tế bàn phím máy tính có rất nhiều nút nhấn, bao gồm 2 loại chính:

  • Các nút kí tự: A-Z, số, các kí tự đặc biệt…
  • Các nút bổ trợ (modifier): Shift, Ctrl, Alt, Windows…

Tất cả các phím được sắp xếp theo tiêu chuẩn nhất định. Mặc dù các loại bàn phím khác nhau sẽ có thêm hoặc bớt các phím, thế nhưng cấu trúc của bàn phím hầu như không đổi.

k200 media keyboard refresh b2b b2c

Report Descriptor USB HID của bàn phím máy tính

Phân tích Report Descriptor Keyboard

Để máy tính hiểu được dữ liệu chúng ta gửi lên thì Keyboard phải cung cấp 1 Report Descriptor, sau đó dữ liệu gửi lên phải đúng format của Report Descriptor đó. Bạn có thể Google search: Report Descriptor Keyboard là sẽ có ngay kết quả.

Sử dụng công cụ phân tích Report Descriptor ở bài trước, ta được kết quả như sau:

0x05, 0x01,        // Usage Page (Generic Desktop Ctrls)
0x09, 0x06,        // Usage (Keyboard)
0xA1, 0x01,        // Collection (Application)
0x05, 0x07,        //   Usage Page (Kbrd/Keypad)
0x19, 0xE0,        //   Usage Minimum (0xE0)
0x29, 0xE7,        //   Usage Maximum (0xE7)
0x15, 0x00,        //   Logical Minimum (0)
0x25, 0x01,        //   Logical Maximum (1)
0x75, 0x01,        //   Report Size (1)
0x95, 0x08,        //   Report Count (8)
0x81, 0x02,        //   Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x95, 0x01,        //   Report Count (1)
0x75, 0x08,        //   Report Size (8)
0x81, 0x03,        //   Input (Const,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x95, 0x05,        //   Report Count (5)
0x75, 0x01,        //   Report Size (1)
0x05, 0x08,        //   Usage Page (LEDs)
0x19, 0x01,        //   Usage Minimum (Num Lock)
0x29, 0x05,        //   Usage Maximum (Kana)
0x91, 0x02,        //   Output (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x95, 0x01,        //   Report Count (1)
0x75, 0x03,        //   Report Size (3)
0x91, 0x03,        //   Output (Const,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x95, 0x06,        //   Report Count (6)
0x75, 0x08,        //   Report Size (8)
0x15, 0x00,        //   Logical Minimum (0)
0x25, 0x65,        //   Logical Maximum (101)
0x05, 0x07,        //   Usage Page (Kbrd/Keypad)
0x19, 0x00,        //   Usage Minimum (0x00)
0x29, 0x65,        //   Usage Maximum (0x65)
0x81, 0x00,        //   Input (Data,Array,Abs,No Wrap,Linear,Preferred State,No Null Position)
0xC0,              // End Collection

// 63 bytes

Như vậy Report Descriptor của bàn phím dài 63 byte (của chuột máy tính là 74 byte). Bộ mô tả này chỉ được gửi 1 lần khi cắm thiết bị vào máy tính, để máy tính biết cách đọc các gói tin về sau. Dữ liệu trao đổi qua USB HID gồm Input là các phím được nhấn, còn Output dùng để máy tính điều khiển các đèn LED trên bàn phím (Num Lock, Caps Lock…).

Cấu trúc dữ liệu khi gửi của HID KeyBoard

Nhìn vào Report Descriptor của Keyboard chúng ta cũng dễ dàng phân tích được dữ liệu sẽ truyền lên máy tính như thế nào.

Khi Keyboard truyền lên máy tính thì gói tin sẽ gồm tất cả các mục Input trong Report Descriptor.

Tổng cộng là 1 byte + 1 byte + 6 byte = 8 byte cho mỗi lần gửi.

Trong đó:

  • Byte đầu tiên là Modifier keys status: gồm 8 bit, mỗi bit ứng với 1 phím bổ trợ có mã từ 0xE0 – 0xE7 (Left Ctrl, Left Shift, Left Alt, Left GUI, Right Ctrl, Right Shift, Right Alt, Right GUI). Bit nào bằng 1 là phím đó đang được giữ.
  • Byte thứ 2 là byte dự trữ (Reserved, mục Const), luôn bằng 0, chúng ta không cần quan tâm
  • 6 byte còn lại là Keypress fields có giá trị từ 0x00 – 0x65 (0 – 101 theo hệ thập phân): chứa mã của các phím kí tự đang được nhấn, tối đa 6 phím cùng lúc

STM32 USB HID Keyboard

Chi tiết tham khảo tài liệu về USB HID Keyboard: https://wiki.osdev.org/USB_Human_Interface_Devices

Vậy làm thế nào chúng ta biết được mỗi phím tương ứng với giá trị nào? Hãy cùng tham khảo bảng sau:

Với trường Modifier keys status, các mã từ E0 – E7 tương ứng với phím bổ trợ như sau:

STM32 USB HID Keyboard 2

Với trường Keypress fields, giá trị từ 0x00 – 0x65 tương ứng với kí tự nào được nhấn:

STM32 USB HID Keyboard 3

Chi tiết tham khảo tài liệu bảng mã kí tự trên USB HID Keyboard: https://d1.amobbs.com/bbs_upload782111/files_47/ourdev_692986N5FAHU.pdf

Lập trình STM32 USB HID Keyboard bàn phím máy tính

Cấu hình STM32 USB HID Keyboard trên CubeMX

Cấu hình SYS – Debug – Serial Wire. RCC – HSE – Crystal/Ceramic Resonator.

Cấu hình GPIO Input – Pull Up. Cấu hình tương tự Bài STM32 với Keyboard

Screenshot 2 1
Cấu hình GPIO
USB HID KEYBOARD 1
USB chế độ Device
USB HID KEYBOARD 2
Middleware chọn HID Class
USB HID KEYBOARD 3
Clock USB chọn 48MHz
USB HID KEYBOARD 4
Gen code và Open Project

Lập trình STM32 USB HID Keyboard trên Keil C

Sau khi mở project, chúng ta phải cấu hình lại cho HID, bởi vì mặc định CubeMX Gen ra là chuột máy tính. Đầu tiên sửa nInterfaceProtocol (trong Configuration Descriptor) từ 0x02 (Mouse) thành 0x01 (Keyboard).

HID Keilc 1
Chỉnh Protocol thành 0x01
HID Keilc 2
Chỉnh Report Descriptor
HID Keilc 3
Tìm tới nơi define kích thước Report
HID Keilc 4
Chỉnh lại kích thước Report Descriptor là 63

Lưu ý: Endpoint IN mà CubeMX sinh ra cho chuột chỉ có HID_EPIN_SIZE = 4 byte, trong khi report bàn phím dài 8 byte. Các bạn sửa HID_EPIN_SIZE trong usbd_hid.h thành 8, nếu không gói tin gửi lên sẽ bị cắt và máy tính nhận sai phím.

Nhấn F7 Build và F8 nạp chương trình vào KIT. Sau đó cắm cổng Micro USB vào máy tính. Vào Device Manager để xem thiết bị đã chuyển thành Keyboard chưa. Các bạn nếu chưa biết làm thì đọc lại bài STM32 HID Chuột máy tính nhé!

usb hid

OK, vậy là đã config xong HID. Chúng ta bắt đầu lập trình để Keypad có thể gửi được dữ liệu lên máy tính.

Phần Keypad các bạn tải thư viện và thêm vào project theo hướng dẫn: STM32 Keypad 3×4

Trong main.c, chúng ta include thư viện Keypad và usbd_hid.h vào.

Khởi tạo các biến cho USB và Keypad

Screenshot 3 1
Thêm thư viện và khai báo các biến

Phần KEYMAP, thay vì các kí tự từ 1 – 9, chúng ta sẽ đối chiếu với bảng mã bên trên, sau đó thay vào các giá trị Hex của bàn phím tương ứng với phím 1 – 9. Phím # mình sẽ thay bằng Enter.

Screenshot 4 1

Trước while chúng ta khởi tạo Keypad, sau đó đọc dữ liệu từ bàn phím.

Nếu phím được nhấn, copy mã phím vào report[2] (Keycode 1), sau đó gửi dữ liệu đi.

Tiếp đến xóa dữ liệu và báo nhả phím bằng cách gửi 1 report trống (toàn byte 0).

Lưu ý: Nếu bạn không gửi report trống lên, máy tính sẽ hiểu là phím vẫn đang được giữ và lặp lại kí tự đó liên tục, giống như khi bạn đè tay lên 1 phím.

Build và nạp vào KIT.

Kết nối phần cứng

PA0, PA1, PA2, PA3 theo thứ tự nối với các chân hàng 2, 7, 6, 4 của Keypad

PA4, PA5, PA6 theo thứ tự nối với các chân cột 3, 1, 5 của Keypad

Kết quả

Kết

STM32 USB HID Keyboard khá giống với HID Mouse hay tất cả các kiểu thiết bị khác sử dụng chuẩn HID. Với kiến thức ở bài này, bạn có thể dễ dàng tự làm cho mình 1 chiếc bàn phím máy tính mà không cần mua ở ngoài cửa hàng.
Nếu thấy bài viết này có ích hãy chia sẻ cho bạn bè và cùng vào Group Nghiện Lập Trình để kết nối với những anh em thích lập trình nhé!!!
Link Code mẫu: Hướng dẫn download tài liệu lập trình stm32

 

5/5 - (1 bình chọn)

2 những suy nghĩ trên “Bài 18: Lập trình STM32 USB HID Keyboard bàn phím máy tính”

Để lại một bình luận

Email của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *