张三丰 发表于 2025-7-30 14:40:51

我不是用CAN工具软件对我的产品测出现这个问题的,是实际两个产品之间,我用STC写的程序的这个产品收不到对方传来的数据,我用CAN分析仪测,才发现是帧ID 影响的收不到数据了

张三丰 发表于 2025-7-30 14:45:08

我的程序完全是按照例程写的,所以其实和例程一样
接收程序:
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)));   //读取有效数据
    }
    while(RX_Index&3)   //判断已读数据长度是否4的整数倍
    {
      CanReadReg((u8)(RX_BUF0 + (RX_Index++&3)));//读取填充数据,一帧数据占据4的整数倍缓冲区空间,不足补0
    }
}

初始化设置:
void CANSetBaudrate()
{
          //CanWriteReg(BTR0,(SJW << 6) + BRP);
          //CanWriteReg(BTR1,(SAM << 7) + (TSG2 << 4) + TSG1);
          CanWriteReg(MR, 0x04);                //使能Reset模式
                CanWriteReg(BTR0, 0x2f);        //SJW(0), BRP(47)
                CanWriteReg(BTR1, 0xff);        //SAM(0), TSG2(7), TSG1(15)
                CanWriteReg(MR, 0x00);                //退出Reset模式
}

void CANInit()
{
        CANEN = 1;               //CAN1模块使能
        CanWriteReg(MR,0x05);//使能 Reset Mode, 采用单滤波设置

        CANSetBaudrate();             //设置波特率
       
        //设置过滤ID为:xxF8xxxx 的帧才接收
//        CanWriteReg(ACR0,0x07);                //总线验收代码寄存器
//        CanWriteReg(ACR1,0xc0);
//        CanWriteReg(ACR2,0x00);
//        CanWriteReg(ACR3,0x00);
//        CanWriteReg(AMR0,0xF8);                //总线验收屏蔽寄存器
//        CanWriteReg(AMR1,0x07);
//        CanWriteReg(AMR2,0xFF);
//        CanWriteReg(AMR3,0xFF);

        //取消过滤ID,所有帧都接收
        CanWriteReg(ACR0,0x00);                //总线验收代码寄存器
        CanWriteReg(ACR1,0x00);
        CanWriteReg(ACR2,0x00);
        CanWriteReg(ACR3,0x00);
        CanWriteReg(AMR0,0xFF);                //总线验收屏蔽寄存器
        CanWriteReg(AMR1,0xFF);
        CanWriteReg(AMR2,0xFF);
        CanWriteReg(AMR3,0xFF);

        CanWriteReg(IMR ,0xff);                //中断寄存器
        CanWriteReg(ISR ,0xff);                //清中断标志
        CanWriteReg(MR,0x01);                //退出 Reset Mode, 采用单滤波设置(设置过滤器后注意选择滤波模式)
        //CanWriteReg(MR,0x00);                //退出 Reset Mode, 采用双滤波设置(设置过滤器后注意选择滤波模式)

        //P_SW1 = (P_SW1 & ~(3<<4)) | (0<<4); //端口切换(CAN_Rx,CAN_Tx) 0x00:P0.0,P0.10x10:P5.0,P5.10x20:P4.2,P4.50x30:P7.0,P7.1
        P_SW1 &= 0xcf;
      P_SW1 |= 0x00;
        CANICR = 0x02;                //CAN中断使能
}

张三丰 发表于 2025-7-30 14:47:04

就屏蔽了这句//P_SW1 = (P_SW1 & ~(3<<4)) | (0<<4); //端口切换(CAN_Rx,CAN_Tx) 0x00:P0.0,P0.10x10:P5.0,P5.10x20:P4.2,P4.50x30:P7.0,P7.1
换成了P_SW1 &= 0xcf;
         P_SW1 |= 0x00;

张三丰 发表于 2025-7-30 14:58:02

我找问题的时候,发现ID影响到了n(返回帧个数),CanReadMsg这个程序就跑飞了一样
u8 CanReadMsg(CAN_DataDef *CAN)
{
    u8 i;

    do{
      CanReadFifo(&CAN);//读取接收缓冲区数据
      i = CanReadReg(SR);
    }while(i&0x80);   //判断接收缓冲区里是否还有数据,有的话继续读取

    return n;   //返回帧个数
}

乘风飞扬 发表于 2025-7-30 17:40:53

例程STC32G-DEMO-CODE里的50-CAN总线扩展帧收发测试程序是将收到的报文通过CAN总线原样返回。
如果你是两个产品进行通信的话,建议用屠龙刀例程包里面的例子测试:14-CAN1-CAN2总线标准帧扩展帧同时使用收发测试
这个例子将收到的报文通过串口打印出来,这样通过串口打印信息就能判断是否收到对应ID的数据。
屠龙刀例程包下载地址:https://www.stcai.com/hxgnsyb

张三丰 发表于 2025-7-30 17:44:00

好的,谢谢啦,我试试

张三丰 发表于 2025-7-31 09:22:04

屠龙刀里的子程序和我用的例程是一样的,没有区别。你那边改ID后不影响收数据吗?

zhang32568 发表于 2025-7-31 19:48:57

会不会是帧ID数据类型出问题?

张三丰 发表于 2025-8-1 09:49:55

我用例程试了也是同样的问题,我只是把例程的波特率改成了10K,我把例程传上来,您跑一下看看

张三丰 发表于 2025-8-1 09:51:50

您说的帧ID数据类型是啥意思?
页: 1 [2]
查看完整版本: CAN接收问题求助