自学内容网 自学内容网

C#上位机通过CAN总线发送bin文件

让gpt生成一段代码用来把bin文件通过can总线发出去

c#代码还是比较强大的,各种功能基本都是一两行代码就实现了,这里记录一下对这个代码的理解和解读

主要代码如下,传入bin文件的地址即可将其从指定的can通道发送出去:

public void SendBINFile(string binFilePath)
{
  if (!File.Exists(binFilePath))
  {
    Console.WriteLine("BIN file not found: " + binFilePath);
    return;
  }

  try
  {
    // 读取 BIN 文件
    byte[] binData = File.ReadAllBytes(binFilePath);
    int chunkSize = 8; // 每帧发送 8 字节
    int totalFrames = (binData.Length + chunkSize - 1) / chunkSize;

    Console.WriteLine($"Sending BIN file: {binFilePath}");
    Console.WriteLine($"Total data size: {binData.Length} bytes, Frames: {totalFrames}");

    for (int i = 0; i < totalFrames; i++)
    {
      // 准备 CAN 消息
      byte[] frameData = new byte[chunkSize];
      int currentFrameSize = Math.Min(chunkSize, binData.Length - i * chunkSize);
      Array.Copy(binData, i * chunkSize, frameData, 0, currentFrameSize);

      TPCANMsg canMessage = new TPCANMsg
      {
        ID = 0x123, // 自定义消息 ID
        LEN = (byte)currentFrameSize,
        MSGTYPE = TPCANMessageType.PCAN_MESSAGE_STANDARD,
        DATA = frameData
      };

      // 发送 CAN 消息
      LastStatus = PCANBasic.Write(Pcan_Handle, ref canMessage);
      Thread.Sleep(1);
      if (LastStatus != TPCANStatus.PCAN_ERROR_OK)
      {
        Console.WriteLine($"Error sending frame {i + 1}: {GetErrorText(LastStatus)}");
      }
      else
      {
        Console.WriteLine($"Frame {i + 1} sent: {BitConverter.ToString(frameData, 0, currentFrameSize)}");
      }
    }
  }
  catch (Exception ex)
  {
    Console.WriteLine("Error sending BIN file: " + ex.Message);
  }
}

其他都比较简单易懂,其中最核心的就是for循环的这部分:

for (int i = 0; i < totalFrames; i++)
    {
      // 准备 CAN 消息
      byte[] frameData = new byte[chunkSize];
      int currentFrameSize = Math.Min(chunkSize, binData.Length - i * chunkSize);
      Array.Copy(binData, i * chunkSize, frameData, 0, currentFrameSize);

      TPCANMsg canMessage = new TPCANMsg
      {
        ID = 0x123, // 自定义消息 ID
        LEN = (byte)currentFrameSize,
        MSGTYPE = TPCANMessageType.PCAN_MESSAGE_STANDARD,
        DATA = frameData
      };

      // 发送 CAN 消息
      LastStatus = PCANBasic.Write(Pcan_Handle, ref canMessage);
      Thread.Sleep(1);

其中framedata用来储存当前要发送的数据,最大8字节,每一个for循环都要进行一次发送。currentFrameSize是当前这轮发送时framedata的尺寸,除了最后一帧外全都是8。

Array.Copy(binData, i * chunkSize, frameData, 0, currentFrameSize)是将“bindata”这个bin文件的指定位置(i * chunkSize)指定大小(currentFrameSize)的数据复制到framedata中用于发送。

其次,Thread.Sleep(1)也是很重要的,250k波特率下每秒can总线发送报文的极限是2000条左右,为了均衡效率和稳定性,我们设置每次发送后延时1ms再继续发送,以避免总线过载或者可能发生的错误。


原文地址:https://blog.csdn.net/weixin_57904199/article/details/145116857

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!