C# 串口升级简易版

一、串口升级思路

1)第一步先能发送文件,并实现进度条功能;
2)制定升级协议,升级需要开始帧、结束校验帧、文件数据的校验等内容;
3)发送文件加上起始帧、结束校验帧和升级文件校验,增加容错性;
4)升级.bin文件测试。

二、代码实现

1)打开文件,文件路径显示在文本框

//声明变量
static bool flagUpdata = true;
static bool flagUpgradeTimer = true;
static byte[] startFrame = { 0x5A, 0x01, 0x02, 0x08, 0x02, 0x00, 0x01, 0x0, 0x0 };
System.Timers.Timer UpgradeTimer = new System.Timers.Timer(100);

static UInt16 upgradeBarTime = 0;
static bool upgradePanelFlag = true;
static bool upgradeEndFlag = true;
static byte[] endFrame = { 0x5A, 0x01, 0x02, 0x08, 0x04, 0x0, 0x2, 0x0, 0x0, 0x0, 0x0 };

byte[] updataFileData = new byte[1024 * 200];
int readByte = 0;
//打开文件
private void btnOpenFile_Click(object sender, EventArgs e)
{           
    OpenFileDialog ofd = new OpenFileDialog();          //点击弹出对话框           
    ofd.Title = "请选择要打开的文本文件";                  //设置对话框标题           
    ofd.Multiselect = true;                             //设置对话框多选           
    ofd.InitialDirectory = @"C:\Users\Andy\Desktop";    //设置对话框初始目录           
    ofd.Filter = "文本文件|*.bin";                       //打开对话框文件类型           
    ofd.ShowDialog();                                   //展示对话框
    string path = ofd.FileName;                         //获得在打开对话框中选中文件的路径
    if (path == "")
    {
        return;
    }

    using (FileStream fsRead = new FileStream(path, FileMode.OpenOrCreate,FileAccess.Read))
    {               
        readByte = fsRead.Read(updataFileData, 0, updataFileData.Length);//实际读取到的字节数
        txbFileAddr.Text = path;                       //文件路径显示在文本框
    }

    upgradeBarTime = 0;
    this.pgbProcessBar.Value = 0;           
    flagUpdata = true;
    upgradeEndFlag = true;
    upgradePanelFlag = true;
    UpgradeTimer.Start();
    btnStartUpgrade.Text = "开始升级";
}

2)开始帧校验成功--->串口发送文件--->结束校验帧

发送文件时,显示进度条,当前进度条是计时的,待优化,实际应该根据文件的大小,显示进度条。

//发送开始帧,初始化Timer事件
private void btnStartUpgrade_Click(object sender, EventArgs e)
{
     if (txbFileAddr.Text=="")
      {
          MessageBox.Show("请打开升级文件");
          return;
      }
            
      if (btnStartUpgrade.Text == "正在升级")
      {
           MessageBox.Show("正在升级,请勿操作!");
           return;
      }
      else
      {

         byte[] crc16BmsData = CrcCheck.CRC16(startFrame);
         startFrame[7] = crc16BmsData[0];         //高八位
         startFrame[8] = crc16BmsData[1];         //低八位
         MainForm.SerialPort1.Write(startFrame, 0, startFrame.Length);
         if (flagUpgradeTimer)
         {
              flagUpgradeTimer = false;                   
              UpgradeTimer.Elapsed += new                 
              System.Timers.ElapsedEventHandler(UpgradeAnalysis);
              UpgradeTimer.Enabled = true;          //设置执行System.Timers.Elapsed事件
              UpgradeTimer.AutoReset = true;        //设置一直执行
              UpgradeTimer.Start();
         }
      }
}

//开始帧应答判断、发送文件、发送结束校验帧及应答数据判断
private void UpgradeAnalysis(object sender, System.Timers.ElapsedEventArgs e)
{
     //开始帧应答数据判断
     if (MainForm.readData.Length == 9)
     {
          //判断帧头、通信目标
          if ((MainForm.readData[0] == 0x5A) && (MainForm.readData[1] == 2)) 
          {
             byte[] crc16StartFrameData = CrcCheck.CRC16(MainForm.readData);
             if ((crc16StartFrameData[0] == MainForm.readData[MainForm.readData.Length - 2]) && (crc16StartFrameData[1] == MainForm.readData[MainForm.readData.Length - 1]))
              {
                   //升级进度条
                   if (upgradeBarTime == 100)
                   {
                       return;
                   }
                   upgradeBarTime++;
                   this.pgbProcessBar.Value = upgradeBarTime;

                   if (flagUpdata)
                   {
                       flagUpdata = false;
                       btnStartUpgrade.Text = "正在升级";
                   }

                   if (upgradePanelFlag)
                   {
                        upgradePanelFlag = false;
                        MainForm.SerialPort1.Write(updataFileData, 0, readByte);//发送升级文件
                        byte[] crc16upgradeFile = CrcCheck.CRC16(updataFileData);
                        endFrame[7] = crc16upgradeFile[0];
                        endFrame[8] = crc16upgradeFile[1];
                        byte[] crc16EndFrame = CrcCheck.CRC16(endFrame);
                        endFrame[9] = crc16EndFrame[0];
                        endFrame[10] = crc16EndFrame[1];
                        MainForm.SerialPort1.Write(endFrame, 0, endFrame.Length);
                   }
               }
               else
               {
                    MainForm.readData = null;
                    this.pgbProcessBar.Value = 0;
                    txbFileAddr.Text = "";
                    btnStartUpgrade.Text = "开始升级";
                    MessageBox.Show("开始帧校验错误,请重新升级");
                    return;
                }
            }
            else
            {
                 MainForm.readData = null;
                 this.pgbProcessBar.Value = 0;
                 txbFileAddr.Text = "";
                 btnStartUpgrade.Text = "开始升级";
                 MessageBox.Show("帧头或通信目标错误,请重新升级");
                 return;
             }
        }
        
        //结束校验帧
       if (MainForm.readData.Length == 11)
       {
            //判断帧头、通信目标、数据长度、第一个数据02
            if ((MainForm.readData[0] == 0x5A) && (MainForm.readData[1] == 2) && (MainForm.readData[4] == 4) && (MainForm.readData[6] == 2))
            {
                  //文件校验值和上报的校验值比对
                 if ((endFrame[7] == MainForm.readData[7]) && (endFrame[8] == MainForm.readData[8]))
                 {
                      //结束帧CRC16校验比对
                      byte[] crc16StartFrameData = CrcCheck.CRC16(MainForm.readData);
                      if ((crc16StartFrameData[0] == MainForm.readData[MainForm.readData.Length - 2]) && (crc16StartFrameData[1] == MainForm.readData[MainForm.readData.Length - 1]))
                      {
                            if (upgradeEndFlag)
                            {
                                upgradeEndFlag = false;
                                btnStartUpgrade.Text = "升级完成";
                                MessageBox.Show("升级完成!");
                            }

                            UpgradeTimer.Close();
                            MainForm.readData = null;
                      }
                      else
                      {
                            MainForm.readData = null;
                            this.pgbProcessBar.Value = 0;
                            txbFileAddr.Text = "";
                            btnStartUpgrade.Text = "开始升级";
                            MessageBox.Show("结束校验帧错误,请重新升级");
                            return;
                      }
                  }
                  else
                  {
                        MainForm.readData = null;
                        this.pgbProcessBar.Value = 0;
                        txbFileAddr.Text = "";
                        btnStartUpgrade.Text = "开始升级";
                        MessageBox.Show("升级文件验帧错误,请重新升级");
                        return;
                  }
            }
            else
            {
                  MainForm.readData = null;
                  upgradeBarTime = 0;
                  txbFileAddr.Text = "";
                  btnStartUpgrade.Text = "开始升级";
                  MessageBox.Show("帧头、通信目标、数据长度或数据错误,请重新升级");
                  return;
            }
       }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值