380091044 发表于 2024-4-23 14:17:35

CAN功能寄存器配置函数中的疑问点,请哪位老师讲解一下?

//========================================================================
// 函数: void CanWriteReg(u8 addr, u8 dat)
// 描述: CAN功能寄存器配置函数。
// 参数: CAN功能寄存器地址, CAN功能寄存器数据.
// 返回: none.
// 版本: VER1.0
// 日期: 2020-11-16
// 备注:
//========================================================================
void CanWriteReg(u8 addr, u8 dat)
{
        CANAR = addr;
        CANDR = dat;
}

//========================================================================
// 函数: 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)));//读取有效数据;这里(RX_Index++&3)决定了0-3四个数,读不到4-7这几个字节??
    }
    while(RX_Index&3)//判断已读数据长度是否4的整数倍;这里怎么看出来是4整数的??
    {
      CanReadReg((u8)(RX_BUF0 + (RX_Index++&3)));//读取填充数据,一帧数据占据4的整数倍缓冲区空间,不足补0
    }
}

乘风飞扬 发表于 2024-4-23 15:08:56

CAN接收缓冲区里面的内容是通过RXBUF0~RXBUF3四个寄存器循环读取的:

也就是例子里面的 RX_BUF0+0 到 RX_BUF0+3。
所以当 RX_Index&3 不等于0,说明没有读完4的整数倍字节。

380091044 发表于 2024-4-23 16:21:39

乘风飞扬 发表于 2024-4-23 15:08
CAN接收缓冲区里面的内容是通过RXBUF0~RXBUF3四个寄存器循环读取的:

也就是例子里面的 RX_BUF0+0 到 RX_B ...

感谢老师指点,我深入看一下,

380091044 发表于 2024-4-23 17:23:34

乘风飞扬 发表于 2024-4-23 15:08
CAN接收缓冲区里面的内容是通过RXBUF0~RXBUF3四个寄存器循环读取的:

也就是例子里面的 RX_BUF0+0 到 RX_B ...

老师:基本都看懂了,还有一点有疑惑,如下:
CAN模块的RXFIFO是一个64BYTE的FIFO,
在数据量为1个字节的时候,最多能存储21帧数据。//这个64字节与21帧啥关系?
数据8个字节的时候,最多能存储5帧数据。//这个64字节与5帧啥关系?

乘风飞扬 发表于 2024-4-23 17:51:38

380091044 发表于 2024-4-23 17:23
老师:基本都看懂了,还有一点有疑惑,如下:
CAN模块的RXFIFO是一个64BYTE的FIFO,
在数据量为1个字节的 ...

这需要了解一帧报文的内容,如图所示标准帧包含3个字节的信息部分与最多8个字节的数据部分:




一帧报文占用FIFO空间是4的整数倍,所以数据长度为1的数据帧,或者数据长度为0的远程帧都会占用4字节FIFO,64字节FIFO最多可以存放16帧报文。
当数据长度为8的话,加上3字节信息部分,总共11字节,最多只能存放5帧。

380091044 发表于 2024-4-23 19:31:18

乘风飞扬 发表于 2024-4-23 17:51
这需要了解一帧报文的内容,如图所示标准帧包含3个字节的信息部分与最多8个字节的数据部分:




哦哦,是这样,谢谢老师

380091044 发表于 2024-4-24 08:40:27

乘风飞扬 发表于 2024-4-23 17:51
这需要了解一帧报文的内容,如图所示标准帧包含3个字节的信息部分与最多8个字节的数据部分:




老师:
CAN模块的RXFIFO是一个64BYTE的FIFO,//XFIFO是一个64BYTE的FIFO这个我在说明书里面没找到?在哪可以看出来?
在数据量为1个字节的时候,最多能存储21帧数据。//按照你讲解,数据1+3字节共计4字节,64除以4也就16字节,21帧数据哪来的?
页: [1]
查看完整版本: CAN功能寄存器配置函数中的疑问点,请哪位老师讲解一下?