本帖最后由 梅川酷子 于 2019-5-17 21:07 编辑
在使用FD CAN的时候,出现了一系列莫名其妙的问题.希望能得到大神们的帮助,非常感谢~
1.内环模式:
发送不成功,第2次发送会进入发送FIFO满的错误。
接收不到自发送的报文。
2.外环模式:
情况跟内环模式一样,但是实际上和H750相连的USB/CAN已经成功接收到报文,示波器上也有相应的波形出现。
H750在不断地重试,而实际上我代码只发送了一次。
3.正常模式:
外部USB/CAN会接收到重复的报文,也就是说,有时一次可发送成功,有时需要两三次重试。
下图我发了三次,间隔几秒,但是,你可以从时间戳看到,序号为3和4的报文是重试的。
接收也类似,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);
}
一周热门 更多>