c#用串口传输二进制文件 xmodem协议

代码是项目中拷出来的,俗称刷机软件,绝对可用,缺少的控件和变量名自己补齐就好

using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.IO.Ports;
using System.Linq;
using System.Net;                                                       //引入socket命名
using System.Net.Sockets;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using Microsoft.VisualBasic;

 

1、第一步,打开二进制文件并存为list

  OpenFileDialog openFileDialog1 = new OpenFileDialog(); //定义打开文本位置的类

            openFileDialog1.Filter = "Bin Files (.bin)|*.bin|所有文件 (*.*)|*.*";//文件筛选器的设定
            openFileDialog1.FilterIndex = 1;
            openFileDialog1.FileName = "";
            openFileDialog1.ShowReadOnly = true;
            if (openFileDialog1.ShowDialog() == DialogResult.OK)
            {
                tbx_FileName.Text = openFileDialog1.FileName;
                try
                {
                    Open_File_list.Clear();

                    FileStream fs = new FileStream(openFileDialog1.FileName, FileMode.Open);//初始化文件流

                    BinaryReader sr = new BinaryReader(fs);
                    sr.BaseStream.Seek(0, SeekOrigin.Begin);

                    Open_File_array_length = (int)fs.Length;

                    for (int i = 0; i < Open_File_array_length; i++)
                    {
                        byte tmp = sr.ReadByte();
                        Open_File_list.Add(tmp);
                    }
                    //关闭此StreamReader对象 
                    sr.Close();
                    fs.Close();
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                    return;
                }
            }

 

 

2、第二步创建一个线程发送list,用到xmodem协议

private void sendFile()
        {
            ComThread_Run_Flag = false;
            btn_SendFile.Enabled = false;
            Timer1_Run_Flag = true;
            rcv_buffer = new byte[255]; //创建数字缓存区
            send_buffer = new byte[1029]; //创建缓存区  1024 for XModem 1k + 3 head chars + 2 crc
            packetno = 1;
            complate_sz = 0;        //已经发送的字节数
            totle_sz = 0;           //需要发送数据包的长度
            remnant_sz = 0;         //剩余长度
            complate = false;      //发送完成标志位
            done = true;    //串口发送文件结束的标记
            //string return_data = "";    //返回值
            Send_Times = 0;         //重发次数

            while (done)
            {
                Thread.Sleep(10);
                Per_Sec_Count++;
                if (Per_Sec_Count > MAX_WAIT_C_SEC * 500)
                {
                    done = false;
                    Per_Sec_Count = 0;
                    btn_SendFile.Enabled = true;
                    ComThread_Run_Flag = true;
                    //Timer1_Run_Flag = false;
                    toolStripProgressBar1.Value = 0;//设置当前值
                    MessageBox.Show("接收超时", "发送文件", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    return;
                }

                int rcv_DataLen = serialPort1.BytesToRead; //接收的字节数

                if (rcv_DataLen > 0)
                {
                    serialPort1.Read(rcv_buffer, 0, rcv_DataLen);//把数据读入缓存区
                    //Console.WriteLine("rcv_buffer0:{0}", rcv_buffer[0].ToString("X2") + " ");
                    //AddContent(rcv_buffer[0].ToString("X2")+"\n", "Green");
                   // Console.WriteLine("totle_sz:{0}  complate_sz:{1}   remnant_sz{2}", totle_sz, complate_sz, remnant_sz);
                    AddContent("<"+DateTime.Now.ToString ("HH:mm:ss")+">"  +"已完成:"+complate_sz+"/"+totle_sz+"\n" ,"Green");
                    //this.AddData(rcv_buffer, rcv_DataLen);//输出显示数据
                    //  BarCountRx.Text = Convert.ToString(Convert.ToInt32(BarCountRx.Text) + rcv_DataLen); //接收字节计数
                    rcv_DataLen += rcv_buffer.Length;
                    BarCountRx.Text = Convert.ToString(rcv_DataLen); //接收字节计数


                    if (rcv_buffer[0] == POLL)
                    {
                        Per_Sec_Count = 0;
                        totle_sz = Open_File_array_length;
                        packetno = 1;
                        complate_sz = 0;
                        Send_Times = 0;
                        toolStripProgressBar1.Maximum = (int)totle_sz;
                        toolStripProgressBar1.Value = 0;//设置当前值
                        goto send_data;
                    }
                    else if (rcv_buffer[0] == ACK)
                    {
                        Per_Sec_Count = 0;
                        complate_sz = complate_sz + remnant_sz;
                        toolStripProgressBar1.Value = complate_sz;
                        toolStripStatusLabel3.Text = (Convert.ToDouble(complate_sz) / Convert.ToDouble(totle_sz)*100).ToString().Substring(0,2) + "%";
                        if (complate_sz < totle_sz)
                        {
                            Send_Times = 0;
                            packetno++;
                            goto send_data;
                        }
                        else
                        {
                            if (complate == true)
                            {
                                done = false;
                                Per_Sec_Count = 0;
                                btn_SendFile.Enabled = true;
                                ComThread_Run_Flag = true;
                                //Timer1_Run_Flag = false;
                                toolStripProgressBar1.Value = 0;//设置当前值
                                MessageBox.Show("发送完成", "发送文件", MessageBoxButtons.OK, MessageBoxIcon.Information);
                                flag_time = true;
                                beforDT = System.DateTime.Now;

                                return;
                            }
                            else
                            {
                                goto send_data;
                            }
                        }
                    }
                    else if (rcv_buffer[0] == NAK)
                    {
                        Per_Sec_Count = 0;
                        goto send_data;
                    }
                    else if (rcv_buffer[0] == CAN)
                    {
                        done = false;
                        Per_Sec_Count = 0;
                        btn_SendFile.Enabled = true;
                        ComThread_Run_Flag = true;
                        //Timer1_Run_Flag = false;
                        toolStripProgressBar1.Value = 0;//设置当前值
                        MessageBox.Show("强制结束", "发送文件", MessageBoxButtons.OK, MessageBoxIcon.Information);
                        return;
                    }
                    else
                    {
                        done = false;
                        Per_Sec_Count = 0;
                        btn_SendFile.Enabled = true;
                        ComThread_Run_Flag = true;
                        //Timer1_Run_Flag = false;
                        toolStripProgressBar1.Value = 0;//设置当前值
                        MessageBox.Show("发送错误", "发送文件", MessageBoxButtons.OK, MessageBoxIcon.Information);
                        return;
                    }

                send_data:
                    try
                    {
                        if (Send_Times < MAX_RSEND)
                        {
                            send_buffer[0] = STX;
                            send_buffer[1] = packetno;
                            send_buffer[2] = (byte)(~packetno);
                            remnant_sz = totle_sz - complate_sz;
                            if (remnant_sz > Per_Pack_Sz)
                            {
                                remnant_sz = Per_Pack_Sz;
                            }
                            if (remnant_sz > 0)
                            {
                                //Array.Copy(Open_File_array, complate_sz, send_buffer, 3, remnant_sz);

                                Open_File_list.CopyTo(complate_sz, send_buffer, 3, remnant_sz);
                                if (remnant_sz < Per_Pack_Sz)         //数据不足一包完整的数据包
                                {
                                    for (int i = 3 + remnant_sz; i < Per_Pack_Sz + 3; i++)
                                    {
                                        send_buffer[i] = CTRLZ;
                                    }
                                }

                                int CRC = u16CRCVerify(send_buffer, 3, Per_Pack_Sz);

                                send_buffer[Per_Pack_Sz + 3] = (byte)((CRC >> 8) & 0xFF);
                                send_buffer[Per_Pack_Sz + 4] = (byte)((CRC) & 0xFF);

                                for (int j = 0; j < Per_Pack_Sz + 5; j++)
                                {
                                    Console.Write(send_buffer[j].ToString("X2") + " ");
                                }
                                Console.WriteLine("");

                                this.serialPort1.Write(send_buffer, 0, Per_Pack_Sz + 5);
                                Send_Times++;
                            }
                            else
                            {
                                byte[] buffer2 = new byte[1];
                                buffer2[0] = EOT;
                                for (int j = 0; j < 1; j++)
                                {
                                    Console.Write(buffer2[j].ToString("X2") + " ");
                                }
                                Console.WriteLine("");

                                this.serialPort1.Write(buffer2, 0, 1);

                                complate = true;
                            }
                        }
                        else
                        {
                            done = false;
                            Send_Times = 0;
                            Per_Sec_Count = 0;
                            btn_SendFile.Enabled = true;
                            ComThread_Run_Flag = true;
                            //Timer1_Run_Flag = false;
                            toolStripProgressBar1.Value = 0;//设置当前值
                            MessageBox.Show("发送错误", "发送文件", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                            return;
                        }
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show(ex.Message);
                        return;
                    }
                }
            }
        }

  • 3
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
STM32是一款广泛应用于嵌入式系统开发的微控制器,它支持使用自定义协议发送二进制文件。在这个过程中,我们可以使用一些文件传输协议,比如XMODEM或者YMODEM等,通过串口或者网络接口将二进制文件发送到另一台设备或者主机。 要实现这一功能,我们首先需要在STM32的固件中集成相应的文件传输协议库,这样才能够在微控制器上实现二进制文件的发送功能。然后,我们需要在主机或者另一台设备上同样实现相同的文件传输协议,以便于接收STM32发送过来的二进制文件。 在实际的应用中,我们需要通过编程来实现文件的读取和发送,首先在STM32上读取待发送的二进制文件,然后将文件数据按照自定义协议进行打包,并通过串口或者网络接口发送到目标设备。在目标设备上,我们需要实现对应的接收逻辑,来解析并保存被发送的二进制文件。 需要注意的是,在使用自定义协议发送二进制文件时,我们需要仔细处理数据的校验和确认机制,以确保文件能够完整地发送和接收。同时,考虑到数据传输的稳定性和效率,我们也需要在代码中添加一些错误处理和重传机制,以应对在数据传输过程中可能出现的问题。 总而言之,通过STM32使用自定义协议发送二进制文件是一项相对复杂的任务,需要我们充分理解文件传输协议的原理,并在实际的应用中经过严格的测试和验证,确保数据的可靠性和稳定性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值