public bool PCNodeSendReturn(byte[] SendByteArray, out byte[] RecvData, int cnt, int time)
        {
            int  i;
            bool sendflag = false;

            RecvData = null;
            try
            {
                uart1.setReceInt(1000);   //测试串口接收中断使用
                for (i = 0; i < cnt; i++)
                {
                    sendflag = uart1.sendData(SendByteArray, SendByteArray.Length); // 通过串口发送数据
                    System.Threading.Thread.Sleep(time);
                    RecvData = uart1.recvData();                                    // 通过串口接收数据
                    if (RecvData.Length >= 1)
                    {
                        break;
                    }
                }
            }
            catch
            {
                return(false);  //产生错误,返回false
            }
            return(sendflag);   // 返回接收数据数据的首地址
        }
        //======================================================================
        //函数名称:uartSendRecv
        //函数返回:true:数据帧发送成功并接收到返回值;
        //          false:数据帧发送后未接收到返回值或返回值解析失败
        //参数说明:sendBytes:待发送的数据;cnt:重复发送次数;
        //          time:发送后等待接收返回值的时间
        //功能概要:串口发送数据,并等待接收返回值
        //======================================================================
        private bool uartSendRecv(byte[] sendBytes, int cnt, int time)
        {
            //(1)变量声明
            bool rv;
            bool sendFlag;

            byte[] recvData;  //返回数据

            rv = true;
            //(2)提示发送数据操作
            fmain.lbl_mainstatus.Text = "运行状态:正发送数据至终端...";
            txtShow("\r\n正发送数据至终端,等待返回数据...\r\n");
            //(3)发送数据帧到终端
            uart.recvData();//在发送数据帧之前清空接收缓冲区
            //数据发送并等待指定时间接收返回值
            sendFlag = pcNode.PCNodeSendReturn(sendBytes, out recvData, cnt, time);
            //(4)未接收到数据则更新状态栏
            if (recvData == null || recvData.Length <= 0)
            {
                fmain.lbl_mainstatus.Text = "运行状态:终端无数据返回";
                txtShow("终端无数据返回\r\n");

                //提示失败
                rv = false;
                goto uartSendRecv_EXIT;
            }
            //(5)成功接收数据,提示并进行数据解析
            fmain.lbl_mainstatus.Text = "运行状态:接收到终端数据返回,数据解析中...";
            txtShow("接收到终端数据返回,数据解析中...\r\n");
            //(5.1)终端接收到更新提示,跳转bootloader程序并返回Start Update
            if (System.Text.Encoding.Default.GetString(recvData) == "Start Update")
            {
                fmain.lbl_mainstatus.Text = "运行状态:程序进入bootloader,开始更新";
                txtShow("程序进入bootloader,开始更新\r\n");

                rv = true;
                goto uartSendRecv_EXIT;
            }
            //(5.2)接收到更新返回数据
            else if (update != null && update.updateRecv(recvData) != 0)  //数据解析失败
            {
                fmain.lbl_mainstatus.Text = "运行状态:数据解析失败";
                txtShow("数据解析失败\r\n");

                rv = false;
                goto uartSendRecv_EXIT;
            }
            //(6)至此,数据接收成功
            fmain.lbl_mainstatus.Text = "运行状态:数据解析成功,成功接收到终端返回";
            txtShow("数据解析成功,成功接收到终端返回\r\n");

uartSendRecv_EXIT:
            return(rv);
        }
        //======================================================================
        //函数名称:uartSendRecv
        //函数返回:true:数据帧发送成功并接收到返回值;
        //          false:数据帧发送后未接收到返回值或返回值解析失败
        //参数说明:sendBytes:待发送的数据;cnt:重复发送次数;
        //          time:发送后等待接收返回值的时间
        //功能概要:串口发送数据,并等待接收返回值
        //======================================================================
        private bool uartSendRecv(byte[] sendBytes, int cnt, int time)
        {
            //(1)变量声明
            bool rv;
            bool sendFlag;

            byte[] recvData;  //返回数据

            rv = true;
            //(2)提示发送数据操作
            fmain.lbl_mainstatus.Text = "运行状态:正发送更新数据至终端...";
            txtShow("\r\n正发送更新数据至终端...\r\n");
            //(3)发送数据帧到终端
            uart.recvData();//在发送数据帧之前清空接收缓冲区
            //数据发送并等待指定时间接收返回值
            sendFlag = pcNode.PCNodeSendReturn(sendBytes, out recvData, cnt, time);
            //(4)根据终端返回数据来判断终端执行状态
            //(5.1)终端接收到更新提示,跳转bootloader程序并返回Start Update
            if (System.Text.Encoding.Default.GetString(recvData) == "Start Update")
            {
                fmain.lbl_mainstatus.Text = "运行状态:程序进入bootloader,开始更新";
                txtShow("程序进入bootloader,开始更新\r\n");

                rv = true;
                goto uartSendRecv_EXIT;
            }
            //(5.2)接收到更新返回数据
            else if (update.getSendCount() == update.getFrameNum() - 1)  //数据解析失败
            {
                fmain.lbl_mainstatus.Text = "运行状态:准备发送检查命令,等待接收返回值...";
                txtShow("准备发送检查命令,等待接收返回值...\r\n");
                if (update.updateRecv(recvData) != 0)
                {
                    update.checkClear(update.getFrameNum() - 2);//请检查帧发送标志

                    fmain.lbl_mainstatus.Text = "运行状态:终端数据检查失败,补发丢失数据...";
                    txtShow("终端数据检查失败,补发丢失数据...\r\n");

                    rv = false;
                    goto uartSendRecv_EXIT;
                }
                else
                {
                    fmain.lbl_mainstatus.Text = "运行状态:终端更新数据检查成功";
                    txtShow("终端更新数据检查成功\r\n");
                }
            }
            //(6)至此,数据接收成功
            //fmain.lbl_mainstatus.Text = "运行状态:数据解析成功,成功接收到终端返回";
            //txtShow("数据解析成功,成功接收到终端返回\r\n");

uartSendRecv_EXIT:
            return(rv);
        }
Beispiel #4
0
        //======================================================================
        //函数名称:sendRecv
        //函数返回:true:数据帧发送成功并接收到返回值;
        //          false:数据帧发送后未接收到返回值或返回值解析失败
        //参数说明:sendBytes:待发送的数据;cnt:重复发送次数;
        //          time:发送后等待接收返回值的时间
        //功能概要:串口发送数据,并等待接收返回值
        //======================================================================
        private bool sendRecv(byte[] sendBytes, int cnt, int time)
        {
            //(1)变量声明
            byte[] recvData;
            bool   rv;
            bool   sendFlag;
            string com;

            rv = true;
            //(2)更新状态栏,显示当前操作
            txtShow("\r\n正在发送...\r\n");
            //(3)发送数据帧到下位机
            uart.recvData();//在发送数据帧之前清空接收缓冲区
            sendFlag = pcNode.PCNodeSendReturn(sendBytes, out recvData, cnt, time);
            //(4)若发送失败,尝试自动重连一次,并且重发
            if (sendFlag == false)
            {
                fmain.lbl_status.Text = "运行状态:数据发送失败,重新连接终端并重发...";
                txtShow("数据发送失败,重新连接终端并重发...\r\n");
                //重连串口
                if (uart != null && uart.IsOpen)
                {
                    uart.close();
                }
                com  = pcNode.findPCNode();
                uart = pcNode.PCNode_Uart;
                fmain.lbl_status.Text = "运行状态:找到" + com;
                lbl_uart_state.Text   = com;
                //重新发送数据
                sendFlag = pcNode.PCNodeSendReturn(sendBytes, out recvData, cnt, time);
            }
            //(5)未接收到数据则更新状态栏
            if (recvData == null || recvData.Length <= 0)
            {
                fmain.lbl_status.Text = "运行状态:无数据返回";
                txtShow("无数据返回\r\n");

                rv = false;
                goto sendRecv_EXIT;
            }
            //(6)成功接收数据,提示并进行数据解析
            txtShow("有数据返回,数据解析中...\r\n");

            if (System.Text.Encoding.Default.GetString(recvData) == "Start Update")
            {
                fmain.lbl_status.Text = "运行状态:程序进入bootloader,开始更新";
                txtShow("程序进入bootloader,开始更新\r\n");

                rv = true;
                goto sendRecv_EXIT;
            }
            else if (update != null && update.updateRecv(recvData) != 0)  //数据解析失败
            {
                fmain.lbl_status.Text = "运行状态:数据解析失败";
                txtShow("数据解析失败\r\n");

                rv = false;
                goto sendRecv_EXIT;
            }
            //(7)至此,数据接收成功
            fmain.lbl_status.Text = "运行状态:数据解析成功,准备下一帧";
            txtShow("数据解析成功,准备下一帧\r\n");

sendRecv_EXIT:
            return(rv);
        }
        /// ------------------------------------------------------------------------------
        /// <summary>
        /// 功    能:寻找PCNode。
        /// 形    参:无
        /// <returns>无</returns>
        /// -----------------------------------------------------------------------------
        public string findPCNode()
        {
            int    i, j;
            string s1;
            string recvstr;

            int[] uartNoArray;   //
            System.IO.Ports.SerialPort uartport;
            //1.临时变量

            bool result = false;     //

            byte[] recvData = null;  //串口接收返回的信息


            byte[] shakeframe = { (byte)'s', (byte)'h', (byte)'a', (byte)'k', (byte)'e' };

            byte[] frame = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                             0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };

            //初始化内部调用函数临时变量
            s1 = string.Empty;    //初始化临时字符串(置空)

            //创建_port1对象
            uartport = new System.IO.Ports.SerialPort();
            //查询所有串口,串口数在uartNoArray[0]中

            uartNoArray = Uart.findCOM();
            //没有找到串口情况
            if (uartNoArray[0] == 0)
            {
                return(s1 = "没有找到USB串口");
            }

            //有找到串口情况,遍历搜寻串口
            for (i = uartNoArray[0]; i >= 1; i--)
            {
                string comName = "COM" + uartNoArray[i].ToString(); //串口名称
                uart1 = new Uart(uartport, comName, 115200);        //初始化串口工具类
                //2.打开串口
                result = uart1.open();
                if (!result)
                {
                    continue;
                }
                uart1.setReceInt(200);                                  //设置触发DataRecieved事件的字节数(目的是关闭该事件)
                uart1.sendData(frame, frame.Length);                    //预发送数据,防止下位机组帧出错
                System.Threading.Thread.Sleep(100);                     //线程休眠0.1s
                result = uart1.sendData(shakeframe, shakeframe.Length); //发送握手数据
                if (!result)
                {
                    uart1.close(); continue;
                }
                System.Threading.Thread.Sleep(100);   //线程休眠0.1s
                recvData = uart1.recvData();          //接收数据

                //if (recvData == null || recvData.Length == 0)
                //   { uart1.close(); continue; }

                //将握手成功,数组转换成字符串,返回
                recvstr = System.Text.Encoding.Default.GetString(recvData);
                if (!recvstr.Contains("shake:"))
                {
                    uart1.close(); continue;
                }
                j  = recvstr.IndexOf(":");
                s1 = recvstr.Substring(j + 1, recvstr.Length - j - 1);
                //s1 = comName;
                break;
            }
            if (i == 0)
            {
                s1    = "有USB串口,但未连上终端";
                uart1 = null;
            }

            return(s1);
        }