MCU:AC78013FDLA
CAN Transfer TJA1042
AC78013FDLA CAN-CTRL 内核描述
支持 CAN 规格
−
CAN 2.0A/B (最多 8 个字节的有效载荷,经 Bosch 参考模型验证)
−
对 CAN FD 的可选支持
(最多 64 字节的有效载荷,ISO 11898-1:2015 或者 非 ISO Bosch)
可编程的比特率
−
CAN 2.0B 支持最高 1Mbit/s
−
CAN FD 支持最高 8Mbit/s(受收发器和所选择的 CAN-CTRL 内核时钟频率的限制)
−
可选择 AHB 分频时钟或者外部振荡器时钟
可编程波特率预分频器(1 至 1/256)
1 个接收缓冲区,FIFO 深度为 7
两个发送缓冲区:
−
主发送缓冲区 (PTB) FIFO 深度为 1
−
次发送缓冲区 (STB) FIFO 深度为 3,按 FIFO 或优先级决定数据帧发送的先后顺序
16 个独立可编程的内部 29 位接收滤波器
扩展特性:
−
单次发送模式 (PTB 和 STB 都支持)
−
监听模式
−
回环模式 (内部、外部)
−
收发器待机模式
扩展状态和错误报告:
−
捕获最后发生错误的类型和仲裁丢失的位置
−
可编程错误警告限制
可配置的中断资源
时间戳
− CiA 603 时间戳
带集成式低通滤波器的唤醒功能
调试过程:
1.正常发送接收
2.发送过程中使STB引脚拉高
3.正常工作过程中CANH接地、CANL接地
4.正常发送过程中CANH、CANL短路
CAN初始化代码
/*
设置采样点在81.25%
tseg1 = (S_SEG1 +2);
tseg2 = (S_SEG2+1);
BandRate = (48M/(S_PRESC +1) / ((S_SEG1+2)+(S_SEG2+1))))
SamplePoint = (tseg1 /(tseg1 + tseg2));
*/
void SocCanPerhInit(void)
{
CAN_ConfigType canConfig;
CAN_BitrateConfigType canBandrateConfig;
memset((void *)&canConfig, 0, (uint32_t)sizeof(CAN_ConfigType));
memset((void *)&canBandrateConfig, 0, sizeof(CAN_BitrateConfigType));
GPIO_SetFunc(SPORT_GPIOCANTX,SPIN_GPIOCANTX, GPIO_FUN1);
GPIO_SetFunc(SPORT_GPIOCANRX,SPIN_GPIOCANRX, GPIO_FUN1);
GPIO_SetFunc(CAN0_STB, GPIO_FUN0);
GPIO_SetDir(CAN0_STB, GPIO_OUT);
CAN0_TRASCVER_NML;
GPIO_SetPinLevel(CAN0_STB, GPIO_LEVEL_LOW);
canBandrateConfig.PRESC = 5;
canBandrateConfig.SEG_1 = 11;
canBandrateConfig.SEG_2 = 2;
canBandrateConfig.SJW = 2;
canConfig.interruptEn = ENABLE;
canConfig.interruptMask = CAN_IRQ_ALL_ENABLE_MSK;
canConfig.canMode = CAN_MODE_NORMAL;
canConfig.clockSrc = CAN_CLKSRC_AHB;
canConfig.tpss = ENABLE;
canConfig.tsss = ENABLE;
canConfig.filterNum = 3;
canConfig.filterList = canFilterControl; //过滤器设置
canConfig.callback = CAN0_IRQnCallBack;
canConfig.normalBitrate = &canBandrateConfig;
g_sendCANMsgInfo.DATA = (uint8_t *)sendDataBuff;
g_recvCANMsgInfo.DATA = (uint8_t *)recvDataBuff;
CAN_Init(CAN0, &canConfig);
}
//CAN 报文发送函数
uint8_t SocCANSendMsg(uint32_t ID,uint8_t IDE,uint8_t RTR,uint8_t *pDataBuf,uint8_t dataLen)
{
uint8_t ret = 0;
g_sendCANMsgInfo.ID = ID;
g_sendCANMsgInfo.IDE = IDE;
g_sendCANMsgInfo.DLC = dataLen;
memcpy(g_sendCANMsgInfo.DATA, pDataBuf, dataLen);
ret = CAN_TransmitMessage(CAN0, &g_sendCANMsgInfo, CAN_TRANSMIT_SECONDARY);//·¢?íêy?Y
return ret;
}
实验1:正常发送接收
第一次烧录软件之后在接收端并没有看到报文数据,后来排查发现TJA1042引脚被置H,非工作状态。拉低后正常发送接收端能看到具体报文。
接收测试
CAN_FilterControlType canFilterControl[]=
{
{0, ENABLE, 0x00000400, 0x00000000},
{1, ENABLE, CARBCMLIGHTCOMMANDID, 0x00000000}, //只允许指定 ID 通过
{2, ENABLE, 0x00000001, 0x0000000F},
};
代码中设置了3组滤波器,其中0,1都是强制必须指定ID才可以接收,过滤器2中科通过ID为0x1~0xF
typedef struct
{
uint8_t index; /*!< Filter index */
ACTION_Type enable; /*!< Enable or disable */
uint32_t code; /*!< Code data */
uint32_t mask; /*!< Mask data */
} CAN_FilterControlType;
t_mask 对应的bit位为0表示强制匹配,为1表示不要求一致
接收中断函数
void CAN0_IRQnCallBack(void *device, uint32_t wpara, uint32_t lpara)
{
if (wpara & CAN_CTRL1_EIF_Msk) ///<error happened
{
if (((CAN_Type*)device)->CTRL0 & CAN_CTRL0_BUSOFF_Msk)
{
#if(SUPPORT_SOCCANDEBUG)
printf("CAN BUSS OFF\r\n");
#endif
}
}
if (wpara & CAN_CTRL1_RIF_Msk)
{
if (CAN_IsMsgInReceiveBuf((CAN_Type*)device))
{
CAN_ReceiveMessage((CAN_Type*)device, &g_recvCANMsgInfo);
BspCANCopyData();
AppCanQInsertMsg(g_recvCANMsgBuf);
}
}
}
2.发送过程中STB引脚拉高
int32_t CAN_TransmitMessage(CAN_Type *CANx, const CAN_MsgInfoType *info, CAN_TransmitBufferType type);
函数正常情况下,发送成功返回0
STB引脚置高之后,
测试过程中发现每隔15S左右会触发一次BUSOFF标志位置位,但是发送标记位一直显示为0
撤掉异常之后发送恢复正常
3.正常工作过程中CANH、CANL接地
测试发现CANH接地能触发BUSOFF,CANL接地不会触发BUSOFF,两种情况下均不能接收到CAN报文
4.CANH、CANL短路
会触发CANBUSOFF。
以上所有触发BUSOFF的情况发送函数的返回值ret都为0,但是实际上并没有发送成功,这个下一期验证一下返回值一直为0的原因
|