#ifndef _CAN_H #define _CAN_H #include #ifdef __cplusplus extern "C" { #endif #include #include "gd32c10x_can.h" #include "config.h" // 定义一个联合体类型用于 float 和 byte 数组之间的转换 typedef union { float f; u8 b[4]; } float_union_t; // 添加辅助函数用于将 u16 类型数据打包到 u8 数组中 static inline void pack_u16_to_bytes(u8 *buffer, u16 offset, u16 value) { buffer[offset] = (u8)(value & 0xFF); buffer[offset + 1] = (u8)((value >> 8) & 0xFF); } // 添加辅助函数用于将 float 类型数据打包到 u8 数组中 static inline void pack_float_to_bytes(u8 *buffer, u16 offset, float_union_t &float_union) { buffer[offset] = float_union.b[0]; buffer[offset + 1] = float_union.b[1]; buffer[offset + 2] = float_union.b[2]; buffer[offset + 3] = float_union.b[3]; } // 添加辅助函数用于从 u8 数组中解包 short 类型数据 static inline short unpack_bytes_to_short(u8 *buffer, u16 offset) { short value = (short)(buffer[offset] | (buffer[offset + 1] << 8)); return value; } // 添加辅助函数用于从 u8 数组中解包 u16 类型数据 static inline u16 unpack_bytes_to_u16(u8 *buffer, u16 offset) { u16 value = (u16)(buffer[offset] | (buffer[offset + 1] << 8)); return value; } // 添加辅助函数用于从 u8 数组中解包 float 类型数据 static inline float_union_t unpack_bytes_to_float(u8 *buffer, u16 offset) { float_union_t float_union; float_union.b[0] = buffer[offset]; float_union.b[1] = buffer[offset + 1]; float_union.b[2] = buffer[offset + 2]; float_union.b[3] = buffer[offset + 3]; return float_union; } u8 can_gpio_init(void); // CAN 引脚初始化 void can_config(void); // CAN 初始化 void canfd_config(void); // CANFD 初始化 void can_dma_init(void); // CAN DMA 初始化 void CAN0_TX_IRQHandler(void); // CAN 发送中断处理函数 void CAN0_RX0_IRQHandler(void); // CAN 接收中断处理函数 void DMA0_Channel4_IRQHandler(void); // DMA 通道 4 中断处理函数 (CAN 接收) void DMA0_Channel5_IRQHandler(void); // DMA 通道 5 中断处理函数 (CAN 发送) void jumpToBOOT(); void can_loopback_init(void); void can_loopback_test(void); /*! \brief CAN 通信类 \note 封装 CAN 发送和接收功能,支持多电机节点 ID 隔离 */ class CAN_transmiter { private: static const uint8_t CAN_RX_BUFFER_SIZE = 8; // CAN 接收缓冲区大小 static const u32 CAN_SILENT_DURATION_MS = 10000; // CAN 静默时长 10 秒 bool is_sleep = false; // 是否休眠 bool is_silent = false; // 是否静默(收到 base_id=0x0000 后进入静默) u32 silent_start_time = 0; // 静默开始时间(ms) u16 node_id; // 本节点 ID(0-254),使用 CAN ID 高 8 位存储 (在 init() 中初始化为 DEFAULT_NODE_ID) u8 Target_Control_Mode = 0; // 目标控制模式 u8 controller_Mode = 0; // 当前模式 short mcu_temp = 0; // MCU 温度 short motor_temp = 0; // 电机温度 u16 Power_Voltage = 0; // 电源电压 u16 limit_voltage = 0; // 限制电压 u8 cpu_usage = 0; // CPU 使用率(%) float_union_t rt_angle_union = {0}; // 实时角度 float_union_t rt_velocity_union = {0}; // 实时速度 float_union_t rt_current_union = {0}; // 实时电流 float_union_t target_angle_union = {0}; // 目标角度 float_union_t target_velocity_union = {0}; // 目标速度 float_union_t target_current_union = {0}; // 目标电流 float_union_t u_current_union = {0}; // U 相电流 float_union_t w_current_union = {0}; // W 相电流 float_union_t v_current_union = {0}; // V 相电流 bool MotorStatus = 0; // 电机状态码 u8 EEPROMStatus = 0; // EEPROM 状态码 can_trasnmit_message_struct transmit_message; // 发送消息结构体 u8 transmit_mailbox = CAN_NOMAILBOX; // 初始化为无 mailbox 状态 u8 transmit_data[64]; // CANFD 最大 64 字节 // CAN 接收消息队列 can_receive_message_struct rx_message_buffer[CAN_RX_BUFFER_SIZE]; volatile uint8_t rx_buffer_head = 0; volatile uint8_t rx_buffer_tail = 0; void update(); // 更新数据 u8 CAN_Receive(); // CAN 接收 u8 CANFD_Receive(); // CANFD 接收 bool is_rx_buffer_full(); bool is_rx_buffer_empty(); bool dequeue_rx_message(can_receive_message_struct& message); void check_silent_mode(); // 检查静默模式是否结束 public: // 节点 ID 相关辅助函数 (使用高 16 位存储节点 ID) u32 build_can_id(u32 base_id); // 根据节点 ID 构建 CAN ID,格式:[节点 ID(16 位)][基础 ID(16 位)] bool is_message_for_me(u32 received_id); // 判断消息是否发给本节点 public: // 添加构造函数声明 u8 init(void); can_receive_message_struct receive_message; // 接收消息结构体 FlagStatus can0_send_flag; // CAN0 发送标志 float_union_t testfloat_union = {0}; // 测试用 u16 test_u16 = 0; bool MagStatus = 0; // 磁状态码 bool ThermalStatus = 0; // 热能状态码 void communication_check(); // 通信检查 u8 CAN_Sleep(); // CAN 进入睡眠 u8 CAN_Wakeup(); // CAN 唤醒 u8 CAN_AsyncSend(u32 ID, u8 length, u8 *data); // CAN 异步发送 (使用 DMA) u8 CANFD_AsyncSend(u32 ID, u8 length, u8 *data); // CANFD 异步发送 (使用 DMA) u8 CAN_all_Send(); // CAN 发送 u8 CANFD_all_Send(); // CANFD 发送 void enter_silent_mode(); // 进入静默模式(停发 10 秒) bool is_in_silent_mode(); // 检查是否在静默模式中 // 节点 ID 管理接口 u16 get_node_id(); // 获取当前节点 ID void set_node_id(u16 new_id); // 设置节点 ID u8 load_node_id_from_flash(); // 从 Flash 加载节点 ID u8 save_node_id_to_flash(u16 new_id); // 保存节点 ID 到 Flash // 中断处理函数需要访问的公共接口 void enqueue_rx_message_from_isr(const can_receive_message_struct& message) { if (!is_rx_buffer_full()) { rx_message_buffer[rx_buffer_head] = message; rx_buffer_head = (rx_buffer_head + 1) % CAN_RX_BUFFER_SIZE; } // 如果缓冲区满,丢弃新消息 } }; #ifdef __cplusplus } #endif #endif