首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > .NET > C# >

帮帮忙,串口通讯的有关问题,单步调试时正确接受回来12字节,但是正常运行时收回8字节

2011-12-31 
帮帮忙,串口通讯的问题,单步调试时正确接受回来12字节,但是正常运行时收回8字节! 下面是我写的类:usingSys

帮帮忙,串口通讯的问题,单步调试时正确接受回来12字节,但是正常运行时收回8字节!

下面是我写的类:
using   System;
using   System.Collections.Generic;
using   System.Text;
using   System.IO.Ports;
namespace   SRL
{
        ///   <summary>
        ///   串口控制
        ///   </summary>
        public   class   SerialPortControl

        {
                ///   <summary>
                ///   定义一个串口类
                ///   </summary>
                private       SerialPort     MyPort;

                ///   <summary>
                ///   初始化类
                ///   </summary>
                public   SerialPortControl()
                {
                        ResetPort();
                }
                ///   <summary>
                ///   直接使用给某个串口
                ///   </summary>
                ///   <param   name= "port "> COM1,COM2。。。。。。 </param>
                public     SerialPortControl(string   port)
                {
                        _portname   =   port;
                        ResetPort();

                }
                ///   <summary>
                ///   重新设置本串口控制类
                ///   </summary>
                private   void   ResetPort()
                {

                        if   (_portname   !=   null   )//串口名不能为空。
                        {
                                if   (_portname.ToUpper().IndexOf( "COM ")   >   -1)
                                {
                                        MyPort   =   new   SerialPort(_portname);//
                                        MyPort.DataReceived   +=   new   SerialDataReceivedEventHandler(DataReceived);


                                        MyPort.StopBits   =     StopBits.One   ;
                                        MyPort.Parity   =   Parity.None;
                                       
                                }
                        }
                }

                private   string     _portname;


                ///   <summary>
                ///   端口名称
                ///   </summary>
                ///   <example> COM1   COM2 </example>
                public   string     PortName
                {
                        get   {   return   _portname;   }
                        set   {   _portname   =   value;   ResetPort();   }
                }
                public   Exception   LastException;

                ///   <summary>
                ///   检测串口是否正常
                ///   </summary>
                ///   <returns> 如果正常,返回true   ,如果不正常返回false,并且把异常信息返回在   LastException属性   </returns>
                public   bool   PortIsOK()
                {

                        try
                        {
                                if   (true   ==   MyPort.IsOpen)   {   MyPort.Close();   }
                                MyPort.PortName   =   _portname;
                                MyPort.Open();
                                MyPort.Close();
                                return   true;
                        }
                        catch   (Exception   e)


                        {
                                this.LastException   =   e;
                                return   false;
                        }
                }

                ///   <summary>
                ///   最后收到的信息
                ///   </summary>
                public   string   LastReceived  
                {
                        get   {   return   hex_return;   }

                }
                public   bool   Received   =   false;//是否收到了信息。   发送完数据,如果需要车检器返回数据,该属性设置为false;
                                                            //当收到消息,并解析完成后。这个设置为true;
                string   hex_return   =   " ";//收到数据后把十六进制存到这个字符串中。


                ///   <summary>
                ///   向端口中发送命令。
                ///   </summary>
                ///   <param   name= "cmdstring "> "0A   46   0B   31   30   30   32   35 " </param>
                ///   <example>     Send( "0A   46   0B   31   30   30   32   35 ") </example>
                ///   <remarks> 超时设置为5秒,一般来说,端口速度不会延时超过1秒。 </remarks>
                public     string     Send(string   cmdstring)
                {
                        return   Send(cmdstring,   0);
                }
                ///   <summary>
                ///   向端口中发送命令。
                ///   </summary>
                ///   <param   name= "cmdstring "> "0A   46   0B   31   30   30   32   35 " </param>
                ///   <param   name= "timeout "> 指定超时,按秒计算。端口速度一般不会迟延超过1秒。 </param>
                ///   <example>     Send( "0A   46   0B   31   30   30   32   35 ") </example>


                public     string   Send(string   cmdstring,   double   timeout)
                {

                        byte[]   buff   =   HexStringToBinary(cmdstring.Trim());
                        MyPort.Open();
                        //MyPort.DiscardInBuffer();
                        MyPort.DiscardInBuffer();
                        cc   =   0;
                        hex_return   =   " ";
                        MyPort.Write(buff,   0,   buff.Length);
                     
                        /////////////////////////////
               
                        double   tmpx   =   DateTime.Now.TimeOfDay.TotalSeconds;
                        Received   =   false;
                        do
                        {
                                //   System.Windows.Forms.Application.DoEvents();
                        }   while   ((Received!=true     ))   ;//&&   (DateTime.Now.TimeOfDay.TotalSeconds   -   tmpx <timeout));
                        Console.WriteLine(cc);
                        return   hex_return;
                }


                int   cc   =   0;
                ///   <summary>
                ///   如果接受到了数据。
                ///   </summary>
                ///   <param   name= "sender "> 发送者 </param>
                ///   <param   name= "e "> 时间参数 </param>
                private       void   DataReceived(object   sender,   System.IO.Ports.SerialDataReceivedEventArgs   e)
                {
                        int   n   =MyPort.BytesToRead;
                        byte[]   binary   =   new   byte[n];


                        MyPort.Read(binary,   0,   n);
                        hex_return   +=   BinaryToHexString(binary);
                   
                        MyPort.Close();
                        Console.WriteLine(String.Format( "bytestoread:{0},内容:{1} ",   n,   hex_return));
                        Received   =   true;
                        cc   +=1;
                }


                ///   <summary>
                ///   16进制字符串转换为二进制数组
                ///   </summary>
                ///   <param   name= "hexstring "> 字符串每个字节之间都应该有空格,大多数的串口通讯资料上面的16进制都是字节之间都是用空格来分割的。 </param>
                ///   <returns> 返回一个二进制字符串 </returns>
                public   static   byte[]   HexStringToBinary(string   hexstring)
                {
                        string[]   tmpary   =   hexstring.Split( '   ');
                        byte[]   buff   =   new   byte[tmpary.Length];
                        for   (int   i   =   0;   i   <   buff.Length   ;   i++)
{
                                buff[i]   =   Convert.ToByte(tmpary[i],   16);
}
                        return   buff;
                }
                ///   <summary>
                ///   把二进制转换为十六进制字符串。
                ///   </summary>
                ///   <param   name= "buff "> 要被转换的二进制数组 </param>
                ///   <returns> 返回十六进制字符串,以空格隔开每个字节   。 </returns>
                public   static   string   BinaryToHexString(byte[]   buff)
                {
                        string   tmpstring   =   " ";
                        foreach   (byte   var   in   buff)
                        {


                                tmpstring   += "   "   +   Convert.ToString(var,   16);
                        }
                        return   tmpstring.Trim().ToUpper();
                }
        }
}


这是调用的地方。
  private   void   button1_Click(object   sender,   EventArgs   e)
                {
                        //SerialPortControl.PortControl.WriteCommand( "0A   46   0C   31   30   30   32   35 ");

                        SRL.SerialPortControl   pc   =   new   SRL.SerialPortControl( "COM1 ");      
                        if   (pc.PortIsOK()   ==   true)
                        {


                                string   rt   =   pc.Send( "16   16   02   10   01   01   00   02   03   17   00 ");

                                        MessageBox.Show(rt);
                           

                        }                  
                }

这个是控制一种车检器的命令。   16   16   02   10   01   01   00   6C   03   81   00     命令用来发送命令。   16   16   02   10   01   02   00   6D   21   03   A4   00     是应该得到的。我使用串口工具返回的都是正确。   在单步运行时也正确,就是在正常运行时会出现这种情况。   不知道什么原因。   拜托各位高手帮个忙。  


[解决办法]
郁闷 看不懂 LZ 你才是高手 呵呵
[解决办法]
加大接收缓冲试试
[解决办法]
学习
[解决办法]
string[] tmpary = hexstring.Split( ' ');
byte[] buff = new byte[tmpary.Length]; // 和这里不相符和,传的和接受的大小不同
for (int i = 0; i < buff.Length ; i++)
{
buff[i] = Convert.ToByte(tmpary[i], 16); //这里 有问题,
}
return buff;

[解决办法]
单步调试时正确接受回来12字节,但是正常运行时收回8字节
===============================================================
程序运行前加等待时间..
或者如CathySun118(斯年)所说,缓冲区的问题..
[解决办法]
--

热点排行