njrdxdz 发表于 2023-12-15 23:12:29

fifo溢出

你好!请问STC的CAN是如何处理接收缓存溢出错误的,当溢出发生后,新到的报文是丢弃,还是保留(剔除旧报文)?

LAOXU 发表于 2023-12-16 00:20:48

一般接收缓存区采用循环队列, 当溢出发生后,新到的报文是丢弃,旧报文还是有效的, 等待 CPU 读取 .

njrdxdz 发表于 2023-12-17 15:51:02

哦,谢谢!追问:
1、如何释放已经装满的,溢出的RX_FIFO?是不是只能靠读取?
2、假如64byte的FIFO已溢出,如何读取其中的报文,按照手册的描述,报文的存储位置是连续的,而读取的方式是4个字节的倍数。对FIFO中的第二、第三个报文,如何读取喃?
3上述问题,是基于在我们的开发中,当报文密集发送,接收端无法及时收取(非中断下收取),造成FIFO溢出,其后再收取时,收到的数据出错,感觉FIFO中的数据错乱了。

谢谢!

乘风飞扬 发表于 2023-12-18 17:56:50

建议使用最新的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;   //返回帧个数
}

njrdxdz 发表于 2023-12-19 13:54:53

谢谢,版主的及时回复,手册上例程的影响,8字节标准帧一帧收取了16个字节。改为12个字节,就解决了。

QW123 发表于 2024-3-4 14:21:06

njrdxdz 发表于 2023-12-19 13:54
谢谢,版主的及时回复,手册上例程的影响,8字节标准帧一帧收取了16个字节。改为12个字节,就解决了。 ...

具体改的是哪个,方便说下不,让小白学习下{:4_197:}

llyymm 发表于 2024-3-19 12:39:23

njrdxdz 发表于 2023-12-19 13:54
谢谢,版主的及时回复,手册上例程的影响,8字节标准帧一帧收取了16个字节。改为12个字节,就解决了。 ...

经验应该和大家一起分享一下吧!能否把改动点说下?我们也学习一下

QW123 发表于 2024-3-20 20:33:48

llyymm 发表于 2024-3-19 12:39
经验应该和大家一起分享一下吧!能否把改动点说下?我们也学习一下

直觉是楼主写成扩展帧了,

njrdxdz 发表于 2024-3-25 17:53:44

本帖最后由 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,多读取了一轮(按照四轮一帧读取)。

QW123 发表于 2024-3-27 15:55:20

njrdxdz 发表于 2024-3-25 17:53
接受一帧扩展帧,为13个有效字节,包括5个字节的帧ID和8个字节的数据,完全获取,需要通过读取4字节的CAN数 ...

意思就是,读四轮为一组判断,刚好可以按扩展帧格式去解析?, 读三轮为一组判断,刚好可以按标准帧去解析??
页: [1] 2
查看完整版本: fifo溢出