#include #include "debug.h" #include "interface_config.h" #include "app/app_config.h" #define TX_PADDING_VAL (0xA5) #include "sdrv_vic.h" #include "intrinsics.h" #include "app/app_differential_drive.h" #include "app/app_param_manage.h" #include "app/app_ultrasonic.h" uint32_t OTA_CANTxID = 0x02;//默认发送ID为0x02 uint32_t OTA_CANRxID = 0x01;//默认接收ID为0x01 uint32_t WDT_CANRxID = 0x03;//默认接收ID为0x03 Timer can_timer_interface1; Timer can_timer_interface2; bool ecu_online = 0;//0掉线,1在线 UnCanFault can_fault_info = { .bit_data.navigator_count = 0, //导航仪计数器 .bit_data.motor1_count = 0, //手动数据计数器 .bit_data.motor2_count = 0, //手动数据计数器 .bit_data.bms_count = 0, //手动数据计数器 .bit_data.temperature_count = 0, //温度计数器 .bit_data.remote_count = 0, //遥控计数器 .bit_data.navigator_state = 0, //自动数据计数器 .bit_data.motor1_state = 0, //手动数据计数器 .bit_data.motor2_state = 0, //手动数据计数器 .bit_data.bms_state = 0, //手动数据计数器 .bit_data.temperature_state = 0, //温度状态 .bit_data.remote_state = 0, //遥控状态 }; // //StrCanFifoQueue can0_Queue;//8帧can缓存,发送队列 //StrCanFifoQueue can1_Queue; //StrCanFifoQueue can2_Queue; //StrCanFifoQueue can3_Queue; //StrCanFifoQueue can4_Queue; //StrCanFifoQueue can5_Queue; //StrCanFifoQueue can6_Queue; //StrCanFifoQueue can7_Queue; //bool busoff_occur_flag = false;//busoff标志 bool can_0_busoff_flag = false;//busoff标志 bool can_1_busoff_flag = false;//busoff标志 bool can_2_busoff_flag = false;//busoff标志 bool can_3_busoff_flag = false;//busoff标志 bool can_4_busoff_flag = false;//busoff标志 bool can_5_busoff_flag = false;//busoff标志 bool can_6_busoff_flag = false;//busoff标志 bool can_7_busoff_flag = false;//busoff标志 flexcan_handle_t can_handle_0;//can初始化结构体 flexcan_handle_t can_handle_1; flexcan_handle_t can_handle_2; flexcan_handle_t can_handle_3; flexcan_handle_t can_handle_4; flexcan_handle_t can_handle_5; flexcan_handle_t can_handle_6; flexcan_handle_t can_handle_7; static uint8_t fifo_Data_0[8]; static flexcan_frame_t fifo_Buf_0; static uint8_t fifo_Data_1[8]; static flexcan_frame_t fifo_Buf_1; static uint8_t fifo_Data_2[8]; static flexcan_frame_t fifo_Buf_2; static uint8_t fifo_Data_3[8]; static flexcan_frame_t fifo_Buf_3; static uint8_t fifo_Data_4[8]; static flexcan_frame_t fifo_Buf_4; static uint8_t fifo_Data_5[8]; static flexcan_frame_t fifo_Buf_5; static uint8_t fifo_Data_6[8]; static flexcan_frame_t fifo_Buf_6; static uint8_t fifo_Data_7[8]; static flexcan_frame_t fifo_Buf_7; uint8_t flexcan_config_rx_fifo(flexcan_handle_t *handle, flexcan_rx_fifo_config_t *config) { flexcan_frame_t *rx_fifo_frame; //------------------------------------------------------------------------------ if(CAN_INDEX_0 == (handle->controller_id))//根据索引选择不同的中断号以及基地址 { rx_fifo_frame = &fifo_Buf_0; rx_fifo_frame->dataBuffer = &fifo_Data_0[0]; } else if(CAN_INDEX_1 == (handle->controller_id)) { rx_fifo_frame = &fifo_Buf_1; rx_fifo_frame->dataBuffer = &fifo_Data_1[0]; } else if(CAN_INDEX_2 == (handle->controller_id)) { rx_fifo_frame = &fifo_Buf_2; rx_fifo_frame->dataBuffer = &fifo_Data_2[0]; } else if(CAN_INDEX_3 == (handle->controller_id)) { rx_fifo_frame = &fifo_Buf_3; rx_fifo_frame->dataBuffer = &fifo_Data_3[0]; } else if(CAN_INDEX_4 == (handle->controller_id)) { rx_fifo_frame = &fifo_Buf_4; rx_fifo_frame->dataBuffer = &fifo_Data_4[0]; } else if(CAN_INDEX_5 == (handle->controller_id)) { rx_fifo_frame = &fifo_Buf_5; rx_fifo_frame->dataBuffer = &fifo_Data_5[0]; } else if(CAN_INDEX_6 == (handle->controller_id)) { rx_fifo_frame = &fifo_Buf_6; rx_fifo_frame->dataBuffer = &fifo_Data_6[0]; } else if(CAN_INDEX_7 == (handle->controller_id)) { rx_fifo_frame = &fifo_Buf_7; rx_fifo_frame->dataBuffer = &fifo_Data_7[0]; } else { return 0; } flexcan_set_rx_fifo_config(handle, config);//配置fifo接收 for (uint8_t i = 0; i < USED_MB_FOR_FIFO; i++) { flexcan_set_rx_individual_mask(handle, i, config->filter_tab[i].filter_mask); } /* rx by interrupt */ flexcan_fifo_transfer_t Xfer = {rx_fifo_frame}; flexcan_receive_fifo_nonblocking(handle, &Xfer); return 1; } /********************************************************************* * @fn CAN_Send_Msg * * @brief CAN Transmit function. * * @param CANx- CAN1 or CAN2 * ID - Message ID * IDE - CAN_Id_Standard or CAN_Id_Extended * RTR - CAN_RTR_Data or CAN_RTR_Remote * msg - Transmit data buffer. * len - Data length. * * @return 0 - Send successful. * 1 - Send failed. */ uint8_t CAN_Send_Msg( flexcan_handle_t *handle, uint32_t ID, flexcan_frame_format_e ide, flexcan_frame_type_e rtr, uint8_t *msg, uint8_t len, uint8_t tx_index) { uint16_t i = 0; //------------------------------------------------------------------------------ flexcan_frame_t frame = {.id = ID, .length = len, .type = rtr, .format = ide, .dataBuffer = msg}; flexcan_mb_transfer_t xfer = {&frame, tx_index}; while( ( flexcan_get_mb_state(handle, tx_index) != FLEXCAN_StateIdle ) && (i < 0xFFF) ) { i++; } if( i == 0xFFF ) { return 1; } else { flexcan_send_nonblocking(handle, &xfer, TX_PADDING_VAL); return 0; } } /********************************************************************* * @fn flexcan_Receive_callback * * @brief erase Data-Flash block, minimal block is 256B * * @param Page_Address - the address of the page being erased. * Length - Erased data length * * @return none */ void flexcan_Receive_callback_0(flexcan_handle_t *handle, flexcan_status_e status, uint32_t result, void *userData) { flexcan_frame_t *buf = (flexcan_frame_t *)userData; uint8_t i = 0; //-------------------------------------------------------------- switch (status) { case FLEXCAN_RX_IDLE: break; case FLEXCAN_RX_FIFO_IDLE: if(TEMP_MODULE_INPUT_ID_1 == (buf->id))//温度 { for(i = 0; i < (buf->length); i++) { un_sw_sample.arr[i] = buf->dataBuffer[i]; } //发射信号 publishMessage(&un_sw_sample, 1);//发射信号 } break; case FLEXCAN_TX_IDLE: break; case FLEXCAN_WAKEUP_TIMEOUT: break; case FLEXCAN_WAKEUP_MATCH: break; case FLEXCAN_ERROR_STATUS: can_0_busoff_flag = true; break; default: break; } } /********************************************************************* * @fn flexcan_Receive_callback * * @brief erase Data-Flash block, minimal block is 256B * * @param Page_Address - the address of the page being erased. * Length - Erased data length * * @return none */ //uint32_t time_elapsed = 0; //uint32_t time_elapsed1 = 0; void flexcan_Receive_callback_1(flexcan_handle_t *handle, flexcan_status_e status, uint32_t result, void *userData) { flexcan_frame_t *buf = (flexcan_frame_t *)userData; uint8_t i = 0; //-------------------------------------------------------------- switch (status) { case FLEXCAN_RX_IDLE: break; case FLEXCAN_RX_FIFO_IDLE: if(LEFT_FRONT_MOTOR_INPUT1 == (buf->id)) { can_fault_info.bit_data.motor1_count ++; for(i = 0; i < (buf->length); i++) { un_motor_input1.arr[i] = buf->dataBuffer[i]; } //发射信号 publishMessage(&un_motor_input1, 1); } else if( LEFT_FRONT_MOTOR_INPUT2 == (buf->id) ) { for(i = 0; i < (buf->length); i++) { un_motor_temp1.arr[i] = buf->dataBuffer[i]; } //发射信号 publishMessage(&un_motor_temp1, 1);//发射信号 } else if( LEFT_REAR_MOTOR2_INPUT1 == (buf->id) )// { can_fault_info.bit_data.motor3_count ++; for(i = 0; i < (buf->length); i++) { un_motor_input3.arr[i] = buf->dataBuffer[i]; } //发射信号 // publishMessage(&un_motor_input3, 1); //修改为 } else if( LEFT_REAR_MOTOR2_INPUT2 == (buf->id) ) { for(i = 0; i < (buf->length); i++) { un_motor_temp3.arr[i] = buf->dataBuffer[i]; } //发射信号 publishMessage(&un_motor_temp3, 1);//发射信号 } else{} break; case FLEXCAN_TX_IDLE: break; case FLEXCAN_WAKEUP_TIMEOUT: break; case FLEXCAN_WAKEUP_MATCH: break; case FLEXCAN_ERROR_STATUS: can_1_busoff_flag = true; break; default: break; } } /********************************************************************* * @fn flexcan_Receive_callback * * @brief erase Data-Flash block, minimal block is 256B * * @param Page_Address - the address of the page being erased. * Length - Erased data length * * @return none */ void flexcan_Receive_callback_2(flexcan_handle_t *handle, flexcan_status_e status, uint32_t result, void *userData) { flexcan_frame_t *buf = (flexcan_frame_t *)userData; uint8_t i = 0; //-------------------------------------------------------------- switch (status) { case FLEXCAN_RX_IDLE: break; case FLEXCAN_RX_FIFO_IDLE: if(RIGHT_FRONT_MOTOR_INPUT1 == (buf->id)) { can_fault_info.bit_data.motor2_count ++; for(i = 0; i < (buf->length); i++) { un_motor_input2.arr[i] = buf->dataBuffer[i]; } //发射信号 publishMessage(&un_motor_input2, 1); } else if( RIGHT_FRONT_MOTOR_INPUT2 == (buf->id) ) { for(i = 0; i < (buf->length); i++) { un_motor_temp2.arr[i] = buf->dataBuffer[i]; } //发射信号 publishMessage(&un_motor_temp2, 1);//发射信号 } else if( RIGHT_REAR_MOTOR_INPUT1 == (buf->id) )// { can_fault_info.bit_data.motor4_count ++; for(i = 0; i < (buf->length); i++) { un_motor_input4.arr[i] = buf->dataBuffer[i]; } //发射信号 publishMessage(&un_motor_input4, 1); } else if( RIGHT_REAR_MOTOR_INPUT2 == (buf->id) ) { for(i = 0; i < (buf->length); i++) { un_motor_temp4.arr[i] = buf->dataBuffer[i]; } //发射信号 publishMessage(&un_motor_temp4, 1);//发射信号 } else{} break; case FLEXCAN_TX_IDLE: break; case FLEXCAN_WAKEUP_TIMEOUT: break; case FLEXCAN_WAKEUP_MATCH: break; case FLEXCAN_ERROR_STATUS: can_2_busoff_flag = true; break; default: break; } } /********************************************************************* * @fn flexcan_Receive_callback * * @brief erase Data-Flash block, minimal block is 256B * * @param Page_Address - the address of the page being erased. * Length - Erased data length * * @return none */ void flexcan_Receive_callback_3(flexcan_handle_t *handle, flexcan_status_e status, uint32_t result, void *userData) { flexcan_frame_t *buf = (flexcan_frame_t *)userData; uint8_t i = 0; //-------------------------------------------------------------- switch (status) { case FLEXCAN_RX_IDLE: break; case FLEXCAN_RX_FIFO_IDLE: if(BMS_INPUT_ID1 == (buf->id))//BMS { can_fault_info.bit_data.bms_count ++; for(i = 0; i < (buf->length); i++) { un_bms_input.arr[i] = buf->dataBuffer[i]; } publishMessage(&un_bms_input, 1); } else if(BMS_INPUT_ID2 == (buf->id))//BMS { for(i = 0; i < (buf->length); i++) { un_bms_input.arr[i+8] = buf->dataBuffer[i]; } //发射信号 publishMessage(&un_bms_input, 1); } else{} break; case FLEXCAN_TX_IDLE: break; case FLEXCAN_WAKEUP_TIMEOUT: break; case FLEXCAN_WAKEUP_MATCH: break; case FLEXCAN_ERROR_STATUS: can_3_busoff_flag = true; break; default: break; } } /********************************************************************* * @fn flexcan_Receive_callback * * @brief erase Data-Flash block, minimal block is 256B * * @param Page_Address - the address of the page being erased. * Length - Erased data length * * @return none */ void flexcan_Receive_callback_4(flexcan_handle_t *handle, flexcan_status_e status, uint32_t result, void *userData) { //-------------------------------------------------------------- switch (status) { case FLEXCAN_RX_IDLE: break; case FLEXCAN_RX_FIFO_IDLE: break; case FLEXCAN_TX_IDLE: break; case FLEXCAN_WAKEUP_TIMEOUT: break; case FLEXCAN_WAKEUP_MATCH: break; case FLEXCAN_ERROR_STATUS: can_4_busoff_flag = true; break; default: break; } } /********************************************************************* * @fn flexcan_Receive_callback * * @brief erase Data-Flash block, minimal block is 256B * * @param Page_Address - the address of the page being erased. * Length - Erased data length * * @return none */ void flexcan_Receive_callback_5(flexcan_handle_t *handle, flexcan_status_e status, uint32_t result, void *userData) { //-------------------------------------------------------------- switch (status) { case FLEXCAN_RX_IDLE: break; case FLEXCAN_RX_FIFO_IDLE: break; case FLEXCAN_TX_IDLE: break; case FLEXCAN_WAKEUP_TIMEOUT: break; case FLEXCAN_WAKEUP_MATCH: break; case FLEXCAN_ERROR_STATUS: can_5_busoff_flag = true; break; default: break; } } /********************************************************************* * @fn flexcan_Receive_callback * * @brief erase Data-Flash block, minimal block is 256B * * @param Page_Address - the address of the page being erased. * Length - Erased data length * * @return none */ void flexcan_Receive_callback_6(flexcan_handle_t *handle, flexcan_status_e status, uint32_t result, void *userData) { flexcan_frame_t *buf = (flexcan_frame_t *)userData; uint8_t i = 0; //-------------------------------------------------------------- switch (status) { case FLEXCAN_RX_IDLE: break; case FLEXCAN_RX_FIFO_IDLE: if(OTA_CANRxID == (buf->id))//ID为1, boot下载配置 { boot_can_flag = true; FrameHeader = ( (buf->dataBuffer[0] << 8) | (buf->dataBuffer[1]) ); } else if(WDT_CANRxID == (buf->id))//接收到喂狗ID { if(FEEDDOG_HEADER == ( (buf->dataBuffer[0] << 8) | (buf->dataBuffer[1]) )) { WDTReFresh_flag = true;//更新喂狗标志 printf("Feed dog flag received %d\n",getCurrentTime()); } } else if(ULTRASONIC_ID_1 == (buf->id)) { for(i = 0; i < (buf->length); i++) { un_ultrasonic_input1.arr[i] = buf->dataBuffer[i]; } publishMessage(&un_ultrasonic_input1, 1); } else{} break; case FLEXCAN_TX_IDLE: break; case FLEXCAN_WAKEUP_TIMEOUT: break; case FLEXCAN_WAKEUP_MATCH: break; case FLEXCAN_ERROR_STATUS: can_6_busoff_flag = true; break; default: break; } } /********************************************************************* * @fn flexcan_Receive_callback * * @brief erase Data-Flash block, minimal block is 256B * * @param Page_Address - the address of the page being erased. * Length - Erased data length * * @return none */ void flexcan_Receive_callback_7(flexcan_handle_t *handle, flexcan_status_e status, uint32_t result, void *userData) { flexcan_frame_t *buf = (flexcan_frame_t *)userData; uint8_t i = 0; //uintptr_t //-------------------------------------------------------------- switch (status) { case FLEXCAN_RX_IDLE: break; case FLEXCAN_RX_FIFO_IDLE: if(REMOTE_ID == (buf->id))//遥控器CAN { can_fault_info.bit_data.remote_count ++; for(i = 0; i < (buf->length); i++) { un_remote_control_input.arr[i] = buf->dataBuffer[i]; } //发射信号 publishMessage(&un_remote_control_input, 1); // printf("ori_remote_stop: %d\n", un_remote_control_input.bit_data.switch_b); } else { } break; case FLEXCAN_TX_IDLE: break; case FLEXCAN_WAKEUP_TIMEOUT: break; case FLEXCAN_WAKEUP_MATCH: break; case FLEXCAN_ERROR_STATUS: can_7_busoff_flag = true; break; default: break; } } //fifo_config 滤波设置 //can_config 波特率以及其他设置 //call_back 中断回调函数 uint8_t initialization_Flexcan(uint8_t can_index, const flexcan_config_t *can_config, flexcan_rx_fifo_config_t *fifo_config, flexcan_transfer_callback_t call_back) { flexcan_handle_t *handle; uint8_t can_irq_num = 0; uint32_t can_reg_base = 0; //------------------------------------------------------------------ if(FLEXCAN7 == can_index)//根据索引选择不同的中断号以及基地址 { handle = &can_handle_0; can_irq_num = CANFD7_CANFD_INTR_NUM; can_reg_base = APB_CANFD7_BASE; } else if(FLEXCAN21 == can_index) { handle = &can_handle_1; can_irq_num = CANFD21_CANFD_INTR_NUM; can_reg_base = APB_CANFD21_BASE; } else if(FLEXCAN16 == can_index) { handle = &can_handle_2; can_irq_num = CANFD16_CANFD_INTR_NUM; can_reg_base = APB_CANFD16_BASE; } else if(FLEXCAN3 == can_index) { handle = &can_handle_3; can_irq_num = CANFD3_CANFD_INTR_NUM; can_reg_base = APB_CANFD3_BASE; } else if(FLEXCAN23 == can_index) { handle = &can_handle_4; can_irq_num = CANFD23_CANFD_INTR_NUM; can_reg_base = APB_CANFD23_BASE; } else if(FLEXCAN5 == can_index) { handle = &can_handle_5; can_irq_num = CANFD5_CANFD_INTR_NUM; can_reg_base = APB_CANFD5_BASE; } else if(FLEXCAN6 == can_index) { handle = &can_handle_6; can_irq_num = CANFD6_CANFD_INTR_NUM; can_reg_base = APB_CANFD6_BASE; } else if(FLEXCAN4 == can_index) { handle = &can_handle_7; can_irq_num = CANFD4_CANFD_INTR_NUM; can_reg_base = APB_CANFD4_BASE; } else { return 0; } //initialize the FlexCAN handle flexcan_create_handle(handle, can_index, (void *)can_reg_base, can_irq_num, call_back, NULL); /* initialize flexCAN. */ flexcan_init(handle, can_config); /* unfreeze the flexCAN by demo. */ flexcan_freeze(handle, false); /* enable busoff interrupt. */ flexcan_enable_interrupts(handle, FLEXCAN_BusOffInterruptEnable);// /* enable irq. */ irq_attach(handle->irq_num, flexcan_irq_handler, handle); irq_enable(handle->irq_num); /* assign fifo only for rx. */ flexcan_config_rx_fifo(handle, fifo_config); /* assign mailbox14-20 for tx. */ for (uint8_t i = TX_MB_INDEX; i < (TX_MB_INDEX + TX_MAILBOX_NUM); i++) { flexcan_set_tx_mb_config(handle, i, true); } return 1; } /* reinitialize the controller. */ void flexcan_Busoff_Recovery(void) { //---------------------------------------------------------- if (can_0_busoff_flag == true) //busoff { printf("can0 busoff !\n"); flexcan_deinit(&can_handle_0); initialization_Flexcan(CAN_INDEX_0, &can_0_config, &can_0_fifo_config, flexcan_Receive_callback_0); can_0_busoff_flag = false; } if (can_1_busoff_flag == true) //busoff { printf("can1 busoff !\n"); flexcan_deinit(&can_handle_1); initialization_Flexcan(CAN_INDEX_1, &can_1_config, &can_1_fifo_config, flexcan_Receive_callback_1); can_1_busoff_flag = false; } if (can_2_busoff_flag == true) //busoff { printf("can2 busoff !\n"); flexcan_deinit(&can_handle_2); initialization_Flexcan(CAN_INDEX_2, &can_2_config, &can_2_fifo_config, flexcan_Receive_callback_2); can_2_busoff_flag = false; } if (can_3_busoff_flag == true) //busoff { printf("can3 busoff !\n"); flexcan_deinit(&can_handle_3); initialization_Flexcan(CAN_INDEX_3, &can_3_config, &can_3_fifo_config, flexcan_Receive_callback_3); can_3_busoff_flag = false; } if (can_4_busoff_flag == true) //busoff { printf("can4 busoff !\n"); flexcan_deinit(&can_handle_4); initialization_Flexcan(CAN_INDEX_4, &can_4_config, &can_4_fifo_config, flexcan_Receive_callback_4); can_4_busoff_flag = false; } if (can_5_busoff_flag == true) //busoff { printf("can5 busoff !\n"); flexcan_deinit(&can_handle_5); initialization_Flexcan(CAN_INDEX_5, &can_5_config, &can_5_fifo_config, flexcan_Receive_callback_5); can_5_busoff_flag = false; } if (can_6_busoff_flag == true) //busoff { printf("can6 busoff !\n"); flexcan_deinit(&can_handle_6); initialization_Flexcan(CAN_INDEX_6, &can_6_config, &can_6_fifo_config, flexcan_Receive_callback_6); can_6_busoff_flag = false; } if (can_7_busoff_flag == true) //busoff { printf("can7 busoff !\n"); flexcan_deinit(&can_handle_7); initialization_Flexcan(CAN_INDEX_7, &can_7_config, &can_7_fifo_config, flexcan_Receive_callback_7); can_7_busoff_flag = false; } } /* initialization_all_flexcan. */ void initialization_All_Flexcan(void) { sdrv_gpio_set_pin_output_level(GPIO_H12, 0); //CAN使能 initialization_Flexcan(CAN_INDEX_0, &can_0_config, &can_0_fifo_config, flexcan_Receive_callback_0);//250k initialization_Flexcan(CAN_INDEX_1, &can_1_config, &can_1_fifo_config, flexcan_Receive_callback_1);//250k initialization_Flexcan(CAN_INDEX_2, &can_2_config, &can_2_fifo_config, flexcan_Receive_callback_2);//250k initialization_Flexcan(CAN_INDEX_3, &can_3_config, &can_3_fifo_config, flexcan_Receive_callback_3);//1M initialization_Flexcan(CAN_INDEX_4, &can_4_config, &can_4_fifo_config, flexcan_Receive_callback_4);//250k initialization_Flexcan(CAN_INDEX_5, &can_5_config, &can_5_fifo_config, flexcan_Receive_callback_5);//250k initialization_Flexcan(CAN_INDEX_6, &can_6_config, &can_6_fifo_config, flexcan_Receive_callback_6);//1M initialization_Flexcan(CAN_INDEX_7, &can_7_config, &can_7_fifo_config, flexcan_Receive_callback_7);//250k } //100ms 调用一次 void canTimerProcess(void *signal_id) { static uint8_t can_timer[5] = {0,0,0,0,0}; static uint8_t can_temp[10] = {0,0,0,0,0,0,0,0,0,0};//中间判断值 uint8_t temp = 0; can_timer[0] ++; if(can_timer[0] >= 1)//100ms判断一次 { can_timer[0] = 0; if(can_fault_info.bit_data.motor1_count == can_temp[0])//数据一样表示故障 { can_fault_info.bit_data.motor1_state = FAULT; } else { can_fault_info.bit_data.motor1_state = NORMAL; can_temp[0] = can_fault_info.bit_data.motor1_count;//数据更新 } if(can_fault_info.bit_data.motor1_state != can_temp[1]) { can_temp[1] = can_fault_info.bit_data.motor1_state; temp ++; } if(can_fault_info.bit_data.motor2_count == can_temp[2])//数据一样表示故障 { can_fault_info.bit_data.motor2_state = FAULT; } else { can_fault_info.bit_data.motor2_state = NORMAL; can_temp[2] = can_fault_info.bit_data.motor2_count;//数据更新 } if(can_fault_info.bit_data.motor2_state != can_temp[3]) { can_temp[3] = can_fault_info.bit_data.motor2_state; temp ++; } } can_timer[1] ++;//BMS判断 if(can_timer[1] >= 20)//2s判断一次 { can_timer[1] = 0; //BMS if(can_fault_info.bit_data.bms_count == can_temp[4])//数据一样表示故障 { can_fault_info.bit_data.bms_state = FAULT; } else { can_fault_info.bit_data.bms_state = NORMAL; can_temp[4] = can_fault_info.bit_data.bms_count;//数据更新 } if(can_fault_info.bit_data.bms_state != can_temp[5]) { can_temp[5] = can_fault_info.bit_data.bms_state; temp ++; } //温度模块 if(can_fault_info.bit_data.temperature_count == can_temp[6])//数据一样表示故障 { can_fault_info.bit_data.temperature_state = FAULT; } else { can_fault_info.bit_data.temperature_state = NORMAL; can_temp[6] = can_fault_info.bit_data.temperature_count;//数据更新 } if(can_fault_info.bit_data.temperature_state != can_temp[7]) { can_temp[7] = can_fault_info.bit_data.temperature_state; temp ++; } } can_timer[2] ++;//遥控器判断 if(can_timer[2] >= 5)//500ms判断一次 { can_timer[2] = 0; //遥控器 if(can_fault_info.bit_data.remote_count == can_temp[8])//数据一样表示故障 { can_fault_info.bit_data.remote_state = FAULT; } else { can_fault_info.bit_data.remote_state = NORMAL; can_temp[8] = can_fault_info.bit_data.remote_count;//数据更新 } if(can_fault_info.bit_data.remote_state != can_temp[9]) { can_temp[9] = can_fault_info.bit_data.remote_state; temp ++; } } can_timer[4] ++;//故障周期发送信号 if( (0 != temp) || (can_timer[4] >= 5) )//故障周期500发送信号,发生变化立马发送 { can_timer[4] = 0; publishMessage(&can_fault_info, 1);// } //busoff判断 can_timer[3] ++; if(can_timer[3] >= 10)//100*100*10 = 1s处理一次 { can_timer[3] = 0; flexcan_Busoff_Recovery();//BUSS OFF处理 } } //static void processSdoOutput1(void *signal_id) //{ // (void)signal_id; // 标记变量为已使用,避免编译器警告 // CAN_Send_Msg(&can_handle_3, 0x601, FLEXCAN_STANDARD_FRAME, FLEXCAN_FrameTypeData, (uint8_t *)&un_sdo_output1, 8, 15);// //} // //static void processSdoOutput2(void *signal_id) //{ // (void)signal_id; // 标记变量为已使用,避免编译器警告 // CAN_Send_Msg(&can_handle_3, 0x601, FLEXCAN_STANDARD_FRAME, FLEXCAN_FrameTypeData, (uint8_t *)&un_sdo_output2, 8, 16); //} // //static void processSdoOutput3(void *signal_id) //{ // (void)signal_id; // 标记变量为已使用,避免编译器警告 // CAN_Send_Msg(&can_handle_3, 0x601, FLEXCAN_STANDARD_FRAME, FLEXCAN_FrameTypeData, (uint8_t *)&un_sdo_output3, 8, 17); //} // //static void processSdoOutput4(void *signal_id) //{ // (void)signal_id; // 标记变量为已使用,避免编译器警告 // CAN_Send_Msg(&can_handle_3, 0x601, FLEXCAN_STANDARD_FRAME, FLEXCAN_FrameTypeData, (uint8_t *)&un_sdo_output4, 8, 18); //} // //static void processSdoOutput5(void *signal_id) //{ // (void)signal_id; // 标记变量为已使用,避免编译器警告 // CAN_Send_Msg(&can_handle_3, 0x601, FLEXCAN_STANDARD_FRAME, FLEXCAN_FrameTypeData, (uint8_t *)&un_sdo_output5, 8, 19); //} // // //static void processSdoOutput7(void *signal_id) //{ // (void)signal_id; // 标记变量为已使用,避免编译器警告 // CAN_Send_Msg(&can_handle_3, 0x601, FLEXCAN_STANDARD_FRAME, FLEXCAN_FrameTypeData, (uint8_t *)&un_sdo_output7, 8, 20); //} static void processMotorOutput1(void *signal_id) { (void)signal_id; // 标记变量为已使用,避免编译器警告 CAN_Send_Msg(&can_handle_1, LEFT_FRONT_MOTOR_OUTPUT1, FLEXCAN_STANDARD_FRAME, FLEXCAN_FrameTypeData, (uint8_t *)&un_motor_output1, 8, 15);//电机1扭矩和转速输出 CAN_Send_Msg(&can_handle_1, LEFT_REAR_MOTOR_OUTPUT1, FLEXCAN_STANDARD_FRAME, FLEXCAN_FrameTypeData, (uint8_t *)&un_motor_output3, 8, 16);//电机1扭矩和转速输出 } static void processMotorOutput2(void *signal_id) { (void)signal_id; // 标记变量为已使用,避免编译器警告 CAN_Send_Msg(&can_handle_2, RIGHT_FRONT_MOTOR_OUTPUT1, FLEXCAN_STANDARD_FRAME, FLEXCAN_FrameTypeData, (uint8_t *)&un_motor_output2, 8, 15);//电机2扭矩和转速输出 CAN_Send_Msg(&can_handle_2, RIGHT_REAR_MOTOR_OUTPUT1, FLEXCAN_STANDARD_FRAME, FLEXCAN_FrameTypeData, (uint8_t *)&un_motor_output4, 8, 16);//电机2扭矩和转速输出 } static void processMotorOutput3(void *signal_id) { (void)signal_id; // 标记变量为已使用,避免编译器警告 CAN_Send_Msg(&can_handle_1, LEFT_FRONT_MOTOR_OUTPUT2, FLEXCAN_STANDARD_FRAME, FLEXCAN_FrameTypeData, (uint8_t *)&un_motor_output1.arr[8], 8, 17);//电机1功率输出 CAN_Send_Msg(&can_handle_1, LEFT_REAR_MOTOR_OUTPUT2, FLEXCAN_STANDARD_FRAME, FLEXCAN_FrameTypeData, (uint8_t *)&un_motor_output3.arr[8], 8, 18);//电机1功率输出 } static void processMotorOutput4(void *signal_id) { (void)signal_id; // 标记变量为已使用,避免编译器警告 CAN_Send_Msg(&can_handle_2, RIGHT_FRONT_MOTOR_OUTPUT2, FLEXCAN_STANDARD_FRAME, FLEXCAN_FrameTypeData, (uint8_t *)&un_motor_output2.arr[8], 8, 17);//电机2功率输出 CAN_Send_Msg(&can_handle_2, RIGHT_REAR_MOTOR_OUTPUT2, FLEXCAN_STANDARD_FRAME, FLEXCAN_FrameTypeData, (uint8_t *)&un_motor_output4.arr[8], 8, 18);//电机2功率输出 } static void processKgfOutput1(void *signal_id) { (void)signal_id; // 标记变量为已使用,避免编译器警告 if(1 == ecu_online)//20250318 修改为在线才能发送,避免采集模块和E3同时发送 { un_inf_can_kgf_output1.bit_data.can_rx5 = 0xE3; CAN_Send_Msg(&can_handle_0, 0x11000002, FLEXCAN_EXTEND_FRAME, FLEXCAN_FrameTypeData, (uint8_t *)&un_inf_can_kgf_output1, 8, 15);//KGF1 } } static void processKgfOutput2(void *signal_id) { (void)signal_id; // 标记变量为已使用,避免编译器警告 if(1 == ecu_online)//20250318 修改为在线才能发送,避免采集模块和E3同时发送 { un_inf_can_kgf_output2.bit_data.can_rx5 = 0xE3; CAN_Send_Msg(&can_handle_0, 0x14000002, FLEXCAN_EXTEND_FRAME, FLEXCAN_FrameTypeData, (uint8_t *)&un_inf_can_kgf_output2, 8, 16);//KGF2 } } //static void processKgfOutput2(void *signal_id) //{ // (void)signal_id; // 标记变量为已使用,避免编译器警告 // if(1 == ecu_online)//20250318 修改为在线才能发送,避免采集模块和E3同时发送 // { // un_inf_can_kgf_output2.bit_data.can_rx5 = 0xE3; // CAN_Send_Msg(&can_handle_0, 0x14000002, FLEXCAN_EXTEND_FRAME, FLEXCAN_FrameTypeData, (uint8_t *)&un_inf_can_kgf_output2, 8, 16);//KGF2 // } // //} static void processWheelSpeedOutput(void *signal_id) { float CANPressSpeedTemp = 0.0;//速度计算中间值 (void)signal_id; // 标记变量为已使用,避免编译器警告 CANPressSpeedTemp = (diff_data.left_motor_speed*(float)getParam("whl_dia") * M_PI*60)/1000.0/(float)getParam("gRatio");// 转/分钟——》km/h 一圈1.8米 20241016 除以减速比 CANPressSpeedTemp = CANPressSpeedTemp*100;//,最后需要扩大100倍 ,系数0.01 un_wheel_wpeed_output.bit_data.left_front = (uint16_t)((int16_t)(CANPressSpeedTemp));//转速*1.8*60*100/1000/ 转/分钟——》km/h 一圈1.8米,最后需要扩大100倍,系数为0.01最后转换为无符号型, 20240629 减速比不需要考虑已经 un_wheel_wpeed_output.bit_data.left_rear = (uint16_t)((int16_t)(CANPressSpeedTemp));//先转换为int,再转换为无符号 CANPressSpeedTemp = (diff_data.right_motor_speed*(float)getParam("whl_dia") * M_PI*60)/1000.0/(float)getParam("gRatio");// 转/分钟——》km/h 一圈1.8米 CANPressSpeedTemp = CANPressSpeedTemp*100;//,最后需要扩大100倍 ,系数0.01 un_wheel_wpeed_output.bit_data.right_front = (uint16_t)((int16_t)(CANPressSpeedTemp));//转速*1.8*60*100/1000/ 转/分钟——》km/h 一圈1.8米,最后需要扩大100倍,系数为0.01最后转换为无符号型, 20240629 减速比不需要考虑已经 un_wheel_wpeed_output.bit_data.right_rear = (uint16_t)((int16_t)(CANPressSpeedTemp));//先转换为int,再转换为无符号 CAN_Send_Msg(&can_handle_4, 0x98, FLEXCAN_EXTEND_FRAME, FLEXCAN_FrameTypeData, (uint8_t *)&un_wheel_wpeed_output, 8, 15);//导航仪 } static void processHBridgeOutput(void *signal_id) { (void)signal_id; // 标记变量为已使用,避免编译器警告 CAN_Send_Msg(&can_handle_5, 0x7F2, FLEXCAN_STANDARD_FRAME, FLEXCAN_FrameTypeData, (uint8_t *)&un_h_bridge_output, 8, 17);//H桥输出 CAN_Send_Msg(&can_handle_5, 0x722, FLEXCAN_STANDARD_FRAME, FLEXCAN_FrameTypeData, (uint8_t *)&un_h_bridge_output1, 8, 19);//H桥输出 } static void processUnGatherOutput(void *signal_id) { (void)signal_id; // 标记变量为已使用,避免编译器警告 CAN_Send_Msg(&can_handle_0, 0x15000002, FLEXCAN_EXTEND_FRAME, FLEXCAN_FrameTypeData, (uint8_t *)&un_gather_output, 8, 18);//采集输出 } static void processUltrasonicOutput(void *signal_id) { (void)signal_id; // 标记变量为已使用,避免编译器警告 CAN_Send_Msg(&can_handle_6, ULTRASONIC_ID_1, FLEXCAN_STANDARD_FRAME, FLEXCAN_FrameTypeData, (uint8_t *)&un_ultrasonic_output1, 8, 15);//超声波输出 } //static void processHBridgeOutput2(void *signal_id) //{ // (void)signal_id; // 标记变量为已使用,避免编译器警告 // CAN_Send_Msg(&can_handle_5, 0x722, FLEXCAN_STANDARD_FRAME, FLEXCAN_FrameTypeData, (uint8_t *)&un_h_bridge_output2, 8, 16);//H桥输出 //} //static void processLifterOutput(void *signal_id) //{ // (void)signal_id; // 标记变量为已使用,避免编译器警告 // CAN_Send_Msg(&can_handle_5, 0x6F2, FLEXCAN_STANDARD_FRAME, FLEXCAN_FrameTypeData, (uint8_t *)&un_lifter_output, 8, 17);//推杆输出 //} //can 发送 100ms调用一次 void canSendAll(void *signal_id) { static uint16_t wheel_speed_cnt = 0; // static uint8_t kgf_cnt = 0; static uint16_t bms_cnt1 = 0; static uint16_t bms_cnt2 = 0; // static uint16_t motor_speed_cnt = 0; static uint16_t motor_power_cnt = 0; // static uint8_t h_bridge_cnt = 0; uint8_t CanData[8] = {0,0,0,0,0,0,0,0}; //------------------------------------------------------------------------- (void)signal_id; // 标记变量为已使用,避免编译器警告 bms_cnt1 ++; if(bms_cnt1 >= 1000)//1s { bms_cnt1 = 0; CanData[0] = 0x5A; CAN_Send_Msg(&can_handle_3, 0x100, FLEXCAN_STANDARD_FRAME, FLEXCAN_FrameTypeData, CanData, 1, 15);//BMS请求数据 } bms_cnt2 ++; if(bms_cnt2 >= 1100)//1s { bms_cnt2 = 0; CanData[0] = 0x5A; CAN_Send_Msg(&can_handle_3, 0x101, FLEXCAN_STANDARD_FRAME, FLEXCAN_FrameTypeData, CanData, 1, 16);//BMS请求数据 } motor_power_cnt ++; if(motor_power_cnt >= 1000)//1s发送一次 { motor_power_cnt = 0; processMotorOutput3(CanData); processMotorOutput4(CanData); } // motor_power_cnt ++; // if(motor_power_cnt >= 10)//读取转速 20ms发送 // { // motor_power_cnt = 0; // // un_motor_output1.bit_data.MotCon_1Signal6 = 0x84; // un_motor_output1.bit_data.MotCon_1Signal7 = 0x02; // un_motor_output2.bit_data.MotCon_1Signal6 = 0x84; // un_motor_output2.bit_data.MotCon_1Signal7 = 0x02; // // processMotorOutput3(CanData); // processMotorOutput4(CanData); // } // kgf_cnt ++; // if(kgf_cnt >= 5)//20210312 控制CAN通讯模块输出 20210710修改为50ms发送 // { // kgf_cnt = 0; // // processKgfOutput1(CanData); // processKgfOutput2(CanData); // } // //轮速发送 wheel_speed_cnt ++; if(wheel_speed_cnt >= 100) { wheel_speed_cnt = 0; processWheelSpeedOutput(CanData); // CAN_Send_Msg(&can_handle_0, 0x120, FLEXCAN_STANDARD_FRAME, FLEXCAN_FrameTypeData, CanData, 8, 16);//BMS请求数据 // CAN_Send_Msg(&can_handle_1, 0x121, FLEXCAN_STANDARD_FRAME, FLEXCAN_FrameTypeData, CanData, 8, 17);//BMS请求数据 // CAN_Send_Msg(&can_handle_2, 0x122, FLEXCAN_STANDARD_FRAME, FLEXCAN_FrameTypeData, CanData, 8, 17);//BMS请求数据 // CAN_Send_Msg(&can_handle_3, 0x123, FLEXCAN_STANDARD_FRAME, FLEXCAN_FrameTypeData, CanData, 8, 16);//BMS请求数据 // CAN_Send_Msg(&can_handle_4, 0x124, FLEXCAN_STANDARD_FRAME, FLEXCAN_FrameTypeData, CanData, 8, 16);//BMS请求数据 // CAN_Send_Msg(&can_handle_5, 0x125, FLEXCAN_STANDARD_FRAME, FLEXCAN_FrameTypeData, CanData, 8, 16);//BMS请求数据 CAN_Send_Msg(&can_handle_6, 0x126, FLEXCAN_STANDARD_FRAME, FLEXCAN_FrameTypeData, &un_can_debug_output.arr[0], 8, 16);//BMS请求数据 // CAN_Send_Msg(&can_handle_7, 0x127, FLEXCAN_STANDARD_FRAME, FLEXCAN_FrameTypeData, CanData, 8, 16);//BMS请求数据 } // //H桥数据发送 // h_bridge_cnt ++; // if(h_bridge_cnt >= 5) // { // h_bridge_cnt = 0; // // processHBridgeOutput(CanData); // } timerStart(&can_timer_interface1,1,1);//1ms调用一次 } // can定时器信号处理函数 static void canInterfaceTimerProcess(void *signal_id) { (void)signal_id; // 标记变量为已使用,避免编译器警告 // uint32_t time_boot = getCurrentTime();//记录当前时间 canTimerProcess(signal_id); // printf("motor1 interval:%d,motor2 interval:%d\n",time_elapsed,time_elapsed1);//打印电机控制器1,2接收间隔 timerStart(&can_timer_interface2,100,1);//100ms调用一次 // printf("canInterface spend time:%d\n",getCurrentTime() - time_boot);//检查app用了多长时间 } static void canInterfaceInput(void *signal_id) { if (signal_id == &un_sw_sample) { ecu_online = un_sw_sample.bit_data.flg_wake_ecu; } } // APP模块的初始化 void canInterfaceInit(void) { memset(&un_motor_input1, 0, sizeof(UnMotorInput)); memset(&un_motor_input2, 0, sizeof(UnMotorInput)); memset(&un_bms_input , 0, sizeof(UnBmsInput)); memset(&un_temp_module_input, 0, sizeof(UnTempModuleInput)); memset(&un_motor_output1, 0, sizeof(UnMotorOutput)); memset(&un_motor_output2, 0, sizeof(UnMotorOutput)); // un_motor_output1.bit_data.mode = 0x05; // un_motor_output1.bit_data.gear = 0x01; // un_motor_output1.bit_data.can_gear = 0x01; // un_motor_output1.bit_data.motor_direction = 0x01; // un_motor_output1.bit_data.control_data1 = 0x0; // un_motor_output1.bit_data.control_data2 = 0x0; // // un_motor_output2.bit_data.mode = 0x05; // un_motor_output2.bit_data.gear = 0x01; // un_motor_output2.bit_data.can_gear = 0x01; // un_motor_output2.bit_data.motor_direction = 0x00; // un_motor_output2.bit_data.control_data1 = 0x0; // un_motor_output2.bit_data.control_data2 = 0x0; // // un_motor_output3.bit_data.mode = 0x05; // un_motor_output3.bit_data.gear = 0x01; // un_motor_output3.bit_data.can_gear = 0x01; // un_motor_output3.bit_data.motor_direction = 0x01; // un_motor_output3.bit_data.control_data1 = 0x0; // un_motor_output3.bit_data.control_data2 = 0x0; // // un_motor_output4.bit_data.mode = 0x05; // un_motor_output4.bit_data.gear = 0x01; // un_motor_output4.bit_data.can_gear = 0x01; // un_motor_output4.bit_data.motor_direction = 0x00; // un_motor_output4.bit_data.control_data1 = 0x0; // un_motor_output4.bit_data.control_data2 = 0x0; // un_motor_output1.bit_data.set_torque = 30000;//按照偏移量初始化 // un_motor_output1.bit_data.set_rotation_speed = 30000; // un_motor_output1.bit_data.mode = 0; // un_motor_output2.bit_data.set_torque = 30000; // un_motor_output2.bit_data.set_rotation_speed = 30000; // un_motor_output2.bit_data.mode = 0; // can_fault_info.bit_data.navigator_state = 1; memset(&un_inf_can_kgf_output1, 0, sizeof(UnInfCanKGFOutput)); memset(&un_inf_can_kgf_output2, 0, sizeof(UnInfCanKGFOutput)); memset(&un_h_bridge_output, 0, sizeof(UnHBridgeOutput)); memset(&un_wheel_wpeed_output, 0, sizeof(UnWheelSpeedOutput)); memset(&un_remote_control_input, 0, sizeof(UnRemoteControlInput)); un_inf_can_kgf_output2.bit_data.KGF04 = 1;//不能自杀,这个是控制自己上电的通道 // 初始化定时器,使用 brake_timer 的地址作为信号ID timerInit(&can_timer_interface1); timerInit(&can_timer_interface2); subscribe(&can_timer_interface1, canSendAll); subscribe(&can_timer_interface2, canInterfaceTimerProcess); subscribe(&un_motor_output1, processMotorOutput1); subscribe(&un_motor_output2, processMotorOutput2); subscribe(&un_inf_can_kgf_output1, processKgfOutput1); subscribe(&un_inf_can_kgf_output2, processKgfOutput2); subscribe(&un_wheel_wpeed_output, processWheelSpeedOutput); subscribe(&un_h_bridge_output, processHBridgeOutput); subscribe(&un_gather_output, processUnGatherOutput); subscribe(&un_sw_sample, canInterfaceInput); // 急停开关、高压开关 ,唤醒标志 subscribe(&un_ultrasonic_output1, processUltrasonicOutput); // 输出超声波传感器 // subscribe(&un_h_bridge_output2, processHBridgeOutput2); // subscribe(&un_lifter_output, processLifterOutput); // subscribe(&un_sdo_output1, processSdoOutput1); // subscribe(&un_sdo_output2, processSdoOutput2); // subscribe(&un_sdo_output3, processSdoOutput3); // subscribe(&un_sdo_output4, processSdoOutput4); // subscribe(&un_sdo_output5, processSdoOutput5); // subscribe(&un_sdo_output7, processSdoOutput7); timerStart(&can_timer_interface1,1,1);//1ms调用一次 timerStart(&can_timer_interface2,100,1);//100ms调用一次 printf( "canInterface: initial OK %d\n",getCurrentTime()); }