【简介】
CAN 在汽车电子的应用中是不可避免的,本次我们基于S32K3的芯片来使用对应的CAN IP 的功能配置,本地的硬件环境如下:

收发器使用的 TJA1048 连接了两路CAN 本次试验我们使用PTA7/PTA6 这组CAN0接口来熟悉K3的CAN模块的配置。以下是TJA1048 的功能概述可知该收发器支持CAN/CANFD 的模式。

【IO MUX配置】
根据原理图配置PTA6/PTA7 为CAN0 功能。

【CAN 参数配置】
IO 配置完成后我们就可以进行CAN 通讯参数配置了,CAN 的 波特率的配置需要依赖时钟参数的配置,本地的CAN0 的时钟配置为40M.

本地配置Flexcan 的工作参数,本地配置为CAN FD模式,对应配置如下:

生成代码后如下的CAN驱动配置代码会被加入工程。

Can 总线参数配置完成后,我们添加如下代码来初始化CAN 总线。
static int can_init(void)
{
Flexcan_Ip_StatusType ret;
ret = FlexCAN_Ip_Init(INST_FLEXCAN_0, &FlexCAN_State0, &FlexCAN_Config0);
if(ret != FLEXCAN_STATUS_SUCCESS)
{
LOG_E("FlexCAN0 init failed %x.", ret);
}
else
{
LOG_I("FlexCAN0 init OK.");
}
ret = FlexCAN_Ip_ConfigEnhancedRxFifo_Privileged(INST_FLEXCAN_0, &CAN0_EnhanceFIFO_IdFilterTable[0]);
if(ret != FLEXCAN_STATUS_SUCCESS)
{
LOG_E("FlexCAN0 Enhanced RX FIFO config failed %x.", ret);
}
else
{
LOG_I("FlexCAN0 Enhanced RX FIFO config OK.");
}
/* enable flex can module */
ret = FlexCAN_Ip_SetStartMode(INST_FLEXCAN_0);
if(FLEXCAN_STATUS_SUCCESS != ret)
{
LOG_E("FlexCAN0 start failed %d.", (int)ret);
}
else
{
LOG_I("FlexCAN0 start OK.");
}
/* Enable FIFO */
FlexCAN_Ip_RxFifo(INST_FLEXCAN_0, &rxFifoData);
return 1;
}添加对应的中断回调函数代码如下:
void flexcan0_Callback(uint8 instance,
Flexcan_Ip_EventType eventType,
uint32 buffIdx,
const Flexcan_Ip_StateType *flexcanState)
{
PRINTF("FlexCAN0 Callback: instance=%d, eventType=%d, buffIdx=%ld\n", instance, eventType, buffIdx);
switch(eventType)
{
case FLEXCAN_EVENT_RX_COMPLETE:
/* Handle RX complete event */
break;
case FLEXCAN_EVENT_RXFIFO_COMPLETE:
/* Handle RX FIFO complete event */
break;
case FLEXCAN_EVENT_TX_COMPLETE:
/* Handle TX complete event */
break;
case FLEXCAN_EVENT_ENHANCED_RXFIFO_COMPLETE:
/* Handle Enhanced RX FIFO complete event */
FlexCAN_Ip_RxFifo(INST_FLEXCAN_0, &rxFifoData);
PRINTF("Enhanced RX FIFO Data: ID=0x%lX, DataLen=%d, Data=", rxFifoData.msgId, rxFifoData.dataLen);
trace_byte_stream((uint32_t *)rxFifoData.data, rxFifoData.dataLen, 0);
break;
default:
break;
}
}
添加如下测试代码发送can/can fd 帧。
unsigned int can(char argc, char **argv)
{
Flexcan_Ip_DataInfoType dataInfo =
{
.msg_id_type = FLEXCAN_MSG_ID_STD,
.data_length = 64,
.fd_enable = true,//.fd_enable = false, x1231
.fd_padding = 0U,
.enable_brs = true,//.enable_brs = false, x1231
.is_remote = false,
.is_polling = false
};
Flexcan_Ip_DataInfoType dataInfo2 =
{
.msg_id_type = FLEXCAN_MSG_ID_STD,
.data_length = 8,
.fd_enable = false,//.fd_enable = false, x1231
.fd_padding = 0U,
.enable_brs = false,//.enable_brs = false, x1231
.is_remote = false,
.is_polling = false
};
static uint8_t buff_can[8] = {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07};
static uint8_t mb_id = 00;
static uint8_t mb_fd_id = 00;
static uint8_t buff_canfd[64] = {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07};
if((argc == 2) && (strcmp(argv[1],"send") == 0))
{
FlexCAN_Ip_Send(INST_FLEXCAN_0,mb_id++%10,&dataInfo2,0x320,buff_can);
FlexCAN_Ip_Send(INST_FLEXCAN_0,(mb_fd_id++%10) + 10,&dataInfo,0x330,buff_canfd);
}
if((argc ==3) && (strcmp(argv[1],"send") == 0))
{
uint8_t id = myatoi(argv[2]);
FlexCAN_Ip_Send(INST_FLEXCAN_0,id,&dataInfo,0x330,buff_canfd);
}
return 0;
}调用上述代码can 消息已经按照预期发送的can 总线上。

通过CAN 盒发送消息接收中断函数打印色的 CAN 信息和CAN 盒子发送的消息也是匹配的。

我要赚赏金
