添加can遥控器

This commit is contained in:
Robofish 2025-09-30 21:01:58 +08:00
parent 4da08b6e4b
commit 821fa5a03d
8 changed files with 398 additions and 715 deletions

View File

@ -70,6 +70,7 @@ target_sources(${CMAKE_PROJECT_NAME} PRIVATE
User/device/motor.c User/device/motor.c
User/device/motor_rm.c User/device/motor_rm.c
User/device/motor_dm.c User/device/motor_dm.c
User/device/rc_can.c
# User/module sources # User/module sources
User/module/config.c User/module/config.c

View File

@ -1,515 +1,312 @@
/* Includes ----------------------------------------------------------------- */ /* Includes ----------------------------------------------------------------- */
#include "rc_can.h" #include "device/rc_can.h"
#include "bsp/time.h" #include "bsp/time.h"
#include "device/device.h"
/* USER INCLUDE BEGIN */ /* USER INCLUDE BEGIN */
/* USER INCLUDE END */ /* USER INCLUDE END */
/* Private define ----------------------------------------------------------- */ /* Private constants -------------------------------------------------------- */
#define RC_CAN_SCALE_FACTOR 1000.0f // 将[-1.0, 1.0]转换为[-1000, 1000]
#define RC_CAN_DATA_JOYSTICK 0
#define RC_CAN_DATA_SWITCH 1
#define RC_CAN_DATA_MOUSE 2
#define RC_CAN_DATA_KEYBOARD 3
#define RC_CAN_DATA_STATUS 4
/* USER DEFINE BEGIN */ /* USER DEFINE BEGIN */
/* USER DEFINE END */ /* USER DEFINE END */
/* Private macro ------------------------------------------------------------ */ /* Private macro ------------------------------------------------------------ */
/* Private typedef ---------------------------------------------------------- */ /* Private types ------------------------------------------------------------ */
/* Private variables -------------------------------------------------------- */ /* Private variables -------------------------------------------------------- */
/* Private function -------------------------------------------------------- */ /* USER VARIABLE BEGIN */
/** /* USER VARIABLE END */
* @brief
* @param value [-1.0, 1.0]
* @return [-1000, 1000]
*/
static int16_t RC_CAN_ScaleFloat(float value) {
if (value > 1.0f) value = 1.0f;
if (value < -1.0f) value = -1.0f;
return (int16_t)(value * RC_CAN_SCALE_FACTOR);
}
/**
* @brief
* @param rc_can RC_CAN结构体指针
* @param dr16 DR16数据结构体指针
*/
static void RC_CAN_UpdateJoystickData(RC_CAN_t *rc_can, const DR16_t *dr16) {
rc_can->joystick_data.ch_l_x = RC_CAN_ScaleFloat(dr16->data.ch_l_x);
rc_can->joystick_data.ch_l_y = RC_CAN_ScaleFloat(dr16->data.ch_l_y);
rc_can->joystick_data.ch_r_x = RC_CAN_ScaleFloat(dr16->data.ch_r_x);
rc_can->joystick_data.ch_r_y = RC_CAN_ScaleFloat(dr16->data.ch_r_y);
}
/**
* @brief
* @param rc_can RC_CAN结构体指针
* @param dr16 DR16数据结构体指针
*/
static void RC_CAN_UpdateSwitchData(RC_CAN_t *rc_can, const DR16_t *dr16) {
rc_can->switch_data.sw_l = (uint8_t)dr16->data.sw_l;
rc_can->switch_data.sw_r = (uint8_t)dr16->data.sw_r;
rc_can->switch_data.ch_res = RC_CAN_ScaleFloat(dr16->data.ch_res);
rc_can->switch_data.reserved = 0;
}
/**
* @brief
* @param rc_can RC_CAN结构体指针
* @param dr16 DR16数据结构体指针
*/
static void RC_CAN_UpdateMouseData(RC_CAN_t *rc_can, const DR16_t *dr16) {
rc_can->mouse_data.mouse_x = dr16->data.mouse.x;
rc_can->mouse_data.mouse_y = dr16->data.mouse.y;
rc_can->mouse_data.mouse_z = dr16->data.mouse.z;
rc_can->mouse_data.mouse_l = dr16->data.mouse.l_click ? 1 : 0;
rc_can->mouse_data.mouse_r = dr16->data.mouse.r_click ? 1 : 0;
}
/**
* @brief
* @param rc_can RC_CAN结构体指针
* @param dr16 DR16数据结构体指针
*/
static void RC_CAN_UpdateKeyboardData(RC_CAN_t *rc_can, const DR16_t *dr16) {
rc_can->keyboard_data.key_value = dr16->data.keyboard.value;
memset(rc_can->keyboard_data.reserved, 0, sizeof(rc_can->keyboard_data.reserved));
}
/**
* @brief
* @param rc_can RC_CAN结构体指针
* @param dr16 DR16数据结构体指针
*/
static void RC_CAN_UpdateStatusData(RC_CAN_t *rc_can, const DR16_t *dr16) {
rc_can->status_data.online = dr16->header.online ? 1 : 0;
rc_can->status_data.data_valid = 1; // 假设数据有效
rc_can->status_data.timestamp = (uint32_t)(BSP_TIME_Get() / 1000); // 转换为ms
rc_can->status_data.reserved = 0;
}
/**
* @brief
* @param value [-1000, 1000]
* @return [-1.0, 1.0]
*/
static float RC_CAN_UnscaleInt(int16_t value) {
float result = (float)value / RC_CAN_SCALE_FACTOR;
if (result > 1.0f) result = 1.0f;
if (result < -1.0f) result = -1.0f;
return result;
}
/**
* @brief CAN消息
* @param rc_can RC_CAN结构体指针
* @param msg CAN消息指针
*/
static void RC_CAN_ProcessRxMessage(RC_CAN_t *rc_can, BSP_CAN_Message_t *msg) {
uint32_t current_time = (uint32_t)(BSP_TIME_Get() / 1000); // 转换为ms
switch (msg->parsed_id) {
case RC_CAN_DR16_JOYSTICK_ID:
if (msg->dlc >= sizeof(RC_CAN_JoystickData_t)) {
memcpy(&rc_can->joystick_data, msg->data, sizeof(RC_CAN_JoystickData_t));
rc_can->rx_status.joystick_updated = true;
rc_can->rx_status.last_joystick_time = current_time;
}
break;
case RC_CAN_DR16_SWITCH_ID:
if (msg->dlc >= sizeof(RC_CAN_SwitchData_t)) {
memcpy(&rc_can->switch_data, msg->data, sizeof(RC_CAN_SwitchData_t));
rc_can->rx_status.switch_updated = true;
rc_can->rx_status.last_switch_time = current_time;
}
break;
case RC_CAN_DR16_MOUSE_ID:
if (msg->dlc >= sizeof(RC_CAN_MouseData_t)) {
memcpy(&rc_can->mouse_data, msg->data, sizeof(RC_CAN_MouseData_t));
rc_can->rx_status.mouse_updated = true;
rc_can->rx_status.last_mouse_time = current_time;
}
break;
case RC_CAN_DR16_KEYBOARD_ID:
if (msg->dlc >= sizeof(RC_CAN_KeyboardData_t)) {
memcpy(&rc_can->keyboard_data, msg->data, sizeof(RC_CAN_KeyboardData_t));
rc_can->rx_status.keyboard_updated = true;
rc_can->rx_status.last_keyboard_time = current_time;
}
break;
case RC_CAN_DR16_STATUS_ID:
if (msg->dlc >= sizeof(RC_CAN_StatusData_t)) {
memcpy(&rc_can->status_data, msg->data, sizeof(RC_CAN_StatusData_t));
rc_can->rx_status.status_updated = true;
rc_can->rx_status.last_status_time = current_time;
// 更新整体在线状态
rc_can->header.online = (rc_can->status_data.online == 1);
rc_can->header.last_online_time = BSP_TIME_Get();
}
break;
default:
// 未知ID忽略
break;
}
}
/* USER FUNCTION BEGIN */ /* USER FUNCTION BEGIN */
/* USER FUNCTION END */ /* USER FUNCTION END */
/* Private function prototypes ---------------------------------------------- */
static int8_t RC_CAN_ValidateParams(const RC_CAN_Param_t *param);
static int8_t RC_CAN_RegisterIds(RC_CAN_t *rc_can);
/* Exported functions ------------------------------------------------------- */ /* Exported functions ------------------------------------------------------- */
/**
* @brief RC CAN发送模块
* @param rc_can RC_CAN结构体指针
* @param param
* @return DEVICE_OK
*/
int8_t RC_CAN_Init(RC_CAN_t *rc_can, RC_CAN_Param_t *param) { int8_t RC_CAN_Init(RC_CAN_t *rc_can, RC_CAN_Param_t *param) {
if (rc_can == NULL || param == NULL) { if (rc_can == NULL || param == NULL) {
return DEVICE_ERR_NULL; return DEVICE_ERR_NULL;
} }
if (rc_can->initialized) { // 参数验证
return DEVICE_ERR_INITED; if (RC_CAN_ValidateParams(param) != DEVICE_OK) {
return DEVICE_ERR;
} }
// 复制参数 rc_can->param = *param;
memcpy(&rc_can->param, param, sizeof(RC_CAN_Param_t));
// 初始化头部信息 // 初始化header
rc_can->header.online = false; rc_can->header.online = false;
rc_can->header.last_online_time = 0; rc_can->header.last_online_time = 0;
// 清零数据包 // 手动初始化数据结构
memset(&rc_can->joystick_data, 0, sizeof(RC_CAN_JoystickData_t)); rc_can->data.joy.ch_l_x = 0.0f;
memset(&rc_can->switch_data, 0, sizeof(RC_CAN_SwitchData_t)); rc_can->data.joy.ch_l_y = 0.0f;
memset(&rc_can->mouse_data, 0, sizeof(RC_CAN_MouseData_t)); rc_can->data.joy.ch_r_x = 0.0f;
memset(&rc_can->keyboard_data, 0, sizeof(RC_CAN_KeyboardData_t)); rc_can->data.joy.ch_r_y = 0.0f;
memset(&rc_can->status_data, 0, sizeof(RC_CAN_StatusData_t)); rc_can->data.sw.sw_l = RC_CAN_SW_ERR;
rc_can->data.sw.sw_r = RC_CAN_SW_ERR;
// 初始化接收状态 rc_can->data.sw.ch_res = 0.0f;
memset(&rc_can->rx_status, 0, sizeof(RC_CAN_RxStatus_t)); rc_can->data.mouse.x = 0.0f;
rc_can->data.mouse.y = 0.0f;
// 如果是接收模式注册CAN ID rc_can->data.mouse.z = 0.0f;
if (param->mode == RC_CAN_MODE_RECEIVER || param->mode == RC_CAN_MODE_BOTH) { rc_can->data.mouse.mouse_l = false;
BSP_CAN_RegisterId(param->can, RC_CAN_DR16_JOYSTICK_ID, 0); rc_can->data.mouse.mouse_r = false;
BSP_CAN_RegisterId(param->can, RC_CAN_DR16_SWITCH_ID, 0); rc_can->data.keyboard.key_value = 0;
BSP_CAN_RegisterId(param->can, RC_CAN_DR16_MOUSE_ID, 0); for (int i = 0; i < 6; i++) {
BSP_CAN_RegisterId(param->can, RC_CAN_DR16_KEYBOARD_ID, 0); rc_can->data.keyboard.keys[i] = RC_CAN_KEY_NONE;
BSP_CAN_RegisterId(param->can, RC_CAN_DR16_STATUS_ID, 0);
} }
// 初始化状态 // 注册CAN ID队列从机模式需要接收数据
rc_can->last_send_time = 0; if (rc_can->param.mode == RC_CAN_MODE_SLAVE) {
rc_can->initialized = true; return RC_CAN_RegisterIds(rc_can);
}
return DEVICE_OK; return DEVICE_OK;
} }
int8_t RC_CAN_SendData(RC_CAN_t *rc_can, const void *dr16_ptr) { /**
if (rc_can == NULL || dr16_ptr == NULL) { * @brief CAN总线
* @param rc_can RC_CAN结构体指针
* @param data_type
* @return DEVICE_OK
*/
int8_t RC_CAN_SendData(RC_CAN_t *rc_can, RC_CAN_DataType_t data_type) {
if (rc_can == NULL) {
return DEVICE_ERR_NULL; return DEVICE_ERR_NULL;
} }
if (rc_can->param.mode != RC_CAN_MODE_MASTER) {
const DR16_t *dr16 = (const DR16_t *)dr16_ptr;
if (!rc_can->initialized) {
return DEVICE_ERR; return DEVICE_ERR;
} }
BSP_CAN_StdDataFrame_t frame;
if (!rc_can->param.enabled) { frame.dlc = 8;
return DEVICE_OK; // 未启用时直接返回成功 switch (data_type) {
case RC_CAN_DATA_JOYSTICK:
frame.id = rc_can->param.joy_id;
frame.data[0] = (uint8_t)((int16_t)(rc_can->data.joy.ch_l_x * 32768.0f) & 0xFF);
frame.data[1] =
(uint8_t)(((int16_t)(rc_can->data.joy.ch_l_x * 32768.0f) >> 8) & 0xFF);
frame.data[2] = (uint8_t)((int16_t)(rc_can->data.joy.ch_l_y * 32768.0f) & 0xFF);
frame.data[3] =
(uint8_t)(((int16_t)(rc_can->data.joy.ch_l_y * 32768.0f) >> 8) & 0xFF);
frame.data[4] = (uint8_t)((int16_t)(rc_can->data.joy.ch_r_x * 32768.0f) & 0xFF);
frame.data[5] =
(uint8_t)(((int16_t)(rc_can->data.joy.ch_r_x * 32768.0f) >> 8) & 0xFF);
frame.data[6] = (uint8_t)((int16_t)(rc_can->data.joy.ch_r_y * 32768.0f) & 0xFF);
frame.data[7] =
(uint8_t)(((int16_t)(rc_can->data.joy.ch_r_y * 32768.0f) >> 8) & 0xFF);
break;
case RC_CAN_DATA_SWITCH:
frame.id = rc_can->param.sw_id;
frame.data[0] = (uint8_t)(rc_can->data.sw.sw_l);
frame.data[1] = (uint8_t)(rc_can->data.sw.sw_r);
frame.data[2] = (uint8_t)((int16_t)(rc_can->data.sw.ch_res * 32768.0f) & 0xFF);
frame.data[3] =
(uint8_t)(((int16_t)(rc_can->data.sw.ch_res * 32768.0f) >> 8) & 0xFF);
frame.data[4] = 0; // 保留字节
frame.data[5] = 0; // 保留字节
frame.data[6] = 0; // 保留字节
frame.data[7] = 0; // 保留字节
break;
case RC_CAN_DATA_MOUSE:
frame.id = rc_can->param.mouse_id;
frame.data[0] = (uint8_t)((int16_t)(rc_can->data.mouse.x) & 0xFF);
frame.data[1] = (uint8_t)(((int16_t)(rc_can->data.mouse.x) >> 8) & 0xFF);
frame.data[2] = (uint8_t)((int16_t)(rc_can->data.mouse.y) & 0xFF);
frame.data[3] = (uint8_t)(((int16_t)(rc_can->data.mouse.y) >> 8) & 0xFF);
frame.data[4] = (uint8_t)((int16_t)(rc_can->data.mouse.z) & 0xFF);
frame.data[5] = (uint8_t)(((int16_t)(rc_can->data.mouse.z) >> 8) & 0xFF);
frame.data[6] = (uint8_t)(rc_can->data.mouse.mouse_l ? 1 : 0);
frame.data[7] = (uint8_t)(rc_can->data.mouse.mouse_r ? 1 : 0);
break;
case RC_CAN_DATA_KEYBOARD:
frame.id = rc_can->param.keyboard_id;
frame.data[0] = (uint8_t)(rc_can->data.keyboard.key_value & 0xFF);
frame.data[1] = (uint8_t)((rc_can->data.keyboard.key_value >> 8) & 0xFF);
for (int i = 0; i < 6; i++) {
frame.data[2 + i] = (i < 6) ? (uint8_t)(rc_can->data.keyboard.keys[i]) : 0;
} }
break;
uint64_t current_time = BSP_TIME_Get() / 1000; // 转换为ms default:
return DEVICE_ERR;
// 检查发送周期 }
if (current_time - rc_can->last_send_time < rc_can->param.send_period) { if (BSP_CAN_Transmit(rc_can->param.can, BSP_CAN_FORMAT_STD_DATA, frame.id,
return DEVICE_OK; // 未到发送时间 frame.data, frame.dlc) != BSP_OK) {
}
// 更新所有数据包
RC_CAN_UpdateJoystickData(rc_can, dr16);
RC_CAN_UpdateSwitchData(rc_can, dr16);
RC_CAN_UpdateMouseData(rc_can, dr16);
RC_CAN_UpdateKeyboardData(rc_can, dr16);
RC_CAN_UpdateStatusData(rc_can, dr16);
int8_t result = DEVICE_OK;
// 发送所有数据包
if (RC_CAN_SendJoystickData(rc_can) != DEVICE_OK) result = DEVICE_ERR;
if (RC_CAN_SendSwitchData(rc_can) != DEVICE_OK) result = DEVICE_ERR;
if (RC_CAN_SendMouseData(rc_can) != DEVICE_OK) result = DEVICE_ERR;
if (RC_CAN_SendKeyboardData(rc_can) != DEVICE_OK) result = DEVICE_ERR;
if (RC_CAN_SendStatusData(rc_can) != DEVICE_OK) result = DEVICE_ERR;
// 更新发送时间和在线状态
rc_can->last_send_time = (uint32_t)current_time;
rc_can->header.online = true;
rc_can->header.last_online_time = BSP_TIME_Get();
return result;
}
int8_t RC_CAN_SendJoystickData(RC_CAN_t *rc_can) {
if (rc_can == NULL) {
return DEVICE_ERR_NULL;
}
BSP_CAN_StdDataFrame_t tx_frame;
tx_frame.id = RC_CAN_DR16_JOYSTICK_ID;
tx_frame.dlc = sizeof(RC_CAN_JoystickData_t);
memcpy(tx_frame.data, &rc_can->joystick_data, sizeof(RC_CAN_JoystickData_t));
return BSP_CAN_TransmitStdDataFrame(rc_can->param.can, &tx_frame) == BSP_OK ?
DEVICE_OK : DEVICE_ERR;
}
int8_t RC_CAN_SendSwitchData(RC_CAN_t *rc_can) {
if (rc_can == NULL) {
return DEVICE_ERR_NULL;
}
BSP_CAN_StdDataFrame_t tx_frame;
tx_frame.id = RC_CAN_DR16_SWITCH_ID;
tx_frame.dlc = sizeof(RC_CAN_SwitchData_t);
memcpy(tx_frame.data, &rc_can->switch_data, sizeof(RC_CAN_SwitchData_t));
return BSP_CAN_TransmitStdDataFrame(rc_can->param.can, &tx_frame) == BSP_OK ?
DEVICE_OK : DEVICE_ERR;
}
int8_t RC_CAN_SendMouseData(RC_CAN_t *rc_can) {
if (rc_can == NULL) {
return DEVICE_ERR_NULL;
}
BSP_CAN_StdDataFrame_t tx_frame;
tx_frame.id = RC_CAN_DR16_MOUSE_ID;
tx_frame.dlc = sizeof(RC_CAN_MouseData_t);
memcpy(tx_frame.data, &rc_can->mouse_data, sizeof(RC_CAN_MouseData_t));
return BSP_CAN_TransmitStdDataFrame(rc_can->param.can, &tx_frame) == BSP_OK ?
DEVICE_OK : DEVICE_ERR;
}
int8_t RC_CAN_SendKeyboardData(RC_CAN_t *rc_can) {
if (rc_can == NULL) {
return DEVICE_ERR_NULL;
}
BSP_CAN_StdDataFrame_t tx_frame;
tx_frame.id = RC_CAN_DR16_KEYBOARD_ID;
tx_frame.dlc = sizeof(RC_CAN_KeyboardData_t);
memcpy(tx_frame.data, &rc_can->keyboard_data, sizeof(RC_CAN_KeyboardData_t));
return BSP_CAN_TransmitStdDataFrame(rc_can->param.can, &tx_frame) == BSP_OK ?
DEVICE_OK : DEVICE_ERR;
}
int8_t RC_CAN_SendStatusData(RC_CAN_t *rc_can) {
if (rc_can == NULL) {
return DEVICE_ERR_NULL;
}
BSP_CAN_StdDataFrame_t tx_frame;
tx_frame.id = RC_CAN_DR16_STATUS_ID;
tx_frame.dlc = sizeof(RC_CAN_StatusData_t);
memcpy(tx_frame.data, &rc_can->status_data, sizeof(RC_CAN_StatusData_t));
return BSP_CAN_TransmitStdDataFrame(rc_can->param.can, &tx_frame) == BSP_OK ?
DEVICE_OK : DEVICE_ERR;
}
int8_t RC_CAN_SetEnabled(RC_CAN_t *rc_can, bool enabled) {
if (rc_can == NULL) {
return DEVICE_ERR_NULL;
}
rc_can->param.enabled = enabled;
return DEVICE_OK;
}
bool RC_CAN_IsOnline(const RC_CAN_t *rc_can) {
if (rc_can == NULL) {
return false;
}
return rc_can->header.online;
}
int8_t RC_CAN_Update(RC_CAN_t *rc_can) {
if (rc_can == NULL) {
return DEVICE_ERR_NULL;
}
if (!rc_can->initialized) {
return DEVICE_ERR; return DEVICE_ERR;
} }
// 只在接收模式下处理接收
if (rc_can->param.mode != RC_CAN_MODE_RECEIVER && rc_can->param.mode != RC_CAN_MODE_BOTH) {
return DEVICE_OK; return DEVICE_OK;
}
BSP_CAN_Message_t rx_msg;
int8_t result = DEVICE_OK;
// 处理所有可能的接收ID
uint32_t can_ids[] = {
RC_CAN_DR16_JOYSTICK_ID,
RC_CAN_DR16_SWITCH_ID,
RC_CAN_DR16_MOUSE_ID,
RC_CAN_DR16_KEYBOARD_ID,
RC_CAN_DR16_STATUS_ID
};
for (int i = 0; i < 5; i++) {
while (BSP_CAN_GetMessage(rc_can->param.can, can_ids[i], &rx_msg, BSP_CAN_TIMEOUT_IMMEDIATE) == BSP_OK) {
RC_CAN_ProcessRxMessage(rc_can, &rx_msg);
}
}
return result;
} }
int8_t RC_CAN_GetJoystickData(const RC_CAN_t *rc_can, float *ch_l_x, float *ch_l_y, /**
float *ch_r_x, float *ch_r_y) { * @brief CAN数据
if (rc_can == NULL || ch_l_x == NULL || ch_l_y == NULL || * @param rc_can RC_CAN结构体指针
ch_r_x == NULL || ch_r_y == NULL) { * @param data_type
* @return DEVICE_OK
*/
int8_t RC_CAN_Update(RC_CAN_t *rc_can, RC_CAN_DataType_t data_type) {
if (rc_can == NULL) {
return DEVICE_ERR_NULL; return DEVICE_ERR_NULL;
} }
*ch_l_x = RC_CAN_UnscaleInt(rc_can->joystick_data.ch_l_x); // 只有从机模式才能接收数据
*ch_l_y = RC_CAN_UnscaleInt(rc_can->joystick_data.ch_l_y); if (rc_can->param.mode != RC_CAN_MODE_SLAVE) {
*ch_r_x = RC_CAN_UnscaleInt(rc_can->joystick_data.ch_r_x); return DEVICE_ERR;
*ch_r_y = RC_CAN_UnscaleInt(rc_can->joystick_data.ch_r_y);
return DEVICE_OK;
}
int8_t RC_CAN_GetSwitchData(const RC_CAN_t *rc_can, uint8_t *sw_l, uint8_t *sw_r,
float *ch_res) {
if (rc_can == NULL || sw_l == NULL || sw_r == NULL || ch_res == NULL) {
return DEVICE_ERR_NULL;
} }
BSP_CAN_Message_t msg;
*sw_l = rc_can->switch_data.sw_l;
*sw_r = rc_can->switch_data.sw_r;
*ch_res = RC_CAN_UnscaleInt(rc_can->switch_data.ch_res);
return DEVICE_OK;
}
int8_t RC_CAN_GetMouseData(const RC_CAN_t *rc_can, int16_t *mouse_x, int16_t *mouse_y,
int16_t *mouse_z, bool *mouse_l, bool *mouse_r) {
if (rc_can == NULL || mouse_x == NULL || mouse_y == NULL ||
mouse_z == NULL || mouse_l == NULL || mouse_r == NULL) {
return DEVICE_ERR_NULL;
}
*mouse_x = rc_can->mouse_data.mouse_x;
*mouse_y = rc_can->mouse_data.mouse_y;
*mouse_z = rc_can->mouse_data.mouse_z;
*mouse_l = (rc_can->mouse_data.mouse_l != 0);
*mouse_r = (rc_can->mouse_data.mouse_r != 0);
return DEVICE_OK;
}
int8_t RC_CAN_GetKeyboardData(const RC_CAN_t *rc_can, uint16_t *key_value) {
if (rc_can == NULL || key_value == NULL) {
return DEVICE_ERR_NULL;
}
*key_value = rc_can->keyboard_data.key_value;
return DEVICE_OK;
}
int8_t RC_CAN_GetRemoteStatus(const RC_CAN_t *rc_can, bool *remote_online,
bool *data_valid, uint32_t *timestamp) {
if (rc_can == NULL || remote_online == NULL ||
data_valid == NULL || timestamp == NULL) {
return DEVICE_ERR_NULL;
}
*remote_online = (rc_can->status_data.online != 0);
*data_valid = (rc_can->status_data.data_valid != 0);
*timestamp = rc_can->status_data.timestamp;
return DEVICE_OK;
}
bool RC_CAN_IsDataUpdated(RC_CAN_t *rc_can, uint8_t data_type) {
if (rc_can == NULL || data_type > RC_CAN_DATA_STATUS) {
return false;
}
bool updated = false;
switch (data_type) { switch (data_type) {
case RC_CAN_DATA_JOYSTICK: case RC_CAN_DATA_JOYSTICK:
updated = rc_can->rx_status.joystick_updated; if (BSP_CAN_GetMessage(rc_can->param.can, rc_can->param.joy_id, &msg,
rc_can->rx_status.joystick_updated = false; // 清除更新标志 BSP_CAN_TIMEOUT_IMMEDIATE) != BSP_OK) {
return DEVICE_ERR;
}
// 解包数据
int16_t ch_l_x = (int16_t)((msg.data[1] << 8) | msg.data[0]);
int16_t ch_l_y = (int16_t)((msg.data[3] << 8) | msg.data[2]);
int16_t ch_r_x = (int16_t)((msg.data[5] << 8) | msg.data[4]);
int16_t ch_r_y = (int16_t)((msg.data[7] << 8) | msg.data[6]);
// 转换为浮点数(范围:-1.0到1.0
rc_can->data.joy.ch_l_x = (float)ch_l_x / 32768.0f;
rc_can->data.joy.ch_l_y = (float)ch_l_y / 32768.0f;
rc_can->data.joy.ch_r_x = (float)ch_r_x / 32768.0f;
rc_can->data.joy.ch_r_y = (float)ch_r_y / 32768.0f;
break; break;
case RC_CAN_DATA_SWITCH: case RC_CAN_DATA_SWITCH:
updated = rc_can->rx_status.switch_updated; if (BSP_CAN_GetMessage(rc_can->param.can, rc_can->param.sw_id, &msg,
rc_can->rx_status.switch_updated = false; BSP_CAN_TIMEOUT_IMMEDIATE) != BSP_OK) {
return DEVICE_ERR;
}
// 解包数据
rc_can->data.sw.sw_l = (RC_CAN_SW_t)msg.data[0];
rc_can->data.sw.sw_r = (RC_CAN_SW_t)msg.data[1];
int16_t ch_res = (int16_t)((msg.data[3] << 8) | msg.data[2]);
rc_can->data.sw.ch_res = (float)ch_res / 32768.0f;
break; break;
case RC_CAN_DATA_MOUSE: case RC_CAN_DATA_MOUSE:
updated = rc_can->rx_status.mouse_updated; if (BSP_CAN_GetMessage(rc_can->param.can, rc_can->param.mouse_id, &msg,
rc_can->rx_status.mouse_updated = false; BSP_CAN_TIMEOUT_IMMEDIATE) != BSP_OK) {
return DEVICE_ERR;
}
// 解包数据
int16_t x = (int16_t)((msg.data[1] << 8) | msg.data[0]);
int16_t y = (int16_t)((msg.data[3] << 8) | msg.data[2]);
int16_t z = (int16_t)((msg.data[5] << 8) | msg.data[4]);
rc_can->data.mouse.x = (float)x;
rc_can->data.mouse.y = (float)y;
rc_can->data.mouse.z = (float)z;
rc_can->data.mouse.mouse_l = (msg.data[6] & 0x01) ? true : false;
rc_can->data.mouse.mouse_r = (msg.data[7] & 0x01) ? true : false;
break; break;
case RC_CAN_DATA_KEYBOARD: case RC_CAN_DATA_KEYBOARD:
updated = rc_can->rx_status.keyboard_updated; if (BSP_CAN_GetMessage(rc_can->param.can, rc_can->param.keyboard_id, &msg,
rc_can->rx_status.keyboard_updated = false; BSP_CAN_TIMEOUT_IMMEDIATE) != BSP_OK) {
break; return DEVICE_ERR;
case RC_CAN_DATA_STATUS: }
updated = rc_can->rx_status.status_updated; if (msg.dlc < 2) {
rc_can->rx_status.status_updated = false; return DEVICE_ERR;
}
// 解包数据
rc_can->data.keyboard.key_value =
(uint16_t)((msg.data[1] << 8) | msg.data[0]);
for (int i = 0; i < 6 && (i + 2) < msg.dlc; i++) {
rc_can->data.keyboard.keys[i] = (RC_CAN_Key_t)(msg.data[2 + i]);
}
// 清空未使用的按键位置
for (int i = (msg.dlc > 2 ? msg.dlc - 2 : 0); i < 6; i++) {
rc_can->data.keyboard.keys[i] = RC_CAN_KEY_NONE;
}
break; break;
default: default:
updated = false; return DEVICE_ERR;
break;
} }
return updated; // 更新header状态
rc_can->header.online = true;
rc_can->header.last_online_time = BSP_TIME_Get_us();
return DEVICE_OK;
} }
bool RC_CAN_IsDataTimeout(const RC_CAN_t *rc_can) { /* Private functions -------------------------------------------------------- */
/**
* @brief RC_CAN参数
* @param param
* @return DEVICE_OK
*/
static int8_t RC_CAN_ValidateParams(const RC_CAN_Param_t *param) {
if (param == NULL) {
return DEVICE_ERR_NULL;
}
// 检查CAN总线有效性
if (param->can >= BSP_CAN_NUM) {
return DEVICE_ERR;
}
// 检查工作模式有效性
if (param->mode != RC_CAN_MODE_MASTER && param->mode != RC_CAN_MODE_SLAVE) {
return DEVICE_ERR;
}
// 检查CAN ID是否重复
if (param->joy_id == param->sw_id || param->joy_id == param->mouse_id ||
param->joy_id == param->keyboard_id || param->sw_id == param->mouse_id ||
param->sw_id == param->keyboard_id ||
param->mouse_id == param->keyboard_id) {
return DEVICE_ERR;
}
return DEVICE_OK;
}
/**
* @brief CAN ID
* @param rc_can RC_CAN结构体指针
* @return DEVICE_OK
*/
static int8_t RC_CAN_RegisterIds(RC_CAN_t *rc_can) {
if (BSP_CAN_RegisterId(rc_can->param.can, rc_can->param.joy_id, 0) !=
BSP_OK) {
return DEVICE_ERR;
}
if (BSP_CAN_RegisterId(rc_can->param.can, rc_can->param.sw_id, 0) != BSP_OK) {
return DEVICE_ERR;
}
if (BSP_CAN_RegisterId(rc_can->param.can, rc_can->param.mouse_id, 0) !=
BSP_OK) {
return DEVICE_ERR;
}
if (BSP_CAN_RegisterId(rc_can->param.can, rc_can->param.keyboard_id, 0) !=
BSP_OK) {
return DEVICE_ERR;
}
return DEVICE_OK;
}
int8_t RC_CAN_OFFLINE(RC_CAN_t *rc_can){
if (rc_can == NULL) { if (rc_can == NULL) {
return true; return DEVICE_ERR_NULL;
} }
rc_can->header.online = false;
uint32_t current_time = (uint32_t)(BSP_TIME_Get() / 1000); // 转换为ms return DEVICE_OK;
uint32_t timeout_ms = rc_can->param.timeout_ms;
// 检查所有数据类型是否超时
bool timeout = false;
if (current_time - rc_can->rx_status.last_joystick_time > timeout_ms) timeout = true;
if (current_time - rc_can->rx_status.last_switch_time > timeout_ms) timeout = true;
if (current_time - rc_can->rx_status.last_mouse_time > timeout_ms) timeout = true;
if (current_time - rc_can->rx_status.last_keyboard_time > timeout_ms) timeout = true;
if (current_time - rc_can->rx_status.last_status_time > timeout_ms) timeout = true;
return timeout;
} }
/* USER CODE BEGIN */
/* USER FUNCTION BEGIN */ /* USER CODE END */
/* USER FUNCTION END */

View File

@ -19,11 +19,6 @@ extern "C" {
/* USER DEFINE END */ /* USER DEFINE END */
/* Exported constants ------------------------------------------------------- */ /* Exported constants ------------------------------------------------------- */
#define RC_CAN_DR16_JOY_ID 0x350 // 遥杆数据
#define RC_CAN_DR16_SWITCH_ID 0x351 // 拨杆数据
#define RC_CAN_DR16_MOUSE_ID 0x352 // 鼠标数据
#define RC_CAN_DR16_KEYBOARD_ID 0x353 // 键盘数据
#define RC_CAN_DR16_STATUS_ID 0x354 // 状态数据
/* Exported macro ----------------------------------------------------------- */ /* Exported macro ----------------------------------------------------------- */
/* Exported types ----------------------------------------------------------- */ /* Exported types ----------------------------------------------------------- */
@ -35,110 +30,91 @@ typedef enum {
} RC_CAN_SW_t; } RC_CAN_SW_t;
typedef enum { typedef enum {
DR16_KEY_W = 0, RC_CAN_MODE_MASTER = 0, // 主机模式
DR16_KEY_S, RC_CAN_MODE_SLAVE = 1, // 从机模式
DR16_KEY_A, } RC_CAN_Mode_t;
DR16_KEY_D,
DR16_KEY_SHIFT, typedef enum {
DR16_KEY_CTRL, RC_CAN_DATA_JOYSTICK = 0,
DR16_KEY_Q, RC_CAN_DATA_SWITCH,
DR16_KEY_E, RC_CAN_DATA_MOUSE,
DR16_KEY_R, RC_CAN_DATA_KEYBOARD
DR16_KEY_F, } RC_CAN_DataType_t;
DR16_KEY_G,
DR16_KEY_Z, typedef enum {
DR16_KEY_X, RC_CAN_KEY_NONE = 0xFF, // 无按键
DR16_KEY_C, RC_CAN_KEY_W = 0,
DR16_KEY_V, RC_CAN_KEY_S,
DR16_KEY_B, RC_CAN_KEY_A,
DR16_KEY_NUM, RC_CAN_KEY_D,
} DR16_Key_t; RC_CAN_KEY_SHIFT,
// 遥杆数据包 (CAN ID: 0x300) RC_CAN_KEY_CTRL,
RC_CAN_KEY_Q,
RC_CAN_KEY_E,
RC_CAN_KEY_R,
RC_CAN_KEY_F,
RC_CAN_KEY_G,
RC_CAN_KEY_Z,
RC_CAN_KEY_X,
RC_CAN_KEY_C,
RC_CAN_KEY_V,
RC_CAN_KEY_B,
RC_CAN_KEY_NUM,
} RC_CAN_Key_t;
// 遥杆数据包
typedef struct { typedef struct {
int16_t ch_l_x; float ch_l_x;
int16_t ch_l_y; float ch_l_y;
int16_t ch_r_x; float ch_r_x;
int16_t ch_r_y; float ch_r_y;
} RC_CAN_JoyData_t; } RC_CAN_JoyData_t;
// 拨杆数据包 (CAN ID: 0x301) // 拨杆数据包
typedef struct __packed { typedef struct {
RC_CAN_SW_t sw_l; // 左拨杆状态 RC_CAN_SW_t sw_l; // 左拨杆状态
RC_CAN_SW_t sw_r; // 右拨杆状态 RC_CAN_SW_t sw_r; // 右拨杆状态
int16_t ch_res; // 第五通道 (-1000~1000) float ch_res; // 第五通道
} RC_CAN_SwitchData_t; } RC_CAN_SwitchData_t;
// 鼠标数据包 (CAN ID: 0x302) // 鼠标数据包
typedef struct __packed { typedef struct {
int16_t mouse_x; // 鼠标X轴移动 float x; // 鼠标X轴移动
int16_t mouse_y; // 鼠标Y轴移动 float y; // 鼠标Y轴移动
int16_t mouse_z; // 鼠标Z轴(滚轮) float z; // 鼠标Z轴(滚轮)
bool mouse_l; // 鼠标左键 bool mouse_l; // 鼠标左键
bool mouse_r; // 鼠标右键 bool mouse_r; // 鼠标右键
} RC_CAN_MouseData_t; } RC_CAN_MouseData_t;
// 键盘数据包 (CAN ID: 0x303) // 键盘数据包
typedef union { typedef struct {
uint16_t key_value; // 键盘按键位映射 uint16_t key_value; // 键盘按键位映射
DR16_Key_t keys[16]; // 按键数组 RC_CAN_Key_t keys[16];
} RC_CAN_KeyboardData_t; } RC_CAN_KeyboardData_t;
// 状态数据包 (CAN ID: 0x304)
typedef struct __packed {
uint8_t online; // 在线状态 (1:在线, 0:离线)
uint8_t data_valid; // 数据有效性 (1:有效, 0:无效)
uint32_t timestamp; // 时间戳(ms)
uint16_t reserved; // 保留字节
} RC_CAN_StatusData_t;
// 工作模式枚举
typedef enum {
RC_CAN_MODE_SENDER, // 发送模式连接DR16的板子
RC_CAN_MODE_RECEIVER, // 接收模式(其他板子)
RC_CAN_MODE_BOTH // 双向模式(可发送也可接收)
} RC_CAN_Mode_t;
// 接收数据状态
typedef struct { typedef struct {
bool joystick_updated; RC_CAN_JoyData_t joy;
bool switch_updated; RC_CAN_SwitchData_t sw;
bool mouse_updated; RC_CAN_MouseData_t mouse;
bool keyboard_updated; RC_CAN_KeyboardData_t keyboard;
bool status_updated; } RC_CAN_Data_t;
uint32_t last_joystick_time;
uint32_t last_switch_time;
uint32_t last_mouse_time;
uint32_t last_keyboard_time;
uint32_t last_status_time;
} RC_CAN_RxStatus_t;
// RC_CAN 参数结构 // RC_CAN 参数结构
typedef struct { typedef struct {
BSP_CAN_t can; // 使用的CAN总线 BSP_CAN_t can; // 使用的CAN总线
RC_CAN_Mode_t mode; // 工作模式 RC_CAN_Mode_t mode; // 工作模式
bool enabled; // 是否启用发送(仅发送模式有效) uint16_t joy_id; // 遥杆CAN ID
uint32_t send_period; // 发送周期(ms) uint16_t sw_id; // 拨杆CAN ID
uint32_t timeout_ms; // 接收超时时间(ms) uint16_t mouse_id; // 鼠标CAN ID
uint16_t keyboard_id; // 键盘CAN ID
} RC_CAN_Param_t; } RC_CAN_Param_t;
// RC_CAN 主结构 // RC_CAN 主结构
typedef struct { typedef struct {
RC_CAN_Param_t param;
DEVICE_Header_t header; DEVICE_Header_t header;
RC_CAN_Param_t param;
// 数据包 RC_CAN_Data_t data;
RC_CAN_JoystickData_t joystick_data;
RC_CAN_SwitchData_t switch_data;
RC_CAN_MouseData_t mouse_data;
RC_CAN_KeyboardData_t keyboard_data;
RC_CAN_StatusData_t status_data;
// 接收状态(仅接收模式有效)
RC_CAN_RxStatus_t rx_status;
// 状态信息
uint32_t last_send_time;
bool initialized;
} RC_CAN_t; } RC_CAN_t;
/* USER STRUCT BEGIN */ /* USER STRUCT BEGIN */
@ -156,140 +132,22 @@ typedef struct {
int8_t RC_CAN_Init(RC_CAN_t *rc_can, RC_CAN_Param_t *param); int8_t RC_CAN_Init(RC_CAN_t *rc_can, RC_CAN_Param_t *param);
/** /**
* @brief DR16数据到CAN总线 * @brief CAN总线
* @param rc_can RC_CAN结构体指针 * @param rc_can RC_CAN结构体指针
* @param dr16 DR16数据结构体指针 * @param data_type
* @return DEVICE_OK * @return DEVICE_OK
*/ */
int8_t RC_CAN_SendData(RC_CAN_t *rc_can, const void *dr16); int8_t RC_CAN_SendData(RC_CAN_t *rc_can, RC_CAN_DataType_t data_type);
/**
* @brief
* @param rc_can RC_CAN结构体指针
* @return DEVICE_OK
*/
int8_t RC_CAN_SendJoystickData(RC_CAN_t *rc_can);
/**
* @brief
* @param rc_can RC_CAN结构体指针
* @return DEVICE_OK
*/
int8_t RC_CAN_SendSwitchData(RC_CAN_t *rc_can);
/**
* @brief
* @param rc_can RC_CAN结构体指针
* @return DEVICE_OK
*/
int8_t RC_CAN_SendMouseData(RC_CAN_t *rc_can);
/**
* @brief
* @param rc_can RC_CAN结构体指针
* @return DEVICE_OK
*/
int8_t RC_CAN_SendKeyboardData(RC_CAN_t *rc_can);
/**
* @brief
* @param rc_can RC_CAN结构体指针
* @return DEVICE_OK
*/
int8_t RC_CAN_SendStatusData(RC_CAN_t *rc_can);
/**
* @brief 使
* @param rc_can RC_CAN结构体指针
* @param enabled 使
* @return DEVICE_OK
*/
int8_t RC_CAN_SetEnabled(RC_CAN_t *rc_can, bool enabled);
/**
* @brief 线
* @param rc_can RC_CAN结构体指针
* @return true 线false 线
*/
bool RC_CAN_IsOnline(const RC_CAN_t *rc_can);
/** /**
* @brief CAN数据 * @brief CAN数据
* @param rc_can RC_CAN结构体指针 * @param rc_can RC_CAN结构体指针
* @param data_type
* @return DEVICE_OK * @return DEVICE_OK
*/ */
int8_t RC_CAN_Update(RC_CAN_t *rc_can); int8_t RC_CAN_Update(RC_CAN_t *rc_can , RC_CAN_DataType_t data_type);
/**
* @brief
* @param rc_can RC_CAN结构体指针
* @param ch_l_x X轴输出指针
* @param ch_l_y Y轴输出指针
* @param ch_r_x X轴输出指针
* @param ch_r_y Y轴输出指针
* @return DEVICE_OK
*/
int8_t RC_CAN_GetJoystickData(const RC_CAN_t *rc_can, float *ch_l_x, float *ch_l_y,
float *ch_r_x, float *ch_r_y);
/**
* @brief
* @param rc_can RC_CAN结构体指针
* @param sw_l
* @param sw_r
* @param ch_res
* @return DEVICE_OK
*/
int8_t RC_CAN_GetSwitchData(const RC_CAN_t *rc_can, uint8_t *sw_l, uint8_t *sw_r,
float *ch_res);
/**
* @brief
* @param rc_can RC_CAN结构体指针
* @param mouse_x X轴输出指针
* @param mouse_y Y轴输出指针
* @param mouse_z Z轴输出指针
* @param mouse_l
* @param mouse_r
* @return DEVICE_OK
*/
int8_t RC_CAN_GetMouseData(const RC_CAN_t *rc_can, int16_t *mouse_x, int16_t *mouse_y,
int16_t *mouse_z, bool *mouse_l, bool *mouse_r);
/**
* @brief
* @param rc_can RC_CAN结构体指针
* @param key_value
* @return DEVICE_OK
*/
int8_t RC_CAN_GetKeyboardData(const RC_CAN_t *rc_can, uint16_t *key_value);
/**
* @brief DR16状态
* @param rc_can RC_CAN结构体指针
* @param remote_online DR16在线状态输出指针
* @param data_valid
* @param timestamp
* @return DEVICE_OK
*/
int8_t RC_CAN_GetRemoteStatus(const RC_CAN_t *rc_can, bool *remote_online,
bool *data_valid, uint32_t *timestamp);
/**
* @brief
* @param rc_can RC_CAN结构体指针
* @param data_type (0:, 1:, 2:, 3:, 4:)
* @return true false
*/
bool RC_CAN_IsDataUpdated(RC_CAN_t *rc_can, uint8_t data_type);
/**
* @brief
* @param rc_can RC_CAN结构体指针
* @return true false
*/
bool RC_CAN_IsDataTimeout(const RC_CAN_t *rc_can);
int8_t RC_CAN_OFFLINE(RC_CAN_t *rc_can);
/* USER FUNCTION BEGIN */ /* USER FUNCTION BEGIN */
/* USER FUNCTION END */ /* USER FUNCTION END */

View File

@ -8,6 +8,7 @@
#include "device/motor_rm.h" #include "device/motor_rm.h"
#include "component/pid.h" #include "component/pid.h"
#include "component/user_math.h" #include "component/user_math.h"
#include "device/rc_can.h"
/* Private typedef ---------------------------------------------------------- */ /* Private typedef ---------------------------------------------------------- */
/* Private define ----------------------------------------------------------- */ /* Private define ----------------------------------------------------------- */
@ -79,7 +80,17 @@ Config_RobotParam_t robot_config = {
.in = 30.0f, .in = 30.0f,
.out = 30.0f, .out = 30.0f,
}, },
}
},
.rc_can_param = {
.can = BSP_CAN_1,
.mode = RC_CAN_MODE_MASTER,
.joy_id = 0x250,
.sw_id = 0x251,
.mouse_id = 0x252,
.keyboard_id = 0x253,
},
}; };
/* Private function prototypes ---------------------------------------------- */ /* Private function prototypes ---------------------------------------------- */

View File

@ -11,10 +11,11 @@ extern "C" {
#include <stdint.h> #include <stdint.h>
#include "module/shoot.h" #include "module/shoot.h"
#include "module/gimbal.h" #include "module/gimbal.h"
#include "device/rc_can.h"
typedef struct { typedef struct {
Shoot_Params_t shoot_param; Shoot_Params_t shoot_param;
RC_CAN_Param_t rc_can_param;
// Shoot_Params_t shoot_param; /* 射击参数 */ // Shoot_Params_t shoot_param; /* 射击参数 */
} Config_RobotParam_t; } Config_RobotParam_t;

View File

@ -116,7 +116,7 @@ int8_t Shoot_Control(Shoot_t *c, const Shoot_CMD_t *cmd)
for(int i=0;i<SHOOT_FRIC_NUM;i++) for(int i=0;i<SHOOT_FRIC_NUM;i++)
{ /* 计算跟随输出->计算修正输出->加和、滤波、输出 */ { /* 计算跟随输出->计算修正输出->加和、滤波、输出 */
// c->output.out_follow[i]=PID_Calc(&c->pid.fric_follow[i],c->target_variable.target_rpm/MAX_FRIC_RPM,c->feedback.fric_rpm[i],0,c->dt); // c->output.out_follow[i]=PID_Calc(&c->pid.fric_follow[i],c->target_variable.target_rpm/MAX_FRIC_RPM,c->feedback.fric_rpm[i],0,c->dt);
c->output.out_follow[i]=PID_Calc(&c->pid.fric_follow[i],3000.0f/MAX_FRIC_RPM,c->feedback.fric_rpm[i],0,c->dt); c->output.out_follow[i]=PID_Calc(&c->pid.fric_follow[i],300.0f/MAX_FRIC_RPM,c->feedback.fric_rpm[i],0,c->dt);
c->output.out_err[i]=PID_Calc(&c->pid.fric_err[i],c->feedback.fric_avgrpm,c->feedback.fric_rpm[i],0,c->dt); c->output.out_err[i]=PID_Calc(&c->pid.fric_err[i],c->feedback.fric_avgrpm,c->feedback.fric_rpm[i],0,c->dt);
ScaleSumTo1(&c->output.out_follow[i], &c->output.out_err[i]); ScaleSumTo1(&c->output.out_follow[i], &c->output.out_err[i]);

View File

@ -8,8 +8,11 @@
#include "task/user_task.h" #include "task/user_task.h"
/* USER INCLUDE BEGIN */ /* USER INCLUDE BEGIN */
#include "device/dr16.h" #include "device/dr16.h"
#include "device/rc_can.h"
#include "module/config.h"
#include "module/shoot.h" #include "module/shoot.h"
#include <stdbool.h> #include <stdbool.h>
// #include
/* USER INCLUDE END */ /* USER INCLUDE END */
/* Private typedef ---------------------------------------------------------- */ /* Private typedef ---------------------------------------------------------- */
@ -18,6 +21,7 @@
/* Private variables -------------------------------------------------------- */ /* Private variables -------------------------------------------------------- */
/* USER STRUCT BEGIN */ /* USER STRUCT BEGIN */
DR16_t dr16; DR16_t dr16;
RC_CAN_t rc_can;
Shoot_CMD_t for_shoot; Shoot_CMD_t for_shoot;
/* USER STRUCT END */ /* USER STRUCT END */
@ -26,11 +30,11 @@ Shoot_CMD_t for_shoot;
void Task_rc(void *argument) { void Task_rc(void *argument) {
(void)argument; /* 未使用argument消除警告 */ (void)argument; /* 未使用argument消除警告 */
osDelay(RC_INIT_DELAY); /* 延时一段时间再开启任务 */ osDelay(RC_INIT_DELAY); /* 延时一段时间再开启任务 */
/* USER CODE INIT BEGIN */ /* USER CODE INIT BEGIN */
DR16_Init(&dr16); DR16_Init(&dr16);
RC_CAN_Init(&rc_can, &Config_GetRobotParam()->rc_can_param);
/* USER CODE INIT END */ /* USER CODE INIT END */
while (1) { while (1) {
@ -38,6 +42,7 @@ void Task_rc(void *argument) {
DR16_StartDmaRecv(&dr16); DR16_StartDmaRecv(&dr16);
if (DR16_WaitDmaCplt(20)) { if (DR16_WaitDmaCplt(20)) {
DR16_ParseData(&dr16); DR16_ParseData(&dr16);
} else { } else {
DR16_Offline(&dr16); DR16_Offline(&dr16);
} }
@ -60,9 +65,18 @@ void Task_rc(void *argument) {
for_shoot.firecmd = false; for_shoot.firecmd = false;
break; break;
} }
rc_can.data.joy.ch_l_x = dr16.data.ch_l_x;
rc_can.data.joy.ch_l_y = dr16.data.ch_l_y;
rc_can.data.joy.ch_r_x = dr16.data.ch_r_x;
rc_can.data.joy.ch_r_y = dr16.data.ch_r_y;
rc_can.data.sw.sw_l = (RC_CAN_SW_t)dr16.data.sw_l;
rc_can.data.sw.sw_r = (RC_CAN_SW_t)dr16.data.sw_r;
rc_can.data.sw.ch_res = dr16.data.res;
RC_CAN_SendData(&rc_can, RC_CAN_DATA_JOYSTICK);
RC_CAN_SendData(&rc_can, RC_CAN_DATA_SWITCH);
osMessageQueueReset(task_runtime.msgq.shoot.shoot_cmd); osMessageQueueReset(task_runtime.msgq.shoot.shoot_cmd);
osMessageQueuePut(task_runtime.msgq.shoot.shoot_cmd, &for_shoot, 0, 0); osMessageQueuePut(task_runtime.msgq.shoot.shoot_cmd, &for_shoot, 0, 0);
/* USER CODE END */ /* USER CODE END */
} }
} }

View File

@ -32,6 +32,7 @@ void OnProjectLoad (void) {
// //
// User settings // User settings
// //
Edit.SysVar (VAR_HSS_SPEED, max);
File.Open ("$(ProjectDir)/build/Debug/DevC.elf"); File.Open ("$(ProjectDir)/build/Debug/DevC.elf");
} }