From dc87fbc7dadac68111e296a9574a34e4fc7959e6 Mon Sep 17 00:00:00 2001 From: Robofish <1683502971@qq.com> Date: Wed, 24 Sep 2025 19:54:25 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8Ddr16?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- assets/User_code/device/dr16.c | 112 +++++++++++++++++++++++++++------ assets/User_code/device/dr16.h | 63 ++++++++++++++++++- 2 files changed, 153 insertions(+), 22 deletions(-) diff --git a/assets/User_code/device/dr16.c b/assets/User_code/device/dr16.c index d2a1c8d..929e4b5 100644 --- a/assets/User_code/device/dr16.c +++ b/assets/User_code/device/dr16.c @@ -1,14 +1,27 @@ /* DR16接收机 + Example: + + DR16_Init(&dr16); + + while (1) { + DR16_StartDmaRecv(&dr16); + if (DR16_WaitDmaCplt(20)) { + DR16_ParseData(&dr16); + } else { + DR16_Offline(&dr16); + } +} */ /* Includes ----------------------------------------------------------------- */ #include "dr16.h" - -#include - #include "bsp/uart.h" #include "bsp/time.h" +#include "device.h" + +#include +#include /* USER INCLUDE BEGIN */ @@ -37,27 +50,27 @@ static void DR16_RxCpltCallback(void) { static bool DR16_DataCorrupted(const DR16_t *dr16) { if (dr16 == NULL) return DEVICE_ERR_NULL; - if ((dr16->data.ch_r_x < DR16_CH_VALUE_MIN) || - (dr16->data.ch_r_x > DR16_CH_VALUE_MAX)) - return true; + if ((dr16->raw_data.ch_r_x < DR16_CH_VALUE_MIN) || + (dr16->raw_data.ch_r_x > DR16_CH_VALUE_MAX)) + return DEVICE_ERR; - if ((dr16->data.ch_r_y < DR16_CH_VALUE_MIN) || - (dr16->data.ch_r_y > DR16_CH_VALUE_MAX)) - return true; + if ((dr16->raw_data.ch_r_y < DR16_CH_VALUE_MIN) || + (dr16->raw_data.ch_r_y > DR16_CH_VALUE_MAX)) + return DEVICE_ERR; - if ((dr16->data.ch_l_x < DR16_CH_VALUE_MIN) || - (dr16->data.ch_l_x > DR16_CH_VALUE_MAX)) - return true; + if ((dr16->raw_data.ch_l_x < DR16_CH_VALUE_MIN) || + (dr16->raw_data.ch_l_x > DR16_CH_VALUE_MAX)) + return DEVICE_ERR; - if ((dr16->data.ch_l_y < DR16_CH_VALUE_MIN) || - (dr16->data.ch_l_y > DR16_CH_VALUE_MAX)) - return true; + if ((dr16->raw_data.ch_l_y < DR16_CH_VALUE_MIN) || + (dr16->raw_data.ch_l_y > DR16_CH_VALUE_MAX)) + return DEVICE_ERR; - if (dr16->data.sw_l == 0) return true; + if (dr16->raw_data.sw_l == 0) return DEVICE_ERR; - if (dr16->data.sw_r == 0) return true; + if (dr16->raw_data.sw_r == 0) return DEVICE_ERR; - return false; + return DEVICE_OK; } /* Exported functions ------------------------------------------------------- */ @@ -81,8 +94,8 @@ int8_t DR16_Restart(void) { int8_t DR16_StartDmaRecv(DR16_t *dr16) { if (HAL_UART_Receive_DMA(BSP_UART_GetHandle(BSP_UART_DR16), - (uint8_t *)&(dr16->data), - sizeof(dr16->data)) == HAL_OK) + (uint8_t *)&(dr16->raw_data), + sizeof(dr16->raw_data)) == HAL_OK) return DEVICE_OK; return DEVICE_ERR; } @@ -92,6 +105,65 @@ bool DR16_WaitDmaCplt(uint32_t timeout) { SIGNAL_DR16_RAW_REDY); } +int8_t DR16_ParseData(DR16_t *dr16){ + if (dr16 == NULL) return DEVICE_ERR_NULL; + + if (DR16_DataCorrupted(dr16)) { + return DEVICE_ERR; + } + + dr16->header.online = true; + dr16->header.last_online_time = BSP_TIME_Get_us(); + + memset(&(dr16->data), 0, sizeof(dr16->data)); + + float full_range = (float)(DR16_CH_VALUE_MAX - DR16_CH_VALUE_MIN); + + // 解析摇杆数据 + dr16->data.ch_r_x = 2.0f * ((float)dr16->raw_data.ch_r_x - DR16_CH_VALUE_MID) / full_range; + dr16->data.ch_r_y = 2.0f * ((float)dr16->raw_data.ch_r_y - DR16_CH_VALUE_MID) / full_range; + dr16->data.ch_l_x = 2.0f * ((float)dr16->raw_data.ch_l_x - DR16_CH_VALUE_MID) / full_range; + dr16->data.ch_l_y = 2.0f * ((float)dr16->raw_data.ch_l_y - DR16_CH_VALUE_MID) / full_range; + + // 解析拨杆位置 + dr16->data.sw_l = (DR16_SwitchPos_t)dr16->raw_data.sw_l; + dr16->data.sw_r = (DR16_SwitchPos_t)dr16->raw_data.sw_r; + + // 解析鼠标数据 + dr16->data.mouse.x = dr16->raw_data.x; + dr16->data.mouse.y = dr16->raw_data.y; + dr16->data.mouse.z = dr16->raw_data.z; + + dr16->data.mouse.l_click = dr16->raw_data.press_l; + dr16->data.mouse.r_click = dr16->raw_data.press_r; + + // 解析键盘按键 - 使用union简化代码 + uint16_t key_value = dr16->raw_data.key; + + // 解析键盘位映射(W-B键,位0-15) + for (int i = CMD_KEY_W; i <= CMD_KEY_B; i++) { + dr16->data.keyboard.key[i] = (key_value & (1 << i)) != 0; + } + + // 解析鼠标点击 + dr16->data.keyboard.key[CMD_L_CLICK] = dr16->data.mouse.l_click; + dr16->data.keyboard.key[CMD_R_CLICK] = dr16->data.mouse.r_click; + + // 解析第五通道 + dr16->data.ch_res = 2.0f * ((float)dr16->raw_data.res - DR16_CH_VALUE_MID) / full_range; + + return DEVICE_OK; +} + +int8_t DR16_Offline(DR16_t *dr16){ + if (dr16 == NULL) return DEVICE_ERR_NULL; + + dr16->header.online = false; + memset(&(dr16->data), 0, sizeof(dr16->data)); + + return DEVICE_OK; +} + /* USER FUNCTION BEGIN */ /* USER FUNCTION END */ diff --git a/assets/User_code/device/dr16.h b/assets/User_code/device/dr16.h index da21ebf..6e40c94 100644 --- a/assets/User_code/device/dr16.h +++ b/assets/User_code/device/dr16.h @@ -8,7 +8,7 @@ extern "C" { #include #include "component/user_math.h" -#include "device/device.h" +#include "device.h" /* USER INCLUDE BEGIN */ @@ -35,19 +35,78 @@ typedef struct __packed { uint8_t press_r; uint16_t key; uint16_t res; +} DR16_RawData_t; + +typedef enum { + CMD_SW_ERR = 0, + CMD_SW_UP = 1, + CMD_SW_MID = 3, + CMD_SW_DOWN = 2, +} DR16_SwitchPos_t; + +/* 键盘按键值 */ +typedef enum { + CMD_KEY_W = 0, + CMD_KEY_S, + CMD_KEY_A, + CMD_KEY_D, + CMD_KEY_SHIFT, + CMD_KEY_CTRL, + CMD_KEY_Q, + CMD_KEY_E, + CMD_KEY_R, + CMD_KEY_F, + CMD_KEY_G, + CMD_KEY_Z, + CMD_KEY_X, + CMD_KEY_C, + CMD_KEY_V, + CMD_KEY_B, + CMD_L_CLICK, + CMD_R_CLICK, + CMD_KEY_NUM, +} DR16_Key_t; + +typedef struct { + float ch_l_x; /* 遥控器左侧摇杆横轴值,上为正 */ + float ch_l_y; /* 遥控器左侧摇杆纵轴值,右为正 */ + float ch_r_x; /* 遥控器右侧摇杆横轴值,上为正 */ + float ch_r_y; /* 遥控器右侧摇杆纵轴值,右为正 */ + + float ch_res; /* 第五通道值 */ + + DR16_SwitchPos_t sw_r; /* 右侧拨杆位置 */ + DR16_SwitchPos_t sw_l; /* 左侧拨杆位置 */ + + struct { + int16_t x; + int16_t y; + int16_t z; + bool l_click; /* 左键 */ + bool r_click; /* 右键 */ + } mouse; /* 鼠标值 */ + + union { + bool key[CMD_KEY_NUM]; /* 键盘按键值 */ + uint16_t value; /* 键盘按键值的位映射 */ + } keyboard; + + uint16_t res; /* 保留,未启用 */ } DR16_Data_t; typedef struct { DEVICE_Header_t header; + DR16_RawData_t raw_data; DR16_Data_t data; } DR16_t; /* Exported functions prototypes -------------------------------------------- */ int8_t DR16_Init(DR16_t *dr16); int8_t DR16_Restart(void); - int8_t DR16_StartDmaRecv(DR16_t *dr16); bool DR16_WaitDmaCplt(uint32_t timeout); +int8_t DR16_ParseData(DR16_t *dr16); +int8_t DR16_Offline(DR16_t *dr16); /* USER FUNCTION BEGIN */