我写了一段串口通讯的程序,采用的是ModuleBus通讯协议。采用主从站方式进行通讯,我是主站,向从站发送读取命令的请求。
程序长时间运行之后,发现收不到数据,非要拔掉电源重启后才能收到。把程序关了再启动,也没有用。
也怀疑过时串口问题,但是使用USB转串口线也不行。

解决方案 »

  1.   

    关键地方写日志,这个要细心调试找问题。或是没数据时候,你暂停看看,看看监听线程的状态,看看当前的 BytesToRead属性。
      

  2.   

    把代码贴出来
            /// <summary>
            /// 启动适配器
            /// </summary>
            /// <returns>成功返回True,失败返回False</returns>
            protected override bool OnStartAdapter()
            {
               
                _collectThread = new Thread(new ThreadStart(CollectPro));
                _collectThread.Start();
                return true;
            }        /// <summary>
            /// 停止适配器
            /// </summary>
            /// <returns>成功返回True,失败返回False</returns>
            protected override bool OnStopAdapter()
            {
                _exitEvent.Set();
    #if SerialPort
                _serialPort.Close();#else
                _CommAPI.Close();
    #endif            if (_collectThread.ThreadState == ThreadState.Suspended)
                {
                    _collectThread.Resume();
                }
                if (_collectThread.ThreadState == ThreadState.Running)
                {
                    _collectThread.Join();
                }
                return true;
            }        protected void CollectPro()
            {
                if(Init())
                    _serialPort.DataReceived += new SerialDataReceivedEventHandler(_serialPort_DataReceived);
                SendMSG();
            }        
                  /// <summary>
            /// CRC16校验
            /// </summary>
            /// <param name="Buff">校验数组</param>
            /// <param name="Long">校验数据个数</param>
            /// <returns>双字节结果</returns>
            protected UInt16 CRC16(byte[] puchMsg, int usDataLen)
            {
               
            }
            protected void SendMSG()
            {
                UInt16 CRC;         
                byte[] SendBuffer = new byte[8];
                SendBuffer[0] = EquipMentId;    //设备地址
                SendBuffer[1] = Ablity;    //功能码,读数据
                SendBuffer[2] = 0x00;    //寄存器高位
                SendBuffer[3] = 0x02;    //寄存器低位
                SendBuffer[4] = 0x00;    //寄存器数据量高位
                SendBuffer[5] = 0x3b;    //寄存器数据量地位            CRC = CRC16(SendBuffer, 6);
                SendBuffer[6] = Convert.ToByte(CRC & 0xff);  //CRC校低验位
                SendBuffer[7] = Convert.ToByte(CRC >> 8);  //CRC校验高位            while (_collectThread.ThreadState == ThreadState.Running && !_exitEvent.WaitOne(10, false))
                {#if SerialPort
                    if (!_serialPort.IsOpen)
                        continue;
                    _serialPort.DiscardInBuffer();
                    _serialPort.Write(SendBuffer, 0, 8);
                    
                    OutPut("发送数据包请求," + string.Format("SendBuf:{0},WriteBuf:{1}", BitConverter.ToString(SendBuffer, 0, 8), _serialPort.ReadBufferSize.ToString()));
                    Thread.Sleep(30000);
    #else
                    if (!_CommAPI.Opened)
                        continue;
                    _CommAPI.Write(SendBuffer);
                    //Thread.Sleep(4000);
                    OutPut("发送数据包请求," + string.Format("SendBuf:{0}", BitConverter.ToString(SendBuffer, 0, 8)));
                    if (!_CommAPI.Opened)
                        continue;                bRes = 123;
                    _CommAPI.Read(bRes).CopyTo(ReadBuffer,0);
                    OutPut("接受到的数据" + string.Format("ReadBuf:{0}", BitConverter.ToString(ReadBuffer, 0, bRes)));
                  #endif
                }
            }        /// <summary>
            /// 处理数据包
            /// </summary>
            private void ParaPack()
            {
                           }        }        /// <summary>
            /// 数据接收过程
            /// </summary>
           private  void _serialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
            {                  int DataLength = _serialPort.BytesToRead;
                      int dwRead = 123;                  byte[] DataBuffer = new byte[DataLength];
                      if (!_exitEvent.WaitOne(10, false))
                      {
                          _serialPort.Read(DataBuffer, 0, DataLength);
                          if (DataBuffer[0] == EquipMentId || IsFrist)
                          {
                              IsFrist = true;
                              try
                              {
                                  DataBuffer.CopyTo(ReadBuffer, _constPackNum);
                                  _constPackNum += DataLength;
                              }
                              catch
                              {
                                  IsFrist = false;
                                  _constPackNum = 0;
                              }
                          }                      OutPut("解析:" + BitConverter.ToString(DataBuffer, 0, DataLength) + "PackNum:" + _constPackNum.ToString() + ";" + DataLength.ToString());
                          if (_constPackNum >= dwRead)
                          {                          IsFrist = false;
                              ParaPack();
                              OutPut("成功数据包解析:" + BitConverter.ToString(ReadBuffer, 0, _constPackNum));
                              _constPackNum = 0;
                          }
                      }
    #if SerialPort
                    //_serialPort.DiscardInBuffer();
    #else
    #endif        }
            
                /// <summary>
            /// 打开串口
            /// </summary>
            /// <returns>成功返回True</returns>
            protected bool Init()
            {
                OutPut("正在打开串口");
                try
                {
                    LogHelper.WriteLog("尝试打开串口...:", ELogLevel.Error);
    #if SerialPort
                    _serialPort.PortName = _PortName;
                    _serialPort.BaudRate = _BaudRate;
                    _serialPort.DataBits = _DataBits;
                    _serialPort.StopBits = (StopBits)Enum.Parse(typeof(StopBits), _StopBits);
                    _serialPort.Parity = (Parity)Enum.Parse(typeof(Parity), _CheakWay);
                    _serialPort.ReadBufferSize = 500;
                    _serialPort.Open();
                    if (_serialPort.IsOpen)
                    {
                        LogHelper.WriteLog("成功.串口以打开", ELogLevel.Error);
                    }
    #else
                    _CommAPI.PortNum = 1;
                    _CommAPI.BaudRate = _BaudRate;
                    _CommAPI.ByteSize = 0x08;
                    _CommAPI.StopBits = 0x00;
                    _CommAPI.Parity = 0x00;
                    _CommAPI.ReadTimeout = 10;
                    _CommAPI.Open();
                    if (_CommAPI.Opened)
                    {
                        LogHelper.WriteLog("成功.串口以打开", ELogLevel.Error);
                    }
    #endif
                }
                catch (Exception ex)
                {
                    LogHelper.WriteLog("串口打开失败.原因:" + ex.Message, ELogLevel.Error);
                    return false;
                }
                return true;
            }        /// <summary>
            /// 输出程序调试日志
            /// </summary>
            /// <param name="Msg"></param>
            protected void OutPut(string Msg)
            {
                if (_OutPutLog)
                    LogHelper.WriteLog(Msg, ELogLevel.Error);
            }
                
        }
      

  3.   

    怀疑楼主的程序在收不到数据时已经down掉了
    整体做个异常记录看看
    本人是做电力子站的,向你学习!