请教一个串口的问题:我现在读串口的函数是这样的:  
/// <summary>
        /// 接收地址数据
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        public void DataReceivedAddress(object sender, SerialDataReceivedEventArgs e)
        {
            byte[] data = new byte[_com.BytesToRead];
            _com.Read(data, 0, data.Length);
            
            if (data.Length != 0)
            {                DisposeRecvDataAddress(data);            }
        }
       处理接收地址数据:
        /// </summary>
        /// <param name="strReceive"></param>
        public void DisposeRecvDataAddress(byte[] data)
        {
            string strReceive = "";
                for (int i = 0; i < data.Length; i++)
                {
                    strReceive += TenToHex(data[i].ToString());
                    
                }
                Receive_Data += strReceive; 
              
                if (Receive_Data.Length >= 48) 
                {
                       nFlag1 = Receive_Data.IndexOf("68");
                       strZC = Receive_Data.Substring(nFlag1 + 16, 2);
                         
                }
       }
我现在想通过strZC这个来判断,如果等于9C,此时就向串口中写数据,向串口中写数据的函数是这样的:
void write ()
{
          if (strZC == "9C")
                {
                    if (hh == number - 1)
                    {
                        hh = 0;
                    }
                    else
                    {
                        hh++;
                    }
                    _strStationAdd = strStationNew[hh];
                        string[] SendData = new string[12];
                        SendData[0] = "68";
                        SendData[1] = _strStationAdd.Substring(0, 2);
                        SendData[2] = _strStationAdd.Substring(2, 2);
                        SendData[3] = _strStationAdd.Substring(4, 2);
                        SendData[4] = _strStationAdd.Substring(6, 2);
                        SendData[5] = _strStationAdd.Substring(8, 2);
                        SendData[6] = _strStationAdd.Substring(10, 2);
                        SendData[7] = "68";
                        SendData[8] = "1C";
                        SendData[9] = "00";
                        SendData[10] = MeGetCrc(SendData, 10);//计算校验码CRC
                        SendData[11] = "16";
                        byte[] send = new byte[12];
                        send[0] = Convert.ToByte(SendData[0], 16);
                        send[1] = Convert.ToByte(SendData[1], 16);
                        send[2] = Convert.ToByte(SendData[2], 16);
                        send[3] = Convert.ToByte(SendData[3], 16);
                        send[4] = Convert.ToByte(SendData[4], 16);
                        send[5] = Convert.ToByte(SendData[5], 16);
                        send[6] = Convert.ToByte(SendData[6], 16);
                        send[7] = Convert.ToByte(SendData[7], 16);
                        send[8] = Convert.ToByte(SendData[8], 16);
                        send[9] = Convert.ToByte(SendData[9], 16);
                        send[10] = Convert.ToByte(SendData[10], 16);
                        send[11] = Convert.ToByte(SendData[11], 16);
                        _com.Write(send, 0, 12);
                      }
}
如果我把这个write函数直接加在
 strZC = Receive_Data.Substring(nFlag1 + 16, 2);这个语句后面串口就读不到数据了,请高人指点下,看这是为什么?以及如何解决?
 

解决方案 »

  1.   

    nFlag1可能为-1,这个时候能取到‘9C’吗?没取到自然_com.write();没有写进去了
      

  2.   

    byte[] data = new byte[_com.BytesToRead]; 
    _com.Read(data, 0, data.Length); 
    这样是不保证完全读取你的数据帧的内容,不信你自己可以测试,在上面代码后面添加
    int number=1;System.Dialognose.Debug.WriteLine(++number,data.Length);然后你发一帧,只发一帧数据,看看到底是分几次才接收完成的。这个也是调试过程中发现的问题 :)
      

  3.   

    1. 在strZC = Receive_Data.Substring(nFlag1 + 16, 2);后面加一条
       Console.WriteLine(strZC); 看是否存在 9C , 如果不存在,那说
       明你根本就没有捕获到相应的数据。
    2. 你的串口通讯协议是怎样的? 一般情况下接收之间有一个应答机制,
       也就是说设备发送数据出来会有一个超时时间,在指定的超时时间内你
       若没有发送数据到设备,那么设备就不再等待接收数据,而是继续发
       送数据。这样你就永远发送不了数据到设备。
       建议看一下串口协议中超时时间的设置,也很有可能是由这里引起的。
      

  4.   

    我以前弄过一个, 是使用线程来处理的, 希望对你有用:
            private void btnBegin_Click(object sender, EventArgs e)
            {
                switch (((Button)sender).Text)
                {
                    case "开 始":
                        mycom1.PortNum = this.cbCom.SelectedIndex + 1;              //串口号
                        if (!OpenCom())
                        {
                            return;
                        }
                        ((Button)sender).Text = "结 束";
                        this.thGetCard = new Thread(SendData);
                        this.thGetCard.Start();
                        break;
                    case "结 束":
                        if (mycom1.Opened)
                        {
                            mycom1.Close();         //关闭串口
                        }
                        if (this.thGetCard.IsAlive)
                            this.thGetCard.Abort();
                        ((Button)sender).Text = "开 始";
                        break;
                }
            }        private void SendData()      //发送数据
            {
                bool bSign;
                int sendnumb;
                while (true)
                {
                    bSign = false;
                    sendnumb = 0;
                    try
                    {
                        sendnumb = mycom1.Write(G_SendHead);    // 发送读数据指令
                        for (int i = 0; i < 3; i++)
                        {
                            G_RecvData = mycom1.Read(1);      // 取数据
                            if (G_RecvData[0].ToString("X2").Equals("CF"))
                            {     //如果取得想要的数据,则继续,否则循环发送读数据指令
                                bSign = true;
                                break;
                            }
                        }                    if (!bSign) continue;                    DateTime dt = DateTime.Now;
                        while (true)
                        {
                            TimeSpan tSpan = DateTime.Now - dt;
                            if (2000 < tSpan.Ticks) break;         //超时                        sendnumb = mycom1.Write(G_GetCard);   //继续发送读数据指令
                            G_RecvData = mycom1.Read(7);       //继续取数据                        //this.BeginInvoke(this.showResult, new object[] { this.txtMsg,
                            //    "\r\n接收到数据包:" + dis_package(G_RecvData) });                        if (GetCard(G_RecvData, ref CardNo))
                            {
                                this.BeginInvoke(this.showResult, new object[] { this.txtMsg,
                                CardNo.ToString()+"\r\n" });
                            }
                        }                }
                    catch   //(Exception ex)
                    {
                        //this.BeginInvoke(this.showResult, new object[] { this.txtMsg,
                        //        "\r\n捕获导常:" + ex.Message });
                    }
                }
            }
      

  5.   

    估计你的问题和我一样,你修改一下接收的顺序,可以参考我的帖子。http://topic.csdn.net/u/20091112/10/0b737603-fa54-4827-8327-071f5ed43e21.html?41998