Files
test/interface_can.c
2025-07-23 11:46:22 +08:00

1429 lines
52 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include <flexcan_cfg.h>
#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);//采集输出
}
// un_gather_output.bit_data.vehicle_mode = power_data.current_state;
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 >= 10)//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);//打印电机控制器12接收间隔
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_motor_output3, processMotorOutput3);
// subscribe(&un_motor_output4, processMotorOutput4);
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());
}