STM32H743的FDCAN1不能正常工作

2019-07-20 01:52发布

本帖最后由 梅川酷子 于 2019-5-17 21:07 编辑

在使用FD CAN的时候,出现了一系列莫名其妙的问题.希望能得到大神们的帮助,非常感谢~

1.内环模式:
发送不成功,第2次发送会进入发送FIFO满的错误。
接收不到自发送的报文。

2.外环模式:
情况跟内环模式一样,但是实际上和H750相连的USB/CAN已经成功接收到报文,示波器上也有相应的波形出现。
H750在不断地重试,而实际上我代码只发送了一次。


0.png
3.正常模式:
外部USB/CAN会接收到重复的报文,也就是说,有时一次可发送成功,有时需要两三次重试。
下图我发了三次,间隔几秒,但是,你可以从时间戳看到,序号为3和4的报文是重试的。
1.png

接收也类似,USB/CAN每次都能发送成功,并没有提示发送失败,但是H750这边只能接收到很少的报文,丢失非常严重。

环回模式完全不正常,正常模式比环回模式正常一些,但也不完全正常。

以下是一些硬件和软件信息

收发器:MCP2561FD,支持CAN FD
编译器:IAR 8.32
HAL版本:1.3(最新)
帧模式:经典模式

波特率:1Mbps

FDCAN1_Handler.Init.NominalPrescaler = 10;//tq=25ns
FDCAN1_Handler.Init.NominalSyncJumpWidth = 8;//8;
FDCAN1_Handler.Init.NominalTimeSeg1 = 23+8;
FDCAN1_Handler.Init.NominalTimeSeg2 = 8;
FDCAN1_Handler.Init.DataPrescaler = FDCAN1_Handler.Init.NominalPrescaler;
FDCAN1_Handler.Init.DataSyncJumpWidth = FDCAN1_Handler.Init.NominalSyncJumpWidth;
FDCAN1_Handler.Init.DataTimeSeg1 = FDCAN1_Handler.Init.NominalTimeSeg1;
FDCAN1_Handler.Init.DataTimeSeg2 = FDCAN1_Handler.Init.NominalTimeSeg2;


初始化代码
uint8_t FDCAN1_Setup(void)
{
    FDCAN_FilterTypeDef FDCAN1_RXFilter;

    FDCAN1_INIT_LOCK();

    //复位FDCAN1
    HAL_FDCAN_DeInit(&FDCAN1_Handler);

    FDCAN1_Handler.Instance = FDCAN1;
    FDCAN1_Handler.Init.FrameFormat = FDCAN_FRAME_CLASSIC;
    FDCAN1_Handler.Init.Mode = FDCAN_MODE_NORMAL;
    FDCAN1_Handler.Init.AutoRetransmission = DISABLE;
    FDCAN1_Handler.Init.TransmitPause = DISABLE;
    FDCAN1_Handler.Init.ProtocolException = DISABLE;

    FDCAN1_Handler.Init.NominalPrescaler = 10;//tq=25ns
    FDCAN1_Handler.Init.NominalSyncJumpWidth = 8;//8;
    FDCAN1_Handler.Init.NominalTimeSeg1 = 23+8;
    FDCAN1_Handler.Init.NominalTimeSeg2 = 8;
    FDCAN1_Handler.Init.DataPrescaler = FDCAN1_Handler.Init.NominalPrescaler;
    FDCAN1_Handler.Init.DataSyncJumpWidth = FDCAN1_Handler.Init.NominalSyncJumpWidth;
    FDCAN1_Handler.Init.DataTimeSeg1 = FDCAN1_Handler.Init.NominalTimeSeg1;
    FDCAN1_Handler.Init.DataTimeSeg2 = FDCAN1_Handler.Init.NominalTimeSeg2;

    FDCAN_Baudrate=(float)400000000/(FDCAN1_Handler.Init.NominalPrescaler)/(FDCAN1_Handler.Init.NominalTimeSeg1+FDCAN1_Handler.Init.NominalTimeSeg2+1);

    FDCAN1_Handler.Init.MessageRAMOffset = 0;

    FDCAN1_Handler.Init.StdFiltersNbr = 1;
    FDCAN1_Handler.Init.ExtFiltersNbr = 1;
    FDCAN1_Handler.Init.RxFifo0ElmtsNbr = 1;
    FDCAN1_Handler.Init.RxFifo0ElmtSize = FDCAN_DATA_BYTES_64;

    FDCAN1_Handler.Init.RxFifo1ElmtsNbr = 1;
    FDCAN1_Handler.Init.RxFifo1ElmtSize = FDCAN_DATA_BYTES_64;

    FDCAN1_Handler.Init.RxBuffersNbr = 1;

    FDCAN1_Handler.Init.TxEventsNbr = 0;
    FDCAN1_Handler.Init.TxBuffersNbr = 1;
    FDCAN1_Handler.Init.TxFifoQueueElmtsNbr = 1;
    FDCAN1_Handler.Init.TxFifoQueueMode = FDCAN_TX_FIFO_OPERATION;
    FDCAN1_Handler.Init.TxElmtSize = FDCAN_DATA_BYTES_8;

    HAL_FDCAN_Init(&FDCAN1_Handler);

    //配置RX滤波器   
    FDCAN1_RXFilter.IdType=FDCAN_EXTENDED_ID;                       //标准ID
    FDCAN1_RXFilter.FilterIndex=0;                                  //滤波器索引                  
    FDCAN1_RXFilter.FilterType=FDCAN_FILTER_MASK;                   //滤波器类型
    FDCAN1_RXFilter.FilterConfig=FDCAN_FILTER_TO_RXBUFFER;//FDCAN_FILTER_TO_RXFIFO0;           //过滤器0关联到FIFO0  
    FDCAN1_RXFilter.FilterID1=0;                               //32位ID
    FDCAN1_RXFilter.FilterID2=0;                               //如果FDCAN配置为传统模式的话,这里是32位掩码
    if(HAL_FDCAN_ConfigFilter(&FDCAN1_Handler,&FDCAN1_RXFilter)!=HAL_OK)
    {
        return 2;
    }

    HAL_FDCAN_Start(&FDCAN1_Handler);

    HAL_FDCAN_ActivateNotification(&FDCAN1_Handler,FDCAN_IT_RX_FIFO0_NEW_MESSAGE,0);

    return 0;
}


发送代码
uint8_t FDCAN1_Send_Msg(uint8_t* msg,uint32_t len)
{   
    FDCAN1_TRANSMITION_ENTER_LOCK();

    FDCAN1_TxHeader.Identifier= 0;                     //32位ID
    FDCAN1_TxHeader.IdType=FDCAN_EXTENDED_ID;                  //标准ID
    FDCAN1_TxHeader.TxFrameType=FDCAN_DATA_FRAME;              //数据帧
    FDCAN1_TxHeader.DataLength=FDCAN_DLC_BYTES_8;               //数据长度
    FDCAN1_TxHeader.ErrorStateIndicator=FDCAN_ESI_ACTIVE;            
    FDCAN1_TxHeader.BitRateSwitch=FDCAN_BRS_OFF;               //关闭速率切换
    FDCAN1_TxHeader.FDFormat=FDCAN_CLASSIC_CAN;                //传统的CAN模式
    FDCAN1_TxHeader.TxEventFifoControl=FDCAN_NO_TX_EVENTS;     //无发送事件
    FDCAN1_TxHeader.MessageMarker=0;                           

    #if(1)
    if(HAL_FDCAN_AddMessageToTxFifoQ(&FDCAN1_Handler,&FDCAN1_TxHeader,msg)==HAL_OK)
    {
        FDCAN1_TRANSMITION_EXIT_LOCK();
        return 0;
    }
    #else
    if(HAL_FDCAN_AddMessageToTxBuffer(&FDCAN1_Handler,&FDCAN1_TxHeader,msg,1)==HAL_OK)
    {
        HAL_FDCAN_EnableTxBufferRequest(&FDCAN1_Handler,1);
        FDCAN1_TRANSMITION_EXIT_LOCK();
        return 0;
    }
    #endif
    else
    {
        FDCAN1_TRANSMITION_EXIT_LOCK();
        return 1;
    }
}


中断
uint8_t FDCAN1_Receive_Msg(uint8_t *buf)
{   
    if(HAL_FDCAN_GetRxMessage(&FDCAN1_Handler,FDCAN_RX_FIFO0,&FDCAN1_RxHeader,buf)!=HAL_OK)return 0;//接收数据
    return FDCAN1_RxHeader.DataLength>>16;  
}

void FDCAN1_IT0_IRQHandler(void)
{
    HAL_FDCAN_IRQHandler(&FDCAN1_Handler);static uint32_t CAN1_RX0_Counter=0;CAN1_RX0_Counter++;
}

void FDCAN1_IT1_IRQHandler(void)
{
    HAL_FDCAN_IRQHandler(&FDCAN1_Handler);static uint32_t CAN1_RX1_Counter=0;CAN1_RX1_Counter++;
}

void HAL_FDCAN_RxFifo0Callback(FDCAN_HandleTypeDef *hfdcan, uint32_t RxFifo0ITs)
{
    //uint8_t i=0;
    uint8_t rxdata[8];
    if((RxFifo0ITs&FDCAN_IT_RX_FIFO0_NEW_MESSAGE)!=RESET)   //FIFO1新数据中断
    {
        //提取FIFO0中接收到的数据
        HAL_FDCAN_GetRxMessage(hfdcan,FDCAN_RX_FIFO0,&FDCAN1_RxHeader,rxdata);
        //printf("id:%#x ",FDCAN1_RxHeader.Identifier);
        //printf("len:%d ",FDCAN1_RxHeader.DataLength>>16);
        //for(i=0;i<8;i++)
        //printf("rxdata[%d]:%d ",i,rxdata);
        HAL_FDCAN_ActivateNotification(hfdcan,FDCAN_IT_RX_FIFO0_NEW_MESSAGE,0);
    }
}


void HAL_FDCAN_RxFifo1Callback(FDCAN_HandleTypeDef *hfdcan, uint32_t RxFifo1ITs)
{
    //uint8_t i=0;
    uint8_t rxdata[8];
    if((RxFifo1ITs&FDCAN_IT_RX_FIFO1_NEW_MESSAGE)!=RESET)   //FIFO1新数据中断
    {
        //提取FIFO0中接收到的数据
        HAL_FDCAN_GetRxMessage(hfdcan,FDCAN_RX_FIFO1,&FDCAN1_RxHeader,rxdata);
        //printf("id:%#x ",FDCAN1_RxHeader.Identifier);
        //printf("len:%d ",FDCAN1_RxHeader.DataLength>>16);
        //for(i=0;i<8;i++)
        //printf("rxdata[%d]:%d ",i,rxdata);
        HAL_FDCAN_ActivateNotification(hfdcan,FDCAN_IT_RX_FIFO1_NEW_MESSAGE,0);
    }
}



IO初始化
void HAL_FDCAN_MspInit(FDCAN_HandleTypeDef* hfdcan)
{
    GPIO_InitTypeDef GPIO_InitStruct = {0};

    HAL_GPIO_WritePin(GPIOD, GPIO_PIN_0|GPIO_PIN_1, GPIO_PIN_SET);

    GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_PULLUP;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
    GPIO_InitStruct.Alternate = GPIO_AF9_FDCAN1;
    HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);

    HAL_NVIC_SetPriority(FDCAN1_IT0_IRQn, 0, 0);
    HAL_NVIC_EnableIRQ(FDCAN1_IT0_IRQn);
    HAL_NVIC_SetPriority(FDCAN1_IT1_IRQn, 0, 0);
    HAL_NVIC_EnableIRQ(FDCAN1_IT1_IRQn);
    HAL_NVIC_SetPriority(FDCAN_CAL_IRQn, 0, 0);
    HAL_NVIC_EnableIRQ(FDCAN_CAL_IRQn);
}




0条回答

一周热门 更多>