Giao tiếp USB HID trên stm32 với c# window form

giao tiep usb hid
giao tiep usb hid

Giao tiếp usb là giao tiếp rất tiện lợi giúp cho các thiết bị kết nối với máy tính nhanh chóng tiện lợi. Ngoài USB CDC. các bạn có thể phát triển ứng dụng theo hướng USB HID, điểm lợi so với USB CDC là phần mềm sẽ tự động nhận dạng và kết nối với thiết bị ngay lập tức mà không cần phải kiểm tra thủ công qua cổng COM, hơn nữa USB HID STM32 sẽ giúp bạn cá nhân hóa sản phẩm làm cho project trở nên chuyên nghiệp hơn.

USB Custom HID là dạng giao tiếp usb do người dùng tùy biến do vậy, mình đã cấu hình và chỉnh sửa sẵn thư viện usb_hid_device để có thể hoạt động được ngay mà không cần chỉnh sửa gì hết

Tạo project trên chip stm32

Trong bài này mình sẽ dùng kit stm32f103c8t6 bluepill

Các bạn mở cubemx và tạo project như bình thường

Đừng quên tích chọn Serial Write để có thể nạp chương trình và debug

Tích chọn USB Device (FS)

Chúng ta sẽ sử dụng thư viện Muddlewave USB_DEVICE cho cubemx hỗ trợ, các bạn chọn class là Custom Human Interface Device Class

Sau đó sinh code với KeilC hoặc tool khác nếu các bạn muốn

COPY thư viện Custom HID by IoT47

Do các gói thư viện mà ST cung cấp luôn được update thường xuyên nên những gì mình hướng dẫn có thể sẽ không chạy được ở phiên bản CubeMx mà các bạn dùng trong tương lại, do vậy hãy copy đè thư viện USB mà mình cung cấp vào project của bạn để đảm bảo hoạt động chính xác

Các bạn tải thư viện tại đây

Ngoài ra thư mục project do CubeMX sinh ra cho mình như sau

usb hid stm32

Nếu của bạn khác thì có lẽ phiên bản cubemx bạn đang dùng là bản cũ. Các bạn nên update lên phiên bản cubemx mới nhất ( phiên bản cubemx của mình là 6.1.0)

Tiến hành copy đè như sau: ( chú ý màu cam là file/thư mục của mình, màu xanh là file/thư mục của CUBEMX sinh ra cho các bạn

  1. Ghi đè hoàn toàn thư mục STM32_USB_Device_Library vào Middlewares/ST
  2. Ghi đèn hoàn toàn thư muc USB_DEVICE vào thư muc USB_DEVICE
  3. Ghi đè 2 file stm32f1xx_hal_pcd.cstm32f1xx_ll_usb.c trong thư mục Driver vào thư mục Driver/STM32F1xx_HAL_Driver/Src
  4. Ghi đè 2 file stm32f1xx_hal_pcd.hstm32f1xx_ll_usb.h ở trong thư mục Driver vào thư mục Driver/STM32F1xx_HAL_Driver/Inc

Vậy là xong, tiến hành biên dịch và nạp code, kết nối cổng usb vào máy tính. Trong phần Setting – Devices của win10, máy tính đã nhận ra thiết bị USB có tên là IOT47 USB STM32 Demo

usb hid stm32

Ngoài ra, trong Device Manger máy tính đã nhận dạng và thêm nó vào phân lớp Human Interface Devices (HID)

usb hid stm32

Tùy biến tên thiết bị của bạn và VID PID

Máy tính đã nhận ra thiết bị của mình với tên gọi là IOT47 USB HID Demo, để đổi tên này, các bạn thay đổi trong file usbd_desc.c

Các bạn cũng nên thay đổi cả chỉ số VID và PID

usb hid stm32

Giao tiếp truyền nhận dữ liệu với máy tính

Phân lớp USB HID được window hỗ trợ nên hoàn toàn không cần cài driver gì cả. Tuy nhiên ngôn ngữ lập trình c# được thiết kế để che đi phần cứng rất nhiều và việc dùng c# để lập trình giao tiếp với 1 thiết bị ở phân lớp HID là khá khó khăn. Do vậy thay vì giao tiếp c# với stm32 trực tiếp ở lớp HID – USB Input Device. Mình lập trình thông qua 1 thư viện driver được gọi là LibUSBDotNet

Tải LibUSBDotNet tại đây

Sau khi tải về, các bạn giải nén và vào thư mục bin, chạy phần mềm inf-wizard. Phần mềm này sẽ giúp chúng ta tạo ra file driver ( file driver này các bạn sẽ đưa cho người dùng cài đặt vào máy tính của họ)

usb hid stm32

Lúc này, phần mềm sẽ hiện ra danh sách các thiết bị usb đang được kết nối với máy tính. Mình sẽ chọn tới thiết bị USB của mình có tên là IOT47 USB STM32 Demo và số VID là 0x0483 (1155) và PID là 0x5762 (22370)

usb hid stm32
usb hid stm32

Chọn ví trí lưu, sau đó ấn Install

usb hid stm32

Vậy là xong, driver đã được cài vào máy tính của bạn

Lúc này thiết bị USB cũng không nằm trong mục Human Interface devices nữa mà nằm trong lớp libusb-win32 devices

usb hid stm32

Lập trình window form trên Visual Studio

Sau khi khởi tạo project c#, các bạn tiến hành cài đặt thư viện libusbdotnet cho c#

Click chuột phải vào tên tên project trong ở bảng Solution Explorer -> vào Manage NuGet Packages for Solution.

Sau đo chọn tab Browser và gõ tìm kiếm libusbdotnet

Các bạn nhấn install để cài đặt thư viện libusbdotnet vào cho c#

Tạo giao diện truyền nhận dữ liệu usb

Ở đây mình tạo 1 giao diện rất đơn giản gồm có 1 ô truyền dữ liệu đi và 1 ô show dữ liệu nhận đc

Trong file code, add thư viện libusbdotnet

Khai báo 1 số biến toàn cục

Trong đó 1155 là VID và 22370 là PID ( nó phải trùng với vid và pid của stm32 nhé)

Trong sự kiện ấn vào nút kết nối chúng ta sẽ khởi tạo cổng usb và kết nối với thiết usb phía dưới. Nếu kết nối thành công thì sẽ chuyển thành chữ “Ngắt kết nối”, ngược lại thì báo lỗi

Tiếp theo mình sẽ viết hàm truyền dữ liệu usb xuống khi ấn vào button Truyền

Và hàm nhận dữ liệu khi có dữ liệu usb từ stm32 truyền lên. Khi đó chúng ta sẽ in nó ra textbox. Do đây là 1 event nên chúng ta sẽ in ra textbox thông qua Invoke để tránh bị lỗi

Full code trên c# như sau

Lập trình truyền nhận trên STM32

Để gửi, các bạn include thư viện include “usbd_customhid.h” vào trong main.c

Bây giờ có thể gọi hàm USBD_CUSTOM_HID_SendReport để gửi dữ liệu

Lưu ý: khi gửi bắt buộc phải gửi 65 byte với byte đầu tiên luôn là 0x01

Do đó mình sẽ khai báo mảng uint8_t USB_TX_Buffer[65]

Mình sẽ liên tục gửi lên 1 tin nhắn là “Iot47 USB hid demo” mỗi 100ms kèm theo 1 biến đếm tăng dần, nên mình khai báo thêm 1 biến int dem=0;

Bây giờ trong hàm main, vòng lặp while(1)

Còn nhận thì sao ?

Khi có dữ liệu gửi tới cho stm32, hàm ngắt CUSTOM_HID_OutEvent_FS trong file usbd_custom_hid_if.c sẽ được gọi.

65 byte dữ liệu ( byte đầu mặc định là 0x02) sẽ được lưu vào mảng USB_RX_Buffer trong file usbd_custom_hid_if.c. Có code gì thì viết vô đó nhé !

Các bạn dán tên mảng USB_RX_Buffer vào Watch1 ( của sổ debug) để coi dữ liệu nhận được cho tiện nhé !

Bây giờ test thử nào !

Tải toàn bộ project stm32 và c# tại đây

 

Từ tác giả:

Nếu có bất kì thắc mắc nào trong bài viết, vui lòng để lại comment dưới mỗi bài ! Mình sẽ không trả lời thắc mắc của các bạn ở facebook hay email !

Nếu trong phần code bạn nhìn thấy nhưng thứ kiểu như &amp; thì đó là lỗi hiển thị, cụ thể 3 kí tự < > & bị biến đổi thành như thế
&amp; là &
&lt;  là <
&gt; là >

Giới thiệu Đào Nguyện 80 bài viết
DIY,chế cháo, viết blog chia sẽ kiến thức về lập trình,điện tử - IoT. Rất mong được giao lưu, kết bạn với các bạn cùng đam mê. Địa chỉ Facebook: https://www.facebook.com/nguyendao207

9 bình luận

  1. Em còn vài bài tập chưa làm được nên có thể nhờ anh một chút được không ạ?Nếu có thể em sẽ trả phí anh nhé!  1. Dùng vi điều khiển STM32F103 giao tiếp với 8 led đơn và 2 nút nhấn ON, OFF. Khicấp điện thì 8 led tắt, khi nhấn ON thì 8 led sáng, khi nhấn OFF thì 8 led tắt. (Dùng ngắt ngoài).   2. Dùng vi điều khiển STM32F103 giao tiếp với 8 led đơn và 3 nút nhấn ON, OFF,INV. Khi cấp điện thì 8 led tắt, khi nhấn ON thì 4 led thấp (D) sáng, khi nhấn INV thì đảo trạng thái của 8 led: 4 sáng thành tắt, 4 tắt thành sáng, khi nhấn OFF thì 8 led tắt.(Dùng ngắt ngoài).  3. Mạch đếm từ 00 đến 99, dùng vi điều khiển STM32F103 kết nối với 2 led 7 đoạn anode chung và 3 nút nhấn Start, Stop. Viết chương trình thực hiện chức năng: khi cấp điện thì led hiển thị 00, khi nhấn Start thì mạch đếm từ 00 đến 99, nếu nhấn Stop thì ngừng tại giá trị đang đếm, nhấn Start thì đếm tiếp (đếm xuống đến 00 thì ngừng ở 00, đếm lên đến 99 thì ngừng ở 99).  4. Hãy thêm vào bài 6 một nút nhấn có tên là INV có chức năng đảo chiều đếm lên, đếm xuống. Đang đếm lên nếu nhấn INV thì sẽ đếm xuống từ giá trị đang đếm, tương tự khi đang đếm xuống mà nhấn INV thì sẽ đếm lên (có 1 led hiển thị chiều đếm, đếm lên led sáng, đếm xuống led tắt, chân tuỳ chọn).  
    *Yêu cầu: phân tích đề bài, chức năng cần sử dụng, vào CubeMX cấu hình, sinh code, mở Keil C viết code và giải thích ý nghĩa từng dòng code, đoạn code mà mình thêm vào, mở proteus (nối mạch sẵn) nạp code kiểm nghiệm hoạt động của chương trình

Đã đóng bình luận.