421435178@qq.co 发表于 2023-7-24 09:14:21

CAN数据发送求助大神 | 已解决

小白我做can通讯实验用的实验代码,1秒定时时间到后发送两帧can数据,结果是每次只发送一条什么原因,大神给指导

421435178@qq.co 发表于 2023-7-24 09:15:30

两条发送语句只执行第一句

421435178@qq.co 发表于 2023-7-24 09:16:33

canid++是执行的,只是不发送数据

乘风飞扬 发表于 2023-7-24 09:28:46

本帖最后由 乘风飞扬 于 2023-7-24 09:32 编辑

参考最新的屠龙刀例程包,或者STC32G库函数例程包里CAN总线例程,在“CanSendMsg”函数里增加发送完成判断(B_CanxSend ),上一帧数据发送完成后再发送本次数据,避免产生覆盖:
void CanSendMsg(CAN_DataDef *CAN)
{
    u32 CanID;
    u8 RX_Index,i;

    if(CANSEL)//判断是否CAN2
    {
      while(B_Can2Send);//等待CAN2上次发送完成
    }
    else
    {
      while(B_Can1Send);//等待CAN1上次发送完成
    }

    if(CAN->FF)   //判断是否扩展帧
    {
      CanID = CAN->ID << 3;
      CanWriteReg(TX_BUF0,CAN->DLC|((u8)CAN->RTR<<6)|0x80);      //bit7: 标准帧(0)/扩展帧(1), bit6: 数据帧(0)/远程帧(1), bit3~bit0: 数据长度(DLC)
      CanWriteReg(TX_BUF1,(u8)(CanID>>24));
      CanWriteReg(TX_BUF2,(u8)(CanID>>16));
      CanWriteReg(TX_BUF3,(u8)(CanID>>8));

      CanWriteReg(TX_BUF0,(u8)CanID);

      RX_Index = 1;
      for(i=0;((i<CAN->DLC) && (i<8));i++)      //数据长度为DLC,最多不超过8
      {
            CanWriteReg((u8)(TX_BUF0 + (RX_Index++&3)),CAN->DataBuffer);   //写入有效数据
      }
      while(RX_Index&3)   //判断已读数据长度是否4的整数倍
      {
            CanWriteReg((u8)(TX_BUF0 + (RX_Index++&3)),0x00);//写入填充数据,一帧数据占据4的整数倍缓冲区空间,不足补0
      }
    }
    else    //发送标准帧
    {
      CanID = (u16)(CAN->ID << 5);
      CanWriteReg(TX_BUF0,CAN->DLC|((u8)CAN->RTR<<6));//bit7: 标准帧(0)/扩展帧(1), bit6: 数据帧(0)/远程帧(1), bit3~bit0: 数据长度(DLC)
      CanWriteReg(TX_BUF1,(u8)(CanID>>8));
      CanWriteReg(TX_BUF2,(u8)CanID);

      RX_Index = 3;
      for(i=0;((i<CAN->DLC) && (i<8));i++)      //数据长度为DLC,最多不超过8
      {
            CanWriteReg((u8)(TX_BUF0 + (RX_Index++&3)),CAN->DataBuffer);   //写入有效数据
      }
      while(RX_Index&3)   //判断已读数据长度是否4的整数倍
      {
            CanWriteReg((u8)(TX_BUF0 + (RX_Index++&3)),0x00);//写入填充数据,一帧数据占据4的整数倍缓冲区空间,不足补0
      }
    }
    CanWriteReg(CMR ,0x04);                //发起一次帧传输
   
    if(CANSEL)//判断是否CAN2
    {
      B_Can2Send = 1;   //设置CAN2发送忙标志
    }
    else
    {
      B_Can1Send = 1;   //设置CAN1发送忙标志
    }
}在中断函数里清除发送完成标志"B_Can1Send ":
if((isr & 0x04) == 0x04)//TI
{
    CANAR = ISR;
    CANDR = 0x04;    //CLR FLAG
               
    B_Can1Send = 0;
}      

stcstc 发表于 2023-7-24 10:14:54

楼主这个程序是官方例程修改的,例程我没有修改我这个怎么一直1ms发送一次呢?定时器的值修改和计算器1000修改依然没用

421435178@qq.co 发表于 2023-7-24 10:30:34

感谢指导,我试一下

421435178@qq.co 发表于 2023-7-24 11:08:35

乘风飞扬 发表于 2023-7-24 09:28
参考最新的屠龙刀例程包,或者STC32G库函数例程包里CAN总线例程,在“CanSendMsg”函数里增加发送完成判断( ...

在中断里面加了清除标志,在发送那里加了等待,发送函数里面也加了标志,还是不行发不出我要发的数据

乘风飞扬 发表于 2023-7-24 11:36:39

stcstc 发表于 2023-7-24 10:14
楼主这个程序是官方例程修改的,例程我没有修改我这个怎么一直1ms发送一次呢?定时器的值修改和计算器1000 ...

CAN数据收发测试,需要总线上至少有2个节点,一个节点发送数据时另一个节点能够进行应答,这样才能正常收发。
没有节点进行应答的话,当前发送的CAN总线控制器会认为发送有误,就会进行重发。

421435178@qq.co 发表于 2023-7-24 12:32:55

我用的can收发器测试的,收到的都是同一条数据,只是ID++了

乘风飞扬 发表于 2023-7-24 13:32:55

421435178@qq.co 发表于 2023-7-24 12:32
我用的can收发器测试的,收到的都是同一条数据,只是ID++了

用附件例程试试,CAN1发送完一次数据后将CANID加1,然后再发送一次:

                if(sr & 0x01)                //判断是否有 BS:BUS-OFF状态
                {
                  CANAR = MR;
                  CANDR &= ~0x04;//清除 Reset Mode, 从BUS-OFF状态退出
                }
                else
                {
                  CanSendMsg(&CAN1_Tx);   //发送一帧数据
                  CAN1_Tx.ID++;
                  CanSendMsg(&CAN1_Tx);   //发送一帧数据
                }
从串口打印数据可以看到CAN2收到两次CAN1发送的数据,第二次收到CANID+1:


页: [1] 2 3
查看完整版本: CAN数据发送求助大神 | 已解决