zoukankan      html  css  js  c++  java
  • C#串口通信:2自动连接

    上次说到了协议的大致结构,这次我们来说说怎么去实现制动连接串口(当你把设备连上来之后,怎么去让软件自动去识别是否为目标设备,当然这需要上位机与下位机共同完成,这里我们只讨论上位机部分)
    先上协议:

    帧头(3)+设备号(1)+指令类型(2)+数据长度(2)+载荷+CRC(2)
    需要在下位机上实现的部分:
    接收到一帧数据(帧头为53 5A 59,设备号01,类型为02,载荷无)53 59 A2 01 02 00 00 00 CRC后,会返回(帧头为53 5A 59,设备号01,类型为02,载荷为"6F 6B")53 5A 59 01 02 00 02 00 6F 6B CRC则表示指令接收成功。
    下面说我的思路,在软件界面打开后,开一个自动连接线程处理连接部分。具体步骤是:

        获取计算机所有串口。
        尝试发送指定数据到每个可用串口。
        尝试从串口接收数据并检查是否为约定数据,若是则绑定该端口,完成连接。不是则换到下一个。循环。

    好了,让我们简单点,下面直接上代码:
     

    bool IsConnected = false; private void AutoConcted()
    {
        while (true)//循环
        {
            while (!IsConnected)//未连接
            {
                string[] strPorNnames = SerialPort.GetPortNames();//获取所有可用串口名
                foreach (string portName in strPorNnames)//遍历串口
                {
                    try
                    {
                        SPort.PortName = portName; SPort.Open(); SPort.DiscardOutBuffer(); byte[] bytSend = new byte[] { 0x53, 0x59, 0xA2, 0x01, 0x02, 0x00, 0x00, 0x00, CRC };//自行去CRC去 
                        SPort.Write(bytSend, 0, bytSend.Length);
                        Thread.Sleep(100);//确保数据发送及解析时间 
                        int n = SPort.BytesToRead; byte[] bytRec = new byte[n]; SPort.Read(bytRec, 0, n);
                        if (IsHertJump(bytRec))//判断返回是否为指定数据
                        {
                            IsConnected = true; break;//是则跳出循环
                        }
                        else
                        { SPort.Close(); }
                    }
                    catch (Exception) { SPort.Close(); }
                }
                Thread.Sleep(400);
            }
        }
    }

    是的,自动连接应该可以实现了,然而又有了新问题,这种自动连接貌似只能连一次,中途拔掉一下就不行了,因为连接上之后进程就自己销毁了。而且拔掉之后(串口断开)软件并不会有任何的状态提示,之后你所有的数据都会往一个不知道的地方去了。所以,我们还要加一个检测断开的机制。由于两者不会同时需要,所以可以写到一个线程里去,没连上就自动去连,连上了就检测是否断开。
    修改后的代码:(完善后的自动连接线程)

     

    private void AutoConcted()
    {
        while (true)
        {
            while (!IsConnected)
            {
                string[] strPorNnames = SerialPort.GetPortNames(); foreach (string portName in strPorNnames)
                {
                    try
                    {
                        SPort.PortName = portName; SPort.Open(); SPort.DiscardOutBuffer();
                        byte[] bytSend = new byte[] { 0x53, 0x59, 0xA2, 0x01, 0x02, 0x00, 0x00, 0x00, CRC };//自行去CRC去 
                        SPort.Write(bytSend, 0, bytSend.Length); Thread.Sleep(100); int n = SPort.BytesToRead; byte[] bytRec = new byte[n]; SPort.Read(bytRec, 0, n); if (IsHertJump(bytRec)) { IsConnected = true; break; } else { SPort.Close(); }
                    }
                    catch (Exception) { SPort.Close(); }
                }
                Thread.Sleep(400);
            } while (IsConnected)
            {
                if (!SPort.IsOpen)//检查是否断开
                { SPort.Close(); IsConnected = false; }
                Thread.Sleep(1000);
            }
        }
    }




  • 相关阅读:
    HDU 5744
    HDU 5815
    POJ 1269
    HDU 5742
    HDU 4609
    fzu 1150 Farmer Bill's Problem
    fzu 1002 HangOver
    fzu 1001 Duplicate Pair
    fzu 1150 Farmer Bill's Problem
    fzu 1182 Argus 优先队列
  • 原文地址:https://www.cnblogs.com/hnsongbiao/p/8722243.html
Copyright © 2011-2022 走看看