找回密码
 立即注册
查看: 554|回复: 11

fifo溢出

[复制链接]
  • TA的每日心情
    奋斗
    7 天前
  • 签到天数: 1 天

    [LV.1]初来乍到

    4

    主题

    9

    回帖

    104

    积分

    注册会员

    积分
    104
    发表于 2023-12-15 23:12:29 | 显示全部楼层 |阅读模式
    你好!请问STC的CAN是如何处理接收缓存溢出错误的,当溢出发生后,新到的报文是丢弃,还是保留(剔除旧报文)?
    回复 送花

    使用道具 举报

  • TA的每日心情
    开心
    5 小时前
  • 签到天数: 133 天

    [LV.7]常住居民III

    37

    主题

    869

    回帖

    3946

    积分

    荣誉版主

    积分
    3946
    发表于 2023-12-16 00:20:48 | 显示全部楼层
    一般接收缓存区采用循环队列, 当溢出发生后,新到的报文是丢弃,旧报文还是有效的, 等待 CPU 读取 .
    回复 支持 反对 送花

    使用道具 举报

  • TA的每日心情
    奋斗
    7 天前
  • 签到天数: 1 天

    [LV.1]初来乍到

    4

    主题

    9

    回帖

    104

    积分

    注册会员

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

    谢谢!
    回复 支持 反对 送花

    使用道具 举报

  • TA的每日心情
    奋斗
    3 小时前
  • 签到天数: 127 天

    [LV.7]常住居民III

    26

    主题

    1280

    回帖

    3983

    积分

    论坛元老

    积分
    3983
    发表于 2023-12-18 17:56:50 | 显示全部楼层
    建议使用最新的STC32G实验箱例程包,屠龙刀例程包里面的CAN总线收发例子试试
    例子可将缓冲区里面的报文一帧帧的读取出来
    1. //========================================================================
    2. // 函数: void CanReadFifo(CAN_DataDef *CANx)
    3. // 描述: 读取CAN缓冲区数据函数。
    4. // 参数: *CANx: 存放CAN总线读取数据.
    5. // 返回: none.
    6. // 版本: VER2.0
    7. // 日期: 2023-01-31
    8. // 备注:
    9. //========================================================================
    10. void CanReadFifo(CAN_DataDef *CAN)
    11. {
    12.     u8 i;
    13.     u8 pdat[5];
    14.     u8 RX_Index=0;
    15.     pdat[0] = CanReadReg((u8)(RX_BUF0 + (RX_Index++&3)));
    16.     if(pdat[0] & 0x80)  //判断是标准帧还是扩展帧
    17.     {
    18.         pdat[1] = CanReadReg((u8)(RX_BUF0 + (RX_Index++&3)));   //扩展帧ID占4个字节
    19.         pdat[2] = CanReadReg((u8)(RX_BUF0 + (RX_Index++&3)));
    20.         pdat[3] = CanReadReg((u8)(RX_BUF0 + (RX_Index++&3)));
    21.         pdat[4] = CanReadReg((u8)(RX_BUF0 + (RX_Index++&3)));
    22.         CAN->ID = (((u32)pdat[1] << 24) + ((u32)pdat[2] << 16) + ((u32)pdat[3] << 8) + pdat[4]) >> 3;
    23.     }
    24.     else
    25.     {
    26.         pdat[1] = CanReadReg((u8)(RX_BUF0 + (RX_Index++&3)));   //标准帧ID占2个字节
    27.         pdat[2] = CanReadReg((u8)(RX_BUF0 + (RX_Index++&3)));
    28.         CAN->ID = ((pdat[1] << 8) + pdat[2]) >> 5;
    29.     }
    30.    
    31.     CAN->FF = pdat[0] >> 7;     //帧格式
    32.     CAN->RTR = pdat[0] >> 6;    //帧类型
    33.     CAN->DLC = pdat[0];         //数据长度
    34.     for(i=0;((i<CAN->DLC) && (i<8));i++)        //读取数据长度为len,最多不超过8
    35.     {
    36.         CAN->DataBuffer[i] = CanReadReg((u8)(RX_BUF0 + (RX_Index++&3)));   //读取有效数据
    37.     }
    38.     while(RX_Index&3)   //判断已读数据长度是否4的整数倍
    39.     {
    40.         CanReadReg((u8)(RX_BUF0 + (RX_Index++&3)));  //读取填充数据,一帧数据占据4的整数倍缓冲区空间,不足补0
    41.     }
    42. }
    43. //========================================================================
    44. // 函数: u8 CanReadMsg(void)
    45. // 描述: CAN接收数据函数。
    46. // 参数: *CANx: 存放CAN总线读取数据.
    47. // 返回: 帧个数.
    48. // 版本: VER2.0
    49. // 日期: 2023-01-31
    50. // 备注:
    51. //========================================================================
    52. u8 CanReadMsg(CAN_DataDef *CAN)
    53. {
    54.     u8 i;
    55.     u8 n=0;
    56.     do{
    57.         CanReadFifo(&CAN[n++]);  //读取接收缓冲区数据
    58.         i = CanReadReg(SR);
    59.     }while(i&0x80);     //判断接收缓冲区里是否还有数据,有的话继续读取
    60.     return n;   //返回帧个数
    61. }
    复制代码
    回复 支持 反对 送花

    使用道具 举报

  • TA的每日心情
    奋斗
    7 天前
  • 签到天数: 1 天

    [LV.1]初来乍到

    4

    主题

    9

    回帖

    104

    积分

    注册会员

    积分
    104
     楼主| 发表于 2023-12-19 13:54:53 | 显示全部楼层
    谢谢,版主的及时回复,手册上例程的影响,8字节标准帧一帧收取了16个字节。改为12个字节,就解决了。
    回复 支持 反对 送花

    使用道具 举报

  • TA的每日心情
    奋斗
    6 天前
  • 签到天数: 42 天

    [LV.5]常住居民I

    14

    主题

    53

    回帖

    386

    积分

    中级会员

    积分
    386
    发表于 2024-3-4 14:21:06 | 显示全部楼层
    njrdxdz 发表于 2023-12-19 13:54
    谢谢,版主的及时回复,手册上例程的影响,8字节标准帧一帧收取了16个字节。改为12个字节,就解决了。 ...

    具体改的是哪个,方便说下不,让小白学习下
    回复 支持 反对 送花

    使用道具 举报

  • TA的每日心情
    开心
    昨天 23:10
  • 签到天数: 46 天

    [LV.5]常住居民I

    15

    主题

    221

    回帖

    1157

    积分

    金牌会员

    积分
    1157
    发表于 2024-3-19 12:39:23 | 显示全部楼层
    njrdxdz 发表于 2023-12-19 13:54
    谢谢,版主的及时回复,手册上例程的影响,8字节标准帧一帧收取了16个字节。改为12个字节,就解决了。 ...

    经验应该和大家一起分享一下吧!能否把改动点说下?我们也学习一下
    回复 支持 反对 送花

    使用道具 举报

  • TA的每日心情
    奋斗
    6 天前
  • 签到天数: 42 天

    [LV.5]常住居民I

    14

    主题

    53

    回帖

    386

    积分

    中级会员

    积分
    386
    发表于 2024-3-20 20:33:48 | 显示全部楼层
    llyymm 发表于 2024-3-19 12:39
    经验应该和大家一起分享一下吧!能否把改动点说下?我们也学习一下

    直觉是楼主写成扩展帧了,
    回复 支持 反对 送花

    使用道具 举报

  • TA的每日心情
    奋斗
    7 天前
  • 签到天数: 1 天

    [LV.1]初来乍到

    4

    主题

    9

    回帖

    104

    积分

    注册会员

    积分
    104
     楼主| 发表于 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,多读取了一轮(按照四轮一帧读取)。
    回复 支持 反对 送花

    使用道具 举报

  • TA的每日心情
    奋斗
    6 天前
  • 签到天数: 42 天

    [LV.5]常住居民I

    14

    主题

    53

    回帖

    386

    积分

    中级会员

    积分
    386
    发表于 2024-3-27 15:55:20 | 显示全部楼层
    njrdxdz 发表于 2024-3-25 17:53
    接受一帧扩展帧,为13个有效字节,包括5个字节的帧ID和8个字节的数据,完全获取,需要通过读取4字节的CAN数 ...

    意思就是,读四轮为一组判断,刚好可以按扩展帧格式去解析?, 读三轮为一组判断,刚好可以按标准帧去解析??
    回复 支持 反对 送花

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

    GMT+8, 2024-4-29 12:13 , Processed in 0.072669 second(s), 64 queries .

    Powered by Discuz! X3.5

    © 2001-2024 Discuz! Team.

    快速回复 返回顶部 返回列表