小弟正在学习C#中,不过近期要交一个作业,有关SerialPort的,也查了一些帖子,不过实在看不懂,还是把自己这个程序传上来求各位指点了。这里想要实现的是Modbus通信协议下的向串口收发数据,Modbus协议的子程序已经调试验证过了,没有问题,就是通过SerialPort收发数据的这个程序有问题,每次输入一组数据后,发送,就会出现类似死机现象,总之自己也觉得这个程序问题很大,还是请各位大虾指点啊,急需!!!namespace Strategy_Comm_02
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }                /*********************************************初始化串口信息*********************************************************************/
        private void initPortmessage(string baud, string databits, string portname)
        {
            serialPort.BaudRate = Convert.ToByte(baud);
            serialPort.DataBits = Convert.ToByte(databits);
            //serialPort.Parity = paritybox.Text;
            //serialPort.StopBits = (int)(stopbitsbox.Text);
            serialPort.PortName = portname;
        }        //*******************************************指令的标准输入为每个信息字符必须以两位的16进制数表示*******************************/
        private byte[] stringto16int(string str)
        {
            char[] cstr = str.ToCharArray();
            byte[] buf = new byte[1024];
            string ss;
            int j = 0;
            for (int i = 0; i < cstr.Length; i=i+2)                     //**********指令的标准输入为每个信息字符必须以两位的16进制数表示,范围0——F;
            {
                ss = Convert.ToString(cstr[i]) + Convert.ToString(cstr[i+1]);
                buf[j] = Convert.ToByte(ss);
                j++;
            }            return buf;
        }        
        /********************************************定时触发的发送/读取数据事件*********************************************************/
        private void serialPort_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
        {
           
            byte[] buffer1 = new byte[1024];       //=================根据通信协议规则生成的命令代码,将发送到缓冲区的内容
            byte[] buffer2 = new byte[1024];
            Modbus mmodbus = new Modbus();            byte[] command1 = new byte[1024];       //**********输入信号的命令
            byte[] command2 = new byte[1024];       //**********响应信号的命令
            command1 = stringto16int(readbox.Text);
            
            switch (command1[1])    //================ 根据功能位function code 决定执行读/写操作
            {
                case 3:            //=================function=0X03,即从寄存器中读取数据
                    {                        serialPort.Open();
                        buffer1 = mmodbus.asciiGetCommandSend(command1[0], command1[2], command1[3], command1[4], command1[5]); 
                        string sstr = Convert.ToBase64String(buffer1);
                        serialPort.WriteLine(sstr);                        Thread.Sleep(2000);                        command2 = Convert.FromBase64String(serialPort.ReadLine());
                        byte[] num = new byte[1024];
                        int j = 0;
                        for (int i = 4; i < command2.Length; i++)
                        {
                            num[j] = command2[i];
                            j++;
                        }                        buffer2 = mmodbus.asciiGetCommandResponse(command2[0], command2[2], num);                        if (buffer1[buffer1.Length - 2] != buffer2[buffer2.Length - 2])
                        {
                            MessageBox.Show("数据传输有误!");
                            break;
                        }                        string sres = "";
                        for (int i = 1; i < buffer2.Length - 2; i++)
                        {
                            sres += Convert.ToString(buffer2[i]);
                        }
                        responsebox.Text = sres;
                        serialPort.Close();
                        break;
                    }                case 6:          //=================function=0X03,即从寄存器中读取数据
                    {
                        serialPort.Open();
                        buffer1 = mmodbus.asciiPutCommandSend(command1[0], command1[2], command1[3], command1[4], command1[5]);
                        string sstr = Convert.ToBase64String(buffer1);
                        serialPort.WriteLine(sstr);                        Thread.Sleep(2000);                        command2 = Convert.FromBase64String(serialPort.ReadLine());
                        buffer2 = mmodbus.asciiPutCommandResponse(command2[0], command2[2], command2[3], command2[4], command2[5]);                        if (buffer1[buffer1.Length - 2] != buffer2[buffer2.Length - 2])
                        {
                            MessageBox.Show("数据传输有误!");
                            break;
                        }                        string sres = "";
                        for (int i = 1; i < buffer2.Length - 2; i++)
                        {
                            sres += Convert.ToString(buffer2[i]);
                        }
                        responsebox.Text = sres;
                        serialPort.Close();
                        break;
                    }            }            
            
        }        private void Form1_Load(object sender, EventArgs e)
        {
            initPortmessage(boudbox.Text, databitsbox.Text, portbox.Text);
        }    }
}

解决方案 »

  1.   

    在发送和接受的实践中,如果你要将接受到的信息显示在textbox中,要用到委托,否则会出现假死。
    responsebox.Invoke(new MethodInvoker(delegate{responsebox.Text=sres;}));
    这样就不会“假死”了
      

  2.   

    3Q,假死的问题解决了,非常感谢
    不过又有一个问题,command2 = Convert.FromBase64String(serialPort.ReadLine());提醒我“这个由于线程退出或应用程序请求,I/O 操作已中止。”,这个是怎么回事,我想在一个button_click事件中同时完成发出一条指令,并取得其设备相应指令,从中得到读取到得数据。