找回密码
 立即注册
查看: 161|回复: 7

有个疑惑:CAN_DataDef CAN1_Tx; CAN_DataDef CAN1_Rx[8]; 有什么区别

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

    [LV.5]常住居民I

    14

    主题

    53

    回帖

    386

    积分

    中级会员

    积分
    386
    发表于 2024-3-15 15:35:01 | 显示全部楼层 |阅读模式
    本帖最后由 QW123 于 2024-3-15 15:44 编辑

    如题:
    按初始化设置来说
    发送是,
    DataBuffer[0]~DataBuffer[7]
    接收是
    DataBuffer[0]~DataBuffer[7]
    那 结构体,这样定义   CAN_DataDef CAN1_Tx;      CN_DataDef CAN1_Rx[8];   该如何理解?

    能不能全部定义成:
    CAN_DataDef CAN1_Tx;      CN_DataDef CAN1_Rx;
    或者
    CAN_DataDef CAN1_Tx【8】;      CN_DataDef CAN1_Rx【8】;

    又或者其他标记名?

    求老师指点一下,谢谢

    例程程序框架是如下定义的:
    typedef struct
    {
            u8        DLC:4;          //数据长度, bit0~bit3
            u8        :2;             //空数据, bit4~bit5
            u8        RTR:1;          //帧类型, bit6
            u8        FF:1;           //帧格式, bit7
            u32        ID;             //CAN ID
            u8        DataBuffer[8];  //数据缓存--> 这里的8 是指  一帧数据有0~8个字节
    }CAN_DataDef;

    CAN_DataDef CAN1_Tx;     
    CAN_DataDef CAN1_Rx[8];
    --->这个
    CAN1_Rx[8]  8是代表8帧呢? 还是8个字节?
    ........
    void main(void)
    {   
        u8 i,j,n,sr;  
    ........
    if(B_Can1Read)//如果标志为1,即确认CAN1缓存收到数据
            {
                B_Can1Read = 0; //标志清0
                CANSEL = 0;         //选择CAN1模块
                n = CanReadMsg(CAN1_Rx);  
                if(n>0)
                {
                    for(i=0;i<n;i++)   
    --->从下往上推,理解成数据帧的数量,结合上面,是8帧一组判断??可改动??

                    {
                    // CanSendMsg(&CAN1_Rx);  //CAN总线原样返回

                        printf("CAN1:ID=0x%08lX DLC=%d FF=%d RTR=%d ",CAN1_Rx
    .ID,CAN1_Rx.DLC,CAN1_Rx.FF,CAN1_Rx.RTR);   
    //串口打印帧信息
                       for(j=0;j<CAN1_Rx.DLC;j++)
    --> 从这里看,J 根据 DLC, 是8个data,那应该是8个字节

                        {
                            printf("0x%02X ",CAN1_Rx.DataBuffer[j]);    //从串口输出收到的数据
                        }
                        printf("\r\n");

                    }
                }
            }

    补充:
    如果
    需求发送端中需要上电先保持发送M帧,等待稳定,。那接收端这for 循环会不会遗漏啊?
    又或者只需判断K帧,不需要N帧,这for会不会造成延迟?



    回复 送花

    使用道具 举报

  • TA的每日心情
    开心
    昨天 07:37
  • 签到天数: 103 天

    [LV.6]常住居民II

    31

    主题

    383

    回帖

    1926

    积分

    荣誉版主

    积分
    1926
    发表于 2024-3-15 16:47:32 | 显示全部楼层
    这个can1_rx[8]的意思是可以接受8帧。
    至于说的会不会遗漏问题,can内部有fifo,只要不超出fifo就没有问题
    回复 支持 反对 送花

    使用道具 举报

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

    [LV.5]常住居民I

    14

    主题

    53

    回帖

    386

    积分

    中级会员

    积分
    386
     楼主| 发表于 2024-3-18 21:04:25 | 显示全部楼层
    本帖最后由 QW123 于 2024-3-18 21:06 编辑
    王昱顺 发表于 2024-3-15 16:47
    这个can1_rx[8]的意思是可以接受8帧。
    至于说的会不会遗漏问题,can内部有fifo,只要不超出fifo就没有问题 ...

    你好
    谢谢答复
    还是有个疑惑
    如果这个can1_rx[8]的意思是可以接受8帧
    n = CanReadMsg(CAN1_Rx);   返回值 n 表示当前读取的报文个数,存放在CAN1_Rx寄存器里
    那也就是说:
    当设置成 can1_rx[8]时, n = CanReadMsg(CAN1_Rx);  表示一次8帧,一次8帧的从fifo取数据?
    那是不是意味着,可以can1_rx[2],也可以设置成can1_rx[4],   
    can1_rx[16],  can1_rx[64]??

    点评

    fifo可以缓存64个byte,所以主要看传输的帧长度 不超过这个上限应该是可以改到更多的 [attachimg]38762[/attachimg]  详情 回复 发表于 2024-3-18 21:23
    回复 支持 反对 送花

    使用道具 举报

  • TA的每日心情
    开心
    昨天 07:37
  • 签到天数: 103 天

    [LV.6]常住居民II

    31

    主题

    383

    回帖

    1926

    积分

    荣誉版主

    积分
    1926
    发表于 2024-3-18 21:23:03 | 显示全部楼层
    QW123 发表于 2024-3-18 21:04
    你好
    谢谢答复
    还是有个疑惑

    fifo可以缓存64个byte,所以主要看传输的帧长度
    不超过这个上限应该是可以改到更多的

    截图202403182122393952.jpg


    回复 支持 反对 送花

    使用道具 举报

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

    [LV.5]常住居民I

    15

    主题

    221

    回帖

    1157

    积分

    金牌会员

    积分
    1157
    发表于 2024-3-18 23:50:11 | 显示全部楼层
    王昱顺 发表于 2024-3-18 21:23
    fifo可以缓存64个byte,所以主要看传输的帧长度
    不超过这个上限应该是可以改到更多的

    请问我怎样才能测试这个功能呢?比如使用STC32试验箱的“51-CAN1-CAN2总线标准帧扩展帧同时使用收发测试”例程,每帧数据按照8个字节发送,我想让发送端发送三次或四次后,STC接收后再一次性的把接收的数据返回来?(主要是想测试fifo的用法,我按照自己的理解,把CAN的接收发送放到一秒延时里,模拟单片机未及时处理的状态,结果连续发送三帧数据,但只能返回最后一帧的的数据,另外两帧数据居然没了!)
    回复 支持 反对 送花

    使用道具 举报

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

    [LV.5]常住居民I

    14

    主题

    53

    回帖

    386

    积分

    中级会员

    积分
    386
     楼主| 发表于 2024-3-19 13:55:54 | 显示全部楼层
    王昱顺 发表于 2024-3-18 21:23
    fifo可以缓存64个byte,所以主要看传输的帧长度
    不超过这个上限应该是可以改到更多的

    截图202403191324362648.jpg
    像下面的数据,其实有用的数据,就是BYTE0 , 后面BYTE1-BYTE7 ,都是空的,


    截图202403191333243185.jpg

    是不是可以理解成:FIFO存储的时候,这样的一窜 8 BYTE  数据  ,一次性是存了五帧? ?

    (规格书说:数据 8个 BYTE 的时候,fifo最多能存储5帧数据)



    那RX_BUFF在读取的时候,需要循环读取16次?? 这读取次数可控吗??
    (规格书说:接收一帧数据需要循环读取 RXBUF四次??这是最多四次??还是至少四次??)

    因为车上要求挺高的,都是精准到几帧几帧的信号,不同的ECU相互之间如果差几帧,累计时间差, 就有BUG了。

    不知道有没有老师知道,屠龙刀如何精准读帧?

    现在框架是循环的。论坛里也看了,有人动了会丢帧
    if(n>0)
                        {
                            for(i=0;i<n;i++)
                            {

       for(j=0;j<CANx_Rx.DLC;j++);
                             }

                       }

    回复 支持 反对 送花

    使用道具 举报

  • TA的每日心情
    奋斗
    昨天 08:54
  • 签到天数: 126 天

    [LV.7]常住居民III

    26

    主题

    1276

    回帖

    3971

    积分

    论坛元老

    积分
    3971
    发表于 2024-3-19 15:55:00 | 显示全部楼层
    因为CAN模块的发送缓冲区是16字节(只够放一帧报文),接收缓冲区是64字节(可以放多帧报文)。
    一帧报文在缓冲区存放占用的空间是4的整数倍字节,例如标准帧总共11个字节,在缓冲区内占用12字节空间;扩展帧总共13个字节,在缓冲区内占用16字节空间。
    所以定义发送缓冲区只有一帧:CAN_DataDef CAN1_Tx;
    接收缓冲区定义了8帧数据空间:CAN_DataDef CAN1_Rx[8];
    对于大部分应用场景,接收缓冲区定义8帧数据结构已经是够用的了,如果一帧数据很短,64字节可以存放超过8帧报文的话,可以增加CAN1_Rx数组数量。
    1. n = CanReadMsg(CAN1_Rx);
    复制代码
    将缓冲区内数据一帧帧读取出到CAN1_Rx,其中 n 是当前缓冲区收到的报文帧数。
    1.                 for(i=0;i<n;i++)        //帧数
    2.                 {
    3. //                    CanSendMsg(&CAN1_Rx[i]);  //CAN总线原样返回
    4.                     printf("CAN1:ID=0x%08lX DLC=%d FF=%d RTR=%d ",CAN1_Rx[i].ID,CAN1_Rx[i].DLC,CAN1_Rx[i].FF,CAN1_Rx[i].RTR);   //串口打印帧信息
    5.                     for(j=0;j<CAN1_Rx[i].DLC;j++)        //当前帧数据长度
    6.                     {
    7.                         printf("0x%02X ",CAN1_Rx[i].DataBuffer[j]);    //从串口输出收到的数据
    8.                     }
    9.                     printf("\r\n");
    10.                 }
    复制代码
    以上代码是将当前从FIFO读取的报文,一帧帧通过串口打印出来。
    报文从FIFO读取到CAN1_Rx后,CAN控制器就可以继续接收新的报文放入FIFO空间,从CAN1_Rx打印数据或者进行分析过程,不会影响数据接收。
    回复 支持 反对 送花

    使用道具 举报

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

    [LV.5]常住居民I

    14

    主题

    53

    回帖

    386

    积分

    中级会员

    积分
    386
     楼主| 发表于 2024-3-19 17:01:19 | 显示全部楼层
    乘风老师
    我捋一捋哈
    不知道是不是这样理解
    前提:
    接收缓冲区是 开辟了 8帧空间 ,比方是8层楼,每层16个房间?  
    那每层可以可以放一帧标准帧报文(需要12个房间),或者 一帧扩展帧报文(需要16个房间)

    n = CanReadMsg(CAN1_Rx);
    就表示,从FIFO取人安置在这8层楼? 一层一层的装人?
    for(i=0;i<n;i++)  {}
    就表示,打印每层个人信息?


    那这,从报文从FIFO读取送到CAN1_Rx,与接着  从CAN1_Rx 进行打印数据,

    这里面  是 什么关系啊?  串-串,还是串-并?  就是住一层,同步打印一层,还是  住满八层-再从一层开始打印到八层?
    回复 支持 反对 送花

    使用道具 举报

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

    本版积分规则

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

    GMT+8, 2024-4-29 07:40 , Processed in 0.069107 second(s), 60 queries .

    Powered by Discuz! X3.5

    © 2001-2024 Discuz! Team.

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