#include "odrive_can.h" #include "can_it.h" #include "main.h" #include "can.h" /******小端模式,低字节在前***/ /*********数据拆分************/ #define BYTE0(dwTemp) (*(char *)(&dwTemp)) #define BYTE1(dwTemp) (*((char *)(&dwTemp) + 1)) #define BYTE2(dwTemp) (*((char *)(&dwTemp) + 2)) #define BYTE3(dwTemp) (*((char *)(&dwTemp) + 3)) //请在此处写明你所使用的can是can1还是can2 #define WHICH_CAN 2 //如果已经在其他地方完成了can初始化,则此处不进行can初始化 #define INITED 1 odrive_msg_t odrive_msg; /** * 用户自定义can1中断回调函数 */ void User_Odrive_Can1_CB(void) { CAN_RxHeaderTypeDef rx_header; uint8_t rx_data[8]; HAL_CAN_GetRxMessage(&hcan1, CAN_RX_FIFO0, &rx_header, rx_data); switch (rx_header.StdId) { case (AXIS0_NODE << 5) | ODRIVE_ENCODER_VALUE: odrive_msg.pos = rx_data[3] << 24 | rx_data[2] << 16 | rx_data[1] << 8 | rx_data[0]; odrive_msg.speed = rx_data[7] << 24 | rx_data[6] << 16 | rx_data[5] << 8 | rx_data[4]; break; } } #if WHICH_CAN == 2 /** * 用户自定义can2中断回调函数 */ uint8_t rx_data[8]; void User_Odrive_Can2_CB(void) { CAN_RxHeaderTypeDef rx_header; HAL_CAN_GetRxMessage(&hcan2, CAN_RX_FIFO1, &rx_header, rx_data); switch (rx_header.StdId) { case (AXIS0_NODE << 5) | ODRIVE_ENCODER_VALUE: odrive_msg.pos = rx_data[3] << 24 | rx_data[2] << 16 | rx_data[1] << 8 | rx_data[0]; odrive_msg.speed = rx_data[7] << 24 | rx_data[6] << 16 | rx_data[5] << 8 | rx_data[4]; break; } } #endif /** * @brief odrive初始化 * @param none * @return device_status_e,若值为0,则为成功 */ device_status_e Odrive_Can_Init(void) { #if INITED == 0 /**********************can初始化*********************/ CAN_FilterTypeDef can_filter_st; can_filter_st.FilterActivation = ENABLE; can_filter_st.FilterMode = CAN_FILTERMODE_IDMASK; can_filter_st.FilterScale = CAN_FILTERSCALE_32BIT; can_filter_st.FilterIdHigh = 0x0000; can_filter_st.FilterIdLow = 0x0000; can_filter_st.FilterMaskIdHigh = 0x0000; can_filter_st.FilterMaskIdLow = 0x0000; can_filter_st.FilterBank = 0; can_filter_st.FilterFIFOAssignment = CAN_RX_FIFO0; HAL_CAN_ConfigFilter(&hcan1, &can_filter_st); HAL_CAN_Start(&hcan1); HAL_CAN_ActivateNotification(&hcan1, CAN_IT_RX_FIFO0_MSG_PENDING); #if WHICH_CAN == 1 //指向自定义的中断回调函数 BSP_CAN_RegisterCallback(BSP_CAN_1,HAL_CAN_RX_FIFO0_MSG_PENDING_CB,&User_Odrive_Can1_CB); #endif #if WHICH_CAN == 2 //开启can2过滤器之前必须先开启can1 can_filter_st.SlaveStartFilterBank = 14; can_filter_st.FilterBank = 14; can_filter_st.FilterFIFOAssignment = CAN_RX_FIFO1; HAL_CAN_ConfigFilter(&hcan2, &can_filter_st); HAL_CAN_Start(&hcan2); HAL_CAN_ActivateNotification(&hcan2, CAN_IT_RX_FIFO1_MSG_PENDING); //指向自定义的中断回调函数 BSP_CAN_RegisterCallback(BSP_CAN_2,HAL_CAN_RX_FIFO1_MSG_PENDING_CB,&User_Odrive_Can2_CB); #endif #else #if WHICH_CAN == 1 //若已经在别处初始化can,则此处只进行指向自定义的中断回调函数 BSP_CAN_RegisterCallback(BSP_CAN_1,HAL_CAN_RX_FIFO0_MSG_PENDING_CB,&User_Odrive_Can1_CB); #else BSP_CAN_RegisterCallback(BSP_CAN_2,HAL_CAN_RX_FIFO1_MSG_PENDING_CB,&User_Odrive_Can2_CB); #endif #endif return DEVICE_OK; } // void odrive_CB(void) // { // BSP_CAN_RegisterCallback(BSP_CAN_1,HAL_CAN_RX_FIFO0_MSG_PENDING_CB,&User_Odrive_Can1_CB); // }//我自己加的 static CAN_TxHeaderTypeDef tx_message; static uint8_t can_send_data[8]; /** * @brief 速度模式控制电机 * @param node_id 节点id,AXIS0_NODE或者AXIS0_NODE * @param speed 目标速度 * @return device_status_e,若值为0,则为成功 */ device_status_e odrive_speed_cmd(node_id_e node_id, fp32 speed) { if(node_id != AXIS0_NODE && node_id != AXIS1_NODE) { return DEVICE_ERR; }//如果节点id错误,则返回错误 uint32_t send_mail_box; tx_message.StdId = node_id << 5 | ODRIVE_SPEED_SET; tx_message.IDE = CAN_ID_STD; tx_message.RTR = CAN_RTR_DATA; tx_message.DLC = 0x08; can_send_data[0] = BYTE0(speed); can_send_data[1] = BYTE1(speed); can_send_data[2] = BYTE2(speed); can_send_data[3] = BYTE3(speed); can_send_data[4] = 0; can_send_data[5] = 0; can_send_data[6] = 0; can_send_data[7] = 0; #if WHICH_CAN == 1 HAL_CAN_AddTxMessage(&hcan1, &tx_message, can_send_data, &send_mail_box); #else HAL_CAN_AddTxMessage(&hcan2, &tx_message, can_send_data, &send_mail_box); #endif return DEVICE_OK; } uint8_t a; /** * @brief 位置模式控制电机 * @param node_id 节点id,AXIS0_NODE或者AXIS0_NODE * @param pos 目标位置 * @param accel 加速度限制 * @param decel 减速度限制 * @return device_status_e,若值为0,则为成功 */ device_status_e odrive_pos_cmd(node_id_e node_id, fp32 pos) { if(node_id != AXIS0_NODE && node_id != AXIS1_NODE) { return DEVICE_ERR; }//如果节点id错误,则返回错误 uint32_t send_mail_box; //发送位置 tx_message.StdId = node_id << 5 | ODRIVE_POS_SET; tx_message.IDE = CAN_ID_STD; tx_message.RTR = CAN_RTR_DATA; tx_message.DLC = 0x08; can_send_data[0] = BYTE0(pos); can_send_data[1] = BYTE1(pos); can_send_data[2] = BYTE2(pos); can_send_data[3] = BYTE3(pos); can_send_data[4] = 0; can_send_data[5] = 0; can_send_data[6] = 0; can_send_data[7] = 0; #if WHICH_CAN == 1 a= HAL_CAN_AddTxMessage(&hcan1, &tx_message, can_send_data, &send_mail_box); #else HAL_CAN_AddTxMessage(&hcan2, &tx_message, can_send_data, &send_mail_box); #endif return DEVICE_OK; } /** * @brief 位置模式控制电机 * @param node_id 节点id,AXIS0_NODE或者AXIS0_NODE * @param pos 目标位置 * @param accel 加速度限制 * @param decel 减速度限制 * @return device_status_e,若值为0,则为成功 */ device_status_e odrive_accel_cmd(node_id_e node_id, fp32 accel , fp32 decel) { if(node_id != AXIS0_NODE && node_id != AXIS1_NODE) { return DEVICE_ERR; }//如果节点id错误,则返回错误 //发送加减速 uint32_t send_mail_box; tx_message.StdId = node_id << 5 | ODRIVE_TRAJ_ACC_LIM; tx_message.IDE = CAN_ID_STD; tx_message.RTR = CAN_RTR_DATA; tx_message.DLC = 0x08; can_send_data[0] = BYTE0(accel); can_send_data[1] = BYTE1(accel); can_send_data[2] = BYTE2(accel); can_send_data[3] = BYTE3(accel); can_send_data[4] = BYTE0(decel); can_send_data[5] = BYTE1(decel); can_send_data[6] = BYTE2(decel); can_send_data[7] = BYTE3(decel); #if WHICH_CAN == 1 HAL_CAN_AddTxMessage(&hcan1, &tx_message, can_send_data, &send_mail_box); #else HAL_CAN_AddTxMessage(&hcan2, &tx_message, can_send_data, &send_mail_box); #endif return DEVICE_OK; } /** * @brief 获取编码器估算值 * @param node_id 节点id,AXIS0_NODE或者AXIS0_NODE * @return device_status_e,若值为0,则为成功 */ device_status_e odrive_get_encode(node_id_e node_id) { if(node_id != AXIS0_NODE && node_id != AXIS1_NODE) { return DEVICE_ERR; }//如果节点id错误,则返回错误 uint32_t send_mail_box; tx_message.StdId = node_id << 5 | ODRIVE_ENCODER_VALUE; tx_message.IDE = CAN_ID_STD; tx_message.RTR = CAN_RTR_REMOTE; tx_message.DLC = 0x08; can_send_data[0] = 0x10; can_send_data[1] = 0; can_send_data[2] = 0; can_send_data[3] = 0; can_send_data[4] = 0; can_send_data[5] = 0; can_send_data[6] = 0; can_send_data[7] = 0; #if WHICH_CAN == 1 HAL_CAN_AddTxMessage(&hcan1, &tx_message, can_send_data, &send_mail_box); #else HAL_CAN_AddTxMessage(&hcan2, &tx_message, can_send_data, &send_mail_box); #endif return DEVICE_OK; } /** * @brief 获取odrive结构体指针 * @param none * @return 信息结构体指针 */ odrive_msg_t* Get_Odrive_Point(void) { return &odrive_msg; }