1. Chuẩn bị nguyên liệu
Ban phát triển Explorer đúng giờ stm32f407 Explorer V2.4.
Phần mềm STM32CubeMX (Phiên bản 6.10.0).
keil µVision5 IDE (MDK-Arm).
Trình điều khiển ST-LINK/V2.
Trình giả lập Wildfire DAP.
Trợ lý cổng nối tiếp XCOM V2.6.
2. Mục tiêu thí nghiệm
Sử dụng phần mềm STM32CubeMX để định cấu hình bảng phát triển STM32F407 USB_OTG_FS làm USB_DEVICE (USB Slave) hoạt động ở chế độ Lớp thiết bị giao diện con người (HID) và sử dụng bốn nút người dùng lên, xuống, trái và phải để mô phỏng chuột hoặc bàn phím. Windows hoạt động.
3. Mô phỏng quá trình thí nghiệm trên chuột
3.0 Kiến thức tiên quyết
Để có kiến thức liên quan về USB, vui lòng đọc Hướng dẫn STM32CubeMX 29 USB_HOST - Sử dụng hệ thống tệp FatFs để đọc và ghi các thử nghiệm trên đĩa U trong phần "3. Tổng quan về USB". Để biết sơ đồ phần cứng giao diện phụ USB_SALVE, vui lòng đọc "4.0, Phần Kiến thức tiên quyết”.
Để biết cấu hình tham số trong tab Bộ mô tả thiết bị trong cấu hình tham số phụ USB, vui lòng đọc phần Hướng dẫn STM32CubeMX 30 USB_DEVICE - Thử nghiệm đầu đọc thẻ ngoại vi_Card của MSC "3.0, Kiến thức tiên quyết".
Định cấu hình giao diện thiết bị USB để hoạt động ở chế độ Lớp thiết bị giao diện con người (HID), sau đó kết nối nó với máy tính Windows thông qua cáp USB. Nó sẽ xuất hiện trong trình quản lý thiết bị của PC dưới dạng thiết bị đầu vào của con người. Thiết bị được mô phỏng dưới dạng chuột, bàn phím và các thiết bị ngoại vi khác. Theo mặc định, thiết bị ngoại vi HID do CubeMX tạo ra là chuột.
Thiết bị chuột và máy tính giao tiếp qua USB bằng giao thức chuột HID. Giao thức bao gồm bốn byte và được sử dụng để báo cáo trạng thái hiện tại của chuột cho máy tính. Ý nghĩa của bốn byte được thể hiện trong hình bên dưới.
Byte đầu tiên của dữ liệu 8 bit được dùng để biểu thị trạng thái nút trên chuột. Mỗi bit tượng trưng cho một nút, 1 nghĩa là đã nhấn, 0 nghĩa là không nhấn Nút ngoài cùng bên trái nằm ở bit thấp nhất của byte, thường là thấp nhất. bit. Để mô tả nút chuột trái, chữ số đầu tiên biểu thị nút chuột phải và chữ số thứ hai biểu thị nút chuột giữa.
Byte thứ hai biểu thị chuyển động tương đối của chuột theo hướng ngang (X). Ví dụ: đặt dữ liệu byte này thành 10 có nghĩa là di chuyển 10 tích tắc theo hướng dương của X; byte thứ ba biểu thị chuyển động của chuột theo chiều dọc. (Y) hướng. Ví dụ, chuyển động tương đối trên, đặt dữ liệu byte này thành -10 có nghĩa là di chuyển 10 tỷ lệ theo hướng âm của Y; byte thứ tư biểu thị trạng thái của con lăn, ví dụ: đặt dữ liệu byte này thành 10. có nghĩa là cuộn lên 10 thang đo.
3.1. Cấu hình liên quan đến CubeMX
3.1.0 Cấu hình dự án cơ bản
Mở phần mềm STM32CubeMX, nhấn ACCESS TO MCU SELECTOR để chọn board phát triển MCU (chọn model MCU điều khiển chính mà bạn sử dụng board phát triển), chọn model MCU và nhấn Start Project ở góc trên bên phải trang để bắt đầu dự án , như thể hiện trong hình dưới đây.
Sau khi khởi động dự án, hãy định cấu hình bộ dao động tinh thể HSE/LSE trong trang cấu hình chính System Core/RCC và định cấu hình chế độ Gỡ lỗi trong System Core/SYS, như minh họa trong hình bên dưới.
Để biết nội dung tạo dự án chi tiết, độc giả có thể đọc "Hướng dẫn STM32CubeMX 1 Tạo dự án".
3.1.1. Cấu hình cây đồng hồ
Cấu hình xung nhịp 48MHz trong cây xung nhịp thành 48MHz, tức là điều chỉnh thông số Q của Main PLL (vòng khóa pha chính) về 7. Các xung nhịp HCLK, PCLK1 và PCLK2 khác vẫn được đặt ở tần số xung nhịp cao nhất mà STM32F407 có thể đạt được, như thể hiện trong hình dưới đây.
3.1.2. Cấu hình tham số ngoại vi
Thử nghiệm này yêu cầu khởi tạo các nút người dùng WK_UP, KEY2, KEY1 và KEY0 trên bảng phát triển. Để biết các bước cấu hình cụ thể, vui lòng đọc "Đầu vào GPIO hướng dẫn STM32CubeMX 3 - Phản hồi chính".
Thử nghiệm này yêu cầu khởi tạo thiết bị ngoại vi TIM6 để đạt được thời gian 1ms. Để biết các bước cấu hình cụ thể, vui lòng đọc "Hướng dẫn STM32CubeMX Tổng quan về bộ đếm thời gian TIM 5 và bộ hẹn giờ cơ bản".
Thử nghiệm này cần khởi tạo USART1 làm kênh thông tin đầu ra. Để biết các bước cấu hình cụ thể, vui lòng đọc "Hướng dẫn STM32CubeMX 9 Giao tiếp không đồng bộ USART/UART".
Nhấp vào Kết nối/USB_OTG_FS trong cột phân loại chức năng ở phía bên trái của trang Pinout & Cấu hình, định cấu hình chế độ của nó thành chỉ phụ (Device_Only) và giữ tất cả các tham số khác làm mặc định. Cấu hình cụ thể như trong hình bên dưới.
Nhấp vào Middleware và Software Packs/USB DEVICE trong cột phân loại chức năng ở phía bên trái của trang Pinout & Configuration, định cấu hình chế độ của nó thành Human Interface Device Class (HID) và giữ tất cả các tham số khác làm mặc định. Như thể hiện trong hình.
HID_FS_BINTERVAL (chỉ định khoảng thời gian thăm dò để truyền ngắt): 0x01 ~ 0xFF tùy chọn, tính bằng mili giây. Đặt thành 0XA ở đây có nghĩa là máy chủ USB thăm dò thiết bị USB cứ sau 10 mili giây để nhận thông tin mới.
Đối với các tham số còn lại trong tab Cài đặt tham số và Bộ mô tả thiết bị, vui lòng đọc hai phần của Hướng dẫn STM32CubeMX 30 USB_DEVICE - Thử nghiệm đầu đọc thẻ ngoại vi_Card của MSC "3.0, Kiến thức tiên quyết" và "3.1.2, Cấu hình tham số ngoại vi".
3.1.3. Cấu hình ngắt ngoại vi
Khi chế độ USB_DEVICE được định cấu hình trong Middleware và SoftwarePacks không bị Tắt, ngắt toàn cục của USB_OTG sẽ tự động được bật và không thể tắt được.
Lưu ý rằng thử nghiệm này cần kích hoạt ngắt toàn cục của bộ định thời cơ bản TIM6 và kiểm tra ngắt toàn cục trong NVIC. Cấu hình cụ thể như trong hình bên dưới.
3.2. Tạo mã
3.2.0, Định cấu hình trang Trình quản lý dự án
Nhấp để vào trang Trình quản lý dự án, sửa đổi tên dự án, thư mục dự án và chuỗi công cụ trong cột Dự án ở bên trái, sau đó chọn "Tạo khởi tạo thiết bị ngoại vi dưới dạng một cặp tệp 'c/h' cho mỗi thiết bị ngoại vi" trong Trình tạo mã và cuối cùng nhấp vào Nhấp vào TẠO MÃ ở góc trên bên phải của trang để tạo dự án, như trong hình bên dưới.
Bạn đọc có thể đọc thử nghiệm “STM32CubeMX Tutorial 1 Project Setting” phần 3.4.3 để biết nội dung cấu hình Project Manager chi tiết.
3.2.1. Thiết lập quá trình gọi khởi tạo
Chưa có.
3.2.2 Quá trình gọi ngắt ngoại vi
Chưa có.
3.2.3 Thêm mã cần thiết khác
Ở cuối tệp main.c, thêm chức năng đặt giá trị tọa độ của con trỏ chuột bằng cách nhấn các nút và chức năng gọi lại bộ đếm thời gian TIM6 1ms. Mã nguồn cụ thể như sau.
/*Đặt giá trị tọa độ con trỏ chuột*/ static void GetPointerData(uint8_t *pbuf) { int8_t x = 0, y = 0, Button = 0, Wheel=0; /*Nút WK_UP được nhấn*/ if(HAL_GPIO_ReadPin(WK_UP_GPIO_Port, WK_UP_Pin) == GPIO_PIN_SET) { if(HAL_GPIO_ReadPin(WK_UP_GPIO_Port,WK_UP_Pin) == GPIO_PIN_SET) { printf("Cuộn bánh xe lên\r\n"); //y -= CURSOR_STEP; Bánh xe = 10; } } /*Nút KEY2 được nhấn*/ if ( HAL_GPIO_ReadPin(KEY2_GPIO_Port,KEY2_Pin) == GPIO_PIN_RESET) { if(HAL_GPIO_ReadPin(KEY2_GPIO_Port,KEY2_Pin) == GPIO_PIN_RESET) { printf("←←←\r\n"); x -= CURSOR_STEP; } } /*Phím KEY1 được nhấn*/ if(HAL_GPIO_ReadPin(KEY1_GPIO_Port,KEY1_Pin) == GPIO_PIN_RESET) { if(HAL_GPIO_ReadPin(KEY1_GPIO_Port,KEY1_Pin) == GPIO_PIN_RESET) { printf("Left_Button_Pressed\r\n"); //y += nút CURSOR_STEP; } } /*Phím KEY0 được nhấn*/ if(HAL_GPIO_ReadPin(KEY0_GPIO_Port,KEY0_Pin) == GPIO_PIN_RESET) { if(HAL_GPIO_ReadPin(KEY0_GPIO_Port,KEY0_Pin) == GPIO_PIN_RESET) { printf("→→→\r\n"); += CURSOR_STEP; } } pbuf[0] = nút; pbuf[1] = x; pbuf[2] = y; pbuf[3] = Bánh xe } /*TIM6 hẹn giờ 1ms chức năng gọi lại*/ void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) { static __IO bộ đếm uint32_t = 0; /* kiểm tra trạng thái Cần điều khiển mỗi khoảng thời gian bỏ phiếu (10ms) */ if(counter++ == USBD_HID_GetPollingInterval(&hUsbDeviceFS)) { GetPointerData(HID_Buffer); /* gửi dữ liệu qua điểm cuối IN*/ if((HID_Buffer[0] != 0) || (HID_Buffer[1] != 0) || (HID_Buffer[2] != 0) || (HID_Buffer[3] != 0)) { USBD_HID_SendReport(&hUsbDeviceFS, HID_Buffer, sizeof(HID_Buffer) } bộ đếm = 0;
Tệp main.c chứa các tệp tiêu đề được sử dụng, cũng như các định nghĩa/khai báo của một số biến được sử dụng. Cuối cùng, sau khi hàm chính main() khởi tạo các thiết bị ngoại vi, hãy mở bộ hẹn giờ TIM6 ở chế độ ngắt. Trình diễn.
/*tệp main.c*/ /*bao gồm tệp tiêu đề*/ #include "usbd_hid.h" /*xác định/khai báo các biến*/ extern USBD_HandleTypeDef hUsbDeviceFS; #define CURSOR_STEP 7 uint8_t HID_Buffer[4]; bộ đếm thời gian TIM6 trước vòng lặp chính*/ HAL_TIM_Base_Start_IT(&htim6);
4. Xác minh đốt cháy
Để ghi chương trình, hãy sử dụng cáp USB để kết nối giao diện USB_SALVE trên bo mạch phát triển với giao diện USB trên máy tính Windows. Sau khi kết nối thành công, bạn có thể giám sát hoạt động của hệ thống thông qua trợ lý cổng nối tiếp.
Đầu tiên hãy nhấn hai nút người dùng KEY2 và KEY0 trên bảng phát triển. Bạn có thể thấy rằng con trỏ chuột trên máy tính sẽ di chuyển sang trái hoặc phải khi nhấn các nút này. Sau đó nhấn nút người dùng phía trên WK_UP để tìm trợ lý cổng nối tiếp. hiển thị. Nội dung được kéo lên trên cùng, tức là con lăn được cuộn lên trên, sau đó con trỏ chuột được di chuyển đến nút cổng nối tiếp mở/đóng của trợ lý cổng nối tiếp. Sau khi nhấn nút KEY1, nó sẽ được tìm thấy. rằng cổng nối tiếp có thể được điều khiển để mở/đóng. Hiện tượng cụ thể như thể hiện trong hình bên dưới.
5. Mô tả tóm tắt quá trình thử nghiệm bàn phím mô phỏng
5.0 Kiến thức tiên quyết
Thiết bị bàn phím và máy tính giao tiếp qua USB bằng giao thức bàn phím HID. Giao thức này bao gồm 8 byte và được sử dụng để báo cáo trạng thái bàn phím hiện tại cho máy tính. Ý nghĩa của 8 byte như trong hình bên dưới (Lưu ý 1). ).
5.1. Cấu hình liên quan đến CubeMX
Không cần sửa đổi, chỉ cần sử dụng mã kỹ thuật được tạo khi mô phỏng chuột.
5.2. Tạo mã
Mở mã dự án đã tạo. Vì CubeMX mô tả thiết bị là thiết bị chuột theo mặc định, bạn có thể tìm thấy một mảng có tên HID_MOUSE_ReportDesc trong tệp usbd_hid.c. Mảng này là bộ mô tả thiết bị báo cáo chuột chính thức, vì vậy bạn cần sửa đổi bộ mô tả thiết bị. vào bộ mô tả thiết bị bàn phím và kích thước của mảng bộ mô tả thiết bị báo cáo HID_MOUSE_REPORT_DESC_SIZE cũng phải được sửa đổi Nội dung sửa đổi cụ thể như sau (Lưu ý 2).
/*Sửa đổi bộ mô tả thiết bị báo cáo trong usbd_hid.c*/ __ALIGN_BEGIN static uint8_t HID_MOUSE_ReportDesc[HID_MOUSE_REPORT_DESC_SIZE] __ALIGN_END = { 0x05, 0x01, // USAGE_PAGE (Màn hình chung) //63 0x09, 0x06, // USAGE (Bàn phím) 0xa1, 0x01, // THU THẬP (Ứng dụng) 0x05, 0x07, // USAGE_PAGE (Bàn phím) 0x19, 0xe0, // USAGE_MINIMUM (Điều khiển bên trái bàn phím) 0x29, 0xe7, // USAGE_MAXIMUM (GUI bàn phím bên phải) 0x15, 0x00, // LOGICAL_MINIMUM (0) 0x25, 0x01, // LOGICAL_MAXIMUM (1) 0x75, 0x01, // REPORT_SIZE (1) 0x95, 0x08, // REPORT_COUNT (8) 0x81, 0x02, // INPUT (Dữ liệu,Var,Abs) 0x95, 0x01 , // BÁO CÁO_COUNT (1) 0x75, 0x08, // REPORT_SIZE (8) 0x81, 0x03, // INPUT (Cnst,Var,Abs) 0x95, 0x05, // REPORT_COUNT (5) 0x75, 0x01, // REPORT_SIZE (1) 0x05, 0x08, // USAGE_PAGE (đèn LED) 0x19, 0x01, // USAGE_MINIMUM (Khóa số) 0x29, 0x05, // USAGE_MAXIMUM (Kana) 0x91, 0x02, // OUTPUT (Dữ liệu,Var,Abs) 0x95, 0x01, // REPORT_COUNT (1) 0x75, 0x03, / /REPORT_SIZE (3) 0x91, 0x03, // OUTPUT (Cnst,Var,Abs) 0x95, 0x06, // REPORT_COUNT (6) 0x75, 0x08, // REPORT_SIZE (8) 0x15, 0x00, // LOGICAL_MINIMUM (0) 0x25, 0x65, // LOGICAL_MAXIMUM (101) 0x05, 0x07, // USAGE_PAGE (Bàn phím) 0x19, 0x00, // USAGE_MINIMUM (Dành riêng (không có sự kiện nào được chỉ định)) 0x29, 0x65, // USAGE_MAXIMUM (Ứng dụng bàn phím) 0x81, 0x00, // INPUT (Dữ liệu, Ary, Abs) 0xc0, // END_COLLECTION }; /*Sửa đổi kích thước mô tả thiết bị báo cáo trong usbd_hid.h*/ #define HID_MOUSE_REPORT_DESC_SIZE 63U
Sau khi sửa đổi bộ mô tả thiết bị báo cáo và kết nối với máy tính, máy tính sẽ nhận dạng nó là thiết bị bàn phím. Khi máy tính giao tiếp với thiết bị USB, máy tính sẽ thực hiện phân tích dữ liệu theo gói giao thức HID của thiết bị bàn phím. bốn nút trên bảng phát triển Để mô phỏng bốn phím a/x/y/z trên bàn phím, hãy triển khai chương trình trực tiếp trong tệp main.c. Mã nguồn cụ thể như sau.
/*Đặt giá trị tọa độ con trỏ chuột*/ static void GetPointerData(uint8_t *pbuf) { int8_t keyboard = 0; /*Nút WK_UP được nhấn*/ if(HAL_GPIO_ReadPin(WK_UP_GPIO_Port,WK_UP_Pin) == GPIO_PIN_SET) { if(HAL_GPIO_ReadPin(WK_UP_GPIO_Port,WK_UP_Pin) == GPIO_PIN_SET) { printf("WK_UP Đã nhấn: a/A\r\n"); bàn phím = 0x04; while(HAL_GPIO_ReadPin(WK_UP_GPIO_Port,WK_UP_Pin)); } } /*Key2 là đã nhấn Nhấn*/ if(HAL_GPIO_ReadPin(KEY2_GPIO_Port,KEY2_Pin) == GPIO_PIN_RESET) { if(HAL_GPIO_ReadPin(KEY2_GPIO_Port,KEY2_Pin) == GPIO_PIN_RESET) { printf("KEY2 Đã nhấn: x/X\r\n"); bàn phím = 0x1B; while(!HAL_GPIO_ReadPin(KEY2_GPIO_Port,KEY2_Pin)); } } /*Nút KEY1 được nhấn*/ if(HAL_GPIO_ReadPin(KEY1_GPIO_Port,KEY1_Pin) == GPIO_PIN_RESET) { if(HAL_GPIO_ReadPin(KEY1_GPIO_Port,KEY1_Pin) == GPIO_PIN_RESET) { printf("KEY1 Đã nhấn : y/Y\r\n"); bàn phím = 0x1C; while(!HAL_GPIO_ReadPin(KEY1_GPIO_Port,KEY1_Pin)); } } /*Phím KEY0 được nhấn*/ if(HAL_GPIO_ReadPin(KEY0_GPIO_Port , KEY0_Pin) == GPIO_PIN_RESET) { if(HAL_GPIO_ReadPin(KEY0_GPIO_Port,KEY0_Pin) == GPIO_PIN_RESET) { printf("KEY0 Đã nhấn: z/Z\r\n"); bàn phím = 0x1D; while(!HAL_GPIO_ReadPin(KEY0_GPIO_Port,KEY0_Pin)); //Tổng hợp gói dữ liệu bàn phím for(uint8_t i=0;i<8;i++) { if(i == 2) pbuf[i] = keyboard; else pbuf[i] = 0; } } /*Bộ đếm thời gian TIM6 1ms Gọi lại hàm */ void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) { static __IO uint32_t counter = 0; /* kiểm tra trạng thái Cần điều khiển trong mỗi khoảng thời gian thăm dò (10ms) */ if(counter++ == USBD_HID_GetPollingInterval(&hUsbDeviceFS)) { GetPointerData(HID_Buffer); /* gửi dữ liệu qua điểm cuối IN*/ USBD_HID_SendReport(&hUsbDeviceFS, HID_Buffer, sizeof(HID_Buffer)); /* Đặt lại bộ đếm */ bộ đếm = 0; } }
5.3. Xác minh đốt cháy
Để ghi chương trình, hãy sử dụng cáp USB để kết nối giao diện USB_SALVE trên bo mạch phát triển với giao diện USB trên máy tính Windows. Sau khi kết nối thành công, bạn có thể giám sát hoạt động của hệ thống thông qua trợ lý cổng nối tiếp.
Đầu tiên, chúng ta có thể tìm kiếm thiết bị thông qua trình quản lý thiết bị để xem Windwos nhận dạng thiết bị đó là thiết bị nào. Mở trình quản lý thiết bị, tìm thiết bị cuối cùng trên bàn phím, nhấp chuột phải để xem thuộc tính của thiết bị và tìm thiết bị gốc trong thuộc tính của. trang chi tiết, bên dưới Bạn có thể xem VID và PID của thiết bị và thấy rằng chúng nhất quán với ID trong mô tả thiết bị HID mà chúng tôi đã định cấu hình, như minh họa trong hình bên dưới.
Sau đó mở trợ lý cổng nối tiếp, nhấp chuột vào vùng dữ liệu gửi của trợ lý cổng nối tiếp, sau đó nhấn ngẫu nhiên bốn nút người dùng trên bảng phát triển. Bạn có thể tìm thấy mỗi nút trong trợ lý cổng nối tiếp. nhấn sẽ xuất ra bốn ký tự a, x, y., z, đồng thời, cổng nối tiếp sẽ xuất ra dấu nhắc cho biết nút nào đã được nhấn. Hiện tượng cụ thể như trong hình bên dưới.
6. Các chức năng thường dùng
/*trả về khoảng thời gian thăm dò từ bộ mô tả điểm cuối*/ uint32_t USBD_HID_GetPollingInterval(USBD_HandleTypeDef *pdev) /*Gửi báo cáo HID*/ uint8_t USBD_HID_SendReport(USBD_HandleTypeDef *pdev, uint8_t *report, uint16_t len)
7. Giải thích chi tiết chú thích
Lưu ý 1: Nguồn hình ảnh 3, ví dụ mô tả bàn phím giao diện USB.
Lưu ý 2: Bộ mô tả thiết bị báo cáo của bàn phím xuất phát từ ghi chú nghiên cứu STM32CubeMX (44) - Cách sử dụng giao diện USB (nút HID).
Tài liệu tham khảo
Lớp học Weixue: STM32CubeMX Series Hướng dẫn 25: Thiết bị USB.
Cuối cùng, bài viết này về Hướng dẫn STM32CubeMX 31USB_DEVICE-HID Peripheral_Simulation Bàn phím hoặc Chuột kết thúc tại đây. Nếu bạn muốn biết thêm về Hướng dẫn STM32CubeMX 31USB_DEVICE-HID Peripheral_Simulator Bàn phím hoặc Chuột, vui lòng tìm kiếm bài viết CFSDN. ủng hộ blog của tôi trong tương lai! .
Tôi là một lập trình viên xuất sắc, rất giỏi!