QW123 发表于 2024-3-15 15:35:01

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

本帖最后由 QW123 于 2024-3-15 15:44 编辑

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

能不能全部定义成:
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 是指一帧数据有0~8个字节
}CAN_DataDef;

CAN_DataDef CAN1_Tx;   
CAN_DataDef CAN1_Rx;
--->这个 CAN1_Rx8是代表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);    //从串口输出收到的数据
                  }
                  printf("\r\n");
                }
            }
      }

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




王昱顺 发表于 2024-3-15 16:47:32

这个can1_rx的意思是可以接受8帧。
至于说的会不会遗漏问题,can内部有fifo,只要不超出fifo就没有问题

QW123 发表于 2024-3-18 21:04:25

本帖最后由 QW123 于 2024-3-18 21:06 编辑

王昱顺 发表于 2024-3-15 16:47
这个can1_rx的意思是可以接受8帧。
至于说的会不会遗漏问题,can内部有fifo,只要不超出fifo就没有问题 ...
你好
谢谢答复
还是有个疑惑
如果这个can1_rx的意思是可以接受8帧
n = CanReadMsg(CAN1_Rx);   返回值 n 表示当前读取的报文个数,存放在CAN1_Rx寄存器里
那也就是说:
当设置成 can1_rx时, n = CanReadMsg(CAN1_Rx);表示一次8帧,一次8帧的从fifo取数据?
那是不是意味着,可以can1_rx,也可以设置成can1_rx,   can1_rx,can1_rx??

王昱顺 发表于 2024-3-18 21:23:03

QW123 发表于 2024-3-18 21:04
你好
谢谢答复
还是有个疑惑


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




llyymm 发表于 2024-3-18 23:50:11

王昱顺 发表于 2024-3-18 21:23
fifo可以缓存64个byte,所以主要看传输的帧长度
不超过这个上限应该是可以改到更多的



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

QW123 发表于 2024-3-19 13:55:54

王昱顺 发表于 2024-3-18 21:23
fifo可以缓存64个byte,所以主要看传输的帧长度
不超过这个上限应该是可以改到更多的




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




是不是可以理解成: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++);
                         }

                   }

乘风飞扬 发表于 2024-3-19 15:55:00

因为CAN模块的发送缓冲区是16字节(只够放一帧报文),接收缓冲区是64字节(可以放多帧报文)。
一帧报文在缓冲区存放占用的空间是4的整数倍字节,例如标准帧总共11个字节,在缓冲区内占用12字节空间;扩展帧总共13个字节,在缓冲区内占用16字节空间。
所以定义发送缓冲区只有一帧:CAN_DataDef CAN1_Tx;
接收缓冲区定义了8帧数据空间:CAN_DataDef CAN1_Rx;
对于大部分应用场景,接收缓冲区定义8帧数据结构已经是够用的了,如果一帧数据很短,64字节可以存放超过8帧报文的话,可以增加CAN1_Rx数组数量。
n = CanReadMsg(CAN1_Rx);将缓冲区内数据一帧帧读取出到CAN1_Rx,其中 n 是当前缓冲区收到的报文帧数。
                for(i=0;i<n;i++)      //帧数
                {
//                  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++)      //当前帧数据长度
                  {
                        printf("0x%02X ",CAN1_Rx.DataBuffer);    //从串口输出收到的数据
                  }
                  printf("\r\n");
                }以上代码是将当前从FIFO读取的报文,一帧帧通过串口打印出来。
报文从FIFO读取到CAN1_Rx后,CAN控制器就可以继续接收新的报文放入FIFO空间,从CAN1_Rx打印数据或者进行分析过程,不会影响数据接收。

QW123 发表于 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 进行打印数据,

这里面是 什么关系啊?串-串,还是串-并?就是住一层,同步打印一层,还是住满八层-再从一层开始打印到八层?
页: [1]
查看完整版本: 有个疑惑:CAN_DataDef CAN1_Tx; CAN_DataDef CAN1_Rx[8]; 有什么区别