fifo溢出
你好!请问STC的CAN是如何处理接收缓存溢出错误的,当溢出发生后,新到的报文是丢弃,还是保留(剔除旧报文)? 一般接收缓存区采用循环队列, 当溢出发生后,新到的报文是丢弃,旧报文还是有效的, 等待 CPU 读取 . 哦,谢谢!追问:1、如何释放已经装满的,溢出的RX_FIFO?是不是只能靠读取?
2、假如64byte的FIFO已溢出,如何读取其中的报文,按照手册的描述,报文的存储位置是连续的,而读取的方式是4个字节的倍数。对FIFO中的第二、第三个报文,如何读取喃?
3上述问题,是基于在我们的开发中,当报文密集发送,接收端无法及时收取(非中断下收取),造成FIFO溢出,其后再收取时,收到的数据出错,感觉FIFO中的数据错乱了。
谢谢! 建议使用最新的STC32G实验箱例程包,屠龙刀例程包里面的CAN总线收发例子试试
例子可将缓冲区里面的报文一帧帧的读取出来
//========================================================================
// 函数: void CanReadFifo(CAN_DataDef *CANx)
// 描述: 读取CAN缓冲区数据函数。
// 参数: *CANx: 存放CAN总线读取数据.
// 返回: none.
// 版本: VER2.0
// 日期: 2023-01-31
// 备注:
//========================================================================
void CanReadFifo(CAN_DataDef *CAN)
{
u8 i;
u8 pdat;
u8 RX_Index=0;
pdat = CanReadReg((u8)(RX_BUF0 + (RX_Index++&3)));
if(pdat & 0x80)//判断是标准帧还是扩展帧
{
pdat = CanReadReg((u8)(RX_BUF0 + (RX_Index++&3))); //扩展帧ID占4个字节
pdat = CanReadReg((u8)(RX_BUF0 + (RX_Index++&3)));
pdat = CanReadReg((u8)(RX_BUF0 + (RX_Index++&3)));
pdat = CanReadReg((u8)(RX_BUF0 + (RX_Index++&3)));
CAN->ID = (((u32)pdat << 24) + ((u32)pdat << 16) + ((u32)pdat << 8) + pdat) >> 3;
}
else
{
pdat = CanReadReg((u8)(RX_BUF0 + (RX_Index++&3))); //标准帧ID占2个字节
pdat = CanReadReg((u8)(RX_BUF0 + (RX_Index++&3)));
CAN->ID = ((pdat << 8) + pdat) >> 5;
}
CAN->FF = pdat >> 7; //帧格式
CAN->RTR = pdat >> 6; //帧类型
CAN->DLC = pdat; //数据长度
for(i=0;((i<CAN->DLC) && (i<8));i++) //读取数据长度为len,最多不超过8
{
CAN->DataBuffer = CanReadReg((u8)(RX_BUF0 + (RX_Index++&3))); //读取有效数据
}
while(RX_Index&3) //判断已读数据长度是否4的整数倍
{
CanReadReg((u8)(RX_BUF0 + (RX_Index++&3)));//读取填充数据,一帧数据占据4的整数倍缓冲区空间,不足补0
}
}
//========================================================================
// 函数: u8 CanReadMsg(void)
// 描述: CAN接收数据函数。
// 参数: *CANx: 存放CAN总线读取数据.
// 返回: 帧个数.
// 版本: VER2.0
// 日期: 2023-01-31
// 备注:
//========================================================================
u8 CanReadMsg(CAN_DataDef *CAN)
{
u8 i;
u8 n=0;
do{
CanReadFifo(&CAN);//读取接收缓冲区数据
i = CanReadReg(SR);
}while(i&0x80); //判断接收缓冲区里是否还有数据,有的话继续读取
return n; //返回帧个数
}
谢谢,版主的及时回复,手册上例程的影响,8字节标准帧一帧收取了16个字节。改为12个字节,就解决了。 njrdxdz 发表于 2023-12-19 13:54
谢谢,版主的及时回复,手册上例程的影响,8字节标准帧一帧收取了16个字节。改为12个字节,就解决了。 ...
具体改的是哪个,方便说下不,让小白学习下{:4_197:} njrdxdz 发表于 2023-12-19 13:54
谢谢,版主的及时回复,手册上例程的影响,8字节标准帧一帧收取了16个字节。改为12个字节,就解决了。 ...
经验应该和大家一起分享一下吧!能否把改动点说下?我们也学习一下 llyymm 发表于 2024-3-19 12:39
经验应该和大家一起分享一下吧!能否把改动点说下?我们也学习一下
直觉是楼主写成扩展帧了, 本帖最后由 njrdxdz 于 2024-3-28 14:51 编辑
接受一帧扩展帧,为13个有效字节,包括5个字节的帧ID和8个字节的数据,完全获取,需要通过读取4字节的CAN数据接收缓存RXBUF0~RXBUF4,共四轮才能完成,即相当于16个字节(多余3个可以丢弃,读取剩余字节的目的,在于复位RXBUFn指针至RXBUF0,以便下一个新帧的读取)
而对于包含有8个字节的标准帧,因其帧ID只包含3个字节,故该标准帧的有效字节数为11个,也就是通过CAN数据接收缓存RXBUF0~RXBUF4的读取,只需要3轮即可,共读取12个字节。
之前的错误是在接收标准数据帧时,对CAN数据接收缓存RXBUF0~RXBUF4,多读取了一轮(按照四轮一帧读取)。 njrdxdz 发表于 2024-3-25 17:53
接受一帧扩展帧,为13个有效字节,包括5个字节的帧ID和8个字节的数据,完全获取,需要通过读取4字节的CAN数 ...
意思就是,读四轮为一组判断,刚好可以按扩展帧格式去解析?, 读三轮为一组判断,刚好可以按标准帧去解析??
页:
[1]
2