#include "../2025_include_user/Stepmotor.h" uint8_t StepMotor::_buffer = 0; StepMotor::Data StepMotor::_data = {}; static uint8_t frame_index = 0; static uint8_t frame_buffer[9]; extern "C" void Stepmotor_INST_IRQHandler(void) { switch (DL_UART_getPendingInterrupt(Stepmotor_INST)) { case DL_UART_IIDX_RX: StepMotor::_buffer = DL_UART_Main_receiveData(Stepmotor_INST); StepMotor::inject(); break; default: break; } NVIC_ClearPendingIRQ(Stepmotor_INST_INT_IRQN); DL_UART_enableInterrupt(Stepmotor_INST, DL_UART_INTERRUPT_RX); // 启用接收中断 } void StepMotor::init() { NVIC_ClearPendingIRQ(Stepmotor_INST_INT_IRQN); NVIC_EnableIRQ(Stepmotor_INST_INT_IRQN); DL_UART_enable(Stepmotor_INST); // 启用 UART 模块 DL_UART_enableInterrupt(Stepmotor_INST, DL_UART_INTERRUPT_RX); // 启用接收中断 } void StepMotor::inject() { frame_buffer[frame_index++] = _buffer; if (frame_index >= 9) { // 校验BCC uint8_t bcc = 0; for (int i = 0; i < 8; i++) { bcc ^= frame_buffer[i]; } if (bcc == frame_buffer[8]) { // BCC校验通过,解析数据存储到ttl_data _data.address = frame_buffer[0]; _data.flag = frame_buffer[1]; _data.speed = (frame_buffer[2] << 8) | frame_buffer[3]; uint32_t position_raw = (frame_buffer[4] << 24) | (frame_buffer[5] << 16) | (frame_buffer[6] << 8) | frame_buffer[7]; // 位置数据处理为有符号值(高位为符号位) if (position_raw & 0x80000000) { _data.position = (int32_t)(position_raw | 0xFFFFFFFF00000000); } else { _data.position = (int32_t)position_raw; } _data.bcc = frame_buffer[8]; } // 无论校验是否通过,都重置frame_index,准备接收下一帧 frame_index = 0; } } void StepMotor::transmit_command(const uint8_t *cmd) { for (uint8_t i = 0; i < FRAME_LENGTH; i++) { DL_UART_Main_transmitDataBlocking(Stepmotor_INST, cmd[i]); } } // 通用编码函数 void StepMotor::encode_frame(const StepMotor::ControlMode mode, const uint8_t direction, const uint8_t subdivide, const float angle_deg, const uint16_t torque_mA, const float absolute_angle_deg, const float speed_rad_s, uint8_t *frame_buffer) { uint16_t angle_or_current = 0; uint16_t speed = (uint16_t) (speed_rad_s * 10); // 转速 *10 放大 frame_buffer[0] = 0x7B; // 帧头 frame_buffer[1] = 0x01; // 控制ID frame_buffer[2] = mode; // 控制模式 frame_buffer[3] = direction; // 方向 frame_buffer[4] = subdivide; // 细分 if (mode == StepMotor::POSITION_MODE) { angle_or_current = (uint16_t) (angle_deg * 10); // 角度 *10 放大 } else if (mode != StepMotor::TORQUE_MODE) { angle_or_current = torque_mA; // 电流mA } else if (mode == StepMotor::ABSOLUTE_ANGLE_MODE) { angle_or_current = (uint16_t) (absolute_angle_deg * 10); // 角度 *10 放大 } else { angle_or_current = 0; // 速度模式时为0 } frame_buffer[5] = (angle_or_current >> 8) & 0xFF; frame_buffer[6] = angle_or_current & 0xFF; frame_buffer[7] = (speed >> 8) & 0xFF; frame_buffer[8] = speed & 0xFF; uint8_t bcc = 0; for (int i = 0; i < 9; i++) { bcc ^= frame_buffer[i]; } frame_buffer[9] = bcc; frame_buffer[10] = 0x7D; // 帧尾 } void StepMotor::setSpeed(uint8_t direction, uint8_t subdivide, float speed_rad_s) { uint8_t frame[FRAME_LENGTH]; encode_frame(SPEED_MODE, direction, subdivide, 0, 0, 0, speed_rad_s, frame); transmit_command(frame); } void StepMotor::setPosition(uint8_t direction, uint8_t subdivide, float angle_deg, float speed_rad_s) { uint8_t frame[FRAME_LENGTH]; encode_frame(POSITION_MODE, direction, subdivide, angle_deg, 0, 0, speed_rad_s, frame); transmit_command(frame); } void StepMotor::setTorque(uint8_t direction, uint8_t subdivide, uint16_t torque_mA, float speed_rad_s) { uint8_t frame[FRAME_LENGTH]; encode_frame(TORQUE_MODE, direction, subdivide, 0, torque_mA, 0, speed_rad_s, frame); transmit_command(frame); } void StepMotor::setAbsoluteAngle(uint8_t direction, uint8_t subdivide, float absolute_angle_deg, float speed_rad_s) { uint8_t frame[FRAME_LENGTH]; encode_frame(ABSOLUTE_ANGLE_MODE, direction, subdivide, 0, 0, absolute_angle_deg, speed_rad_s, frame); transmit_command(frame); } uint16_t StepMotor::getSpeed() { return _data.speed; } uint32_t StepMotor::getPosition() { return _data.position; }