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

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

[复制链接]
  • 打卡等级:常住居民I
  • 打卡总天数:77
  • 最近打卡:2025-04-15 13:59:49

17

主题

61

回帖

575

积分

高级会员

积分
575
发表于 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会不会造成延迟?



回复

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:458
  • 最近打卡:2025-05-01 07:48:22
已绑定手机
已实名认证

110

主题

2219

回帖

5452

积分

版主

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

使用道具 举报 送花

  • 打卡等级:常住居民I
  • 打卡总天数:77
  • 最近打卡:2025-04-15 13:59:49

17

主题

61

回帖

575

积分

高级会员

积分
575
发表于 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
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:458
  • 最近打卡:2025-05-01 07:48:22
已绑定手机
已实名认证

110

主题

2219

回帖

5452

积分

版主

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

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

截图202403182122393952.jpg


回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:321
  • 最近打卡:2025-05-01 21:04:13
已绑定手机

21

主题

487

回帖

1027

积分

金牌会员

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

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

使用道具 举报 送花

  • 打卡等级:常住居民I
  • 打卡总天数:77
  • 最近打卡:2025-04-15 13:59:49

17

主题

61

回帖

575

积分

高级会员

积分
575
发表于 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++);
                         }

                   }

回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:415
  • 最近打卡:2025-04-30 09:58:34
已绑定手机

39

主题

2006

回帖

6841

积分

论坛元老

积分
6841
发表于 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打印数据或者进行分析过程,不会影响数据接收。
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:常住居民I
  • 打卡总天数:77
  • 最近打卡:2025-04-15 13:59:49

17

主题

61

回帖

575

积分

高级会员

积分
575
发表于 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, 2025-5-2 04:14 , Processed in 0.149156 second(s), 98 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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