C#为什么调试结果和实际运行结果不同?

用的Microsoft Visual Studio 2010,是关于串口调试助手接收到的数据换行的问题,
在调试的时候都正常,是在每句结尾插入换行符,但是实际运行就变成隔几个字符就出现一个换行,一条数据分了好几行,这是为什么呢?

5个回答

能帮我看看是哪里的问题么?代码如下:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Text.RegularExpressions;
using System.IO.Ports;

namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
// 关闭标志,表示串口正在关闭
private bool closing = false;

    //监听标志, 用于安全关闭串口  
    private bool listening = false;

    //累计发送字节  
    private long sendCount = 0;

    //累计接收字节  
    private long receiveCount = 0;

    //每次接收到的数据
    string data;

    //总的接收到的数据
    string sa = "";

    int b;
    int d;






    public Form1()
    {
        InitializeComponent();

    }

    //关闭串口按钮事件
    private void button1_Click(object sender, EventArgs e)
    {
        serialPort1.Close();
        Close();

    }

    //串口初始化
    private void Form1_Load(object sender, EventArgs e)
    {
        //设置默认属性
        if (comboBox_portName.Text == "")
            comboBox_portName.Text = "COM1";

        //查询电脑上的串口并显示在控件里
        foreach (string s in SerialPort.GetPortNames())
        {
            comboBox_portName.Items.Add(s);
        }

        //初始化combox2
        comboBox_rate.Items.Add("300");
        comboBox_rate.Items.Add("600");
        comboBox_rate.Items.Add("1200");
        comboBox_rate.Items.Add("2400");
        comboBox_rate.Items.Add("4800");
        comboBox_rate.Items.Add("9600");
        comboBox_rate.Items.Add("19200");
        comboBox_rate.Items.Add("38400");
        comboBox_rate.Items.Add("76800");
        comboBox_rate.Items.Add("115200");
        comboBox_rate.SelectedIndex = 5;


        serialPort1.DataReceived += new SerialDataReceivedEventHandler(serialPort1_DataReceived);
    }
    //打开串口 
    private void OpenSerialPort()
    {
        if (serialPort1.IsOpen)
        {
            return;
        }
        try
        {
            //根据comboBox设定串口名和波特率打开串口
            serialPort1.PortName = comboBox_portName.Text;
            serialPort1.BaudRate = int.Parse(comboBox_rate.Text);
            serialPort1.Open();
            if (serialPort1.IsOpen) //串口打开之后
            {
                button_openClosePort.Text = "关闭串口";
                Label_mainMessage.ForeColor = Color.Green;
                Label_mainMessage.Text = serialPort1.PortName + "已打开";
            }
        }
        catch //异常状态
        {
            Label_mainMessage.ForeColor = Color.Red;
            Label_mainMessage.Text = "串口打开失败!";
        }
    }


    //关闭串口  
    private void CloseSerialPort()
    {
        if (!serialPort1.IsOpen)
        {
            return;
        }
        try
        {
            closing = true;
            while (listening)
                Application.DoEvents();
            serialPort1.Close();
            closing = false;
            if (!serialPort1.IsOpen) //串口关闭之后
            {
                button_openClosePort.Text = "打开串口";
                Label_mainMessage.ForeColor = Color.Green;
                Label_mainMessage.Text = serialPort1.PortName + "已关闭";
            }
        }
        catch //异常状态
        {
            Label_mainMessage.ForeColor = Color.Red;
            Label_mainMessage.Text = "串口关闭失败!";
        }
    }
    bool IsBr = false;
    //显示接收数据并进行相应的格式转换
    private void DisplayText(object sender, EventArgs e)
    {
        string a;   //定义a存放每次接收到的数据        
        a = data;
        StringBuilder buildHexPlay = new StringBuilder();
        if (a.Length == 0)  //窗口为空,不需要转换  
            return;
        if (check_hexPlay.Checked)   //将字符转换为HEX格式显示  
        {

            char[] bufString = new char[a.Length];
            bufString = a.ToArray();
            foreach (char c in bufString)
            {
                if (c == '\n')
                    buildHexPlay.Append("0");
                buildHexPlay.Append(Convert.ToString(Convert.ToByte(c), 16) + " ");
            }
            a = buildHexPlay.ToString().ToUpper();
            sa += a; //用sa存放2次一共接收到的数据
            textBox_receive.Text = sa;
        }
        else  //将HEX转为字符显示  
        {
            textBox_receive.Text = textBox_receive.Text + data;

            //string[] bufString = new string[textBox_receive.Text.Length];
            //char[] split = { ' ', '\n', '\r' };    //将空格,回车符过滤,BUF:可能存在  
            //bufString = textBox_receive.Text.Trim().Split(split);
            //foreach (string ss in bufString)
            //{
            //    if (ss != "")  //由于有回车符"\r\n"存在,所以得到的SS可能为""  
            //        buildHexPlay.Append(Convert.ToChar(Convert.ToByte(ss, 16)));
            //}
            //textBox_receive.Text = textBox_receive.Text + data;
        }
        Label_receiveCount.Text = "接收字节:" + d;  //显示记数

    }


    private void button2_Click(object sender, EventArgs e)
    {
        if (!serialPort1.IsOpen) //判断串口是否打开
        {
            Label_mainMessage.ForeColor = Color.Red;
            Label_mainMessage.Text = "串口未打开!";
            return;
        }
        else
        {

            StringBuilder buildSend = new StringBuilder();
            int count = 0;
            //if (checkBox_hexSend.Checked)   //发送16进制 这里都需要16进制发送,所以不需要判断 
            {

                List<byte> bufferSend = new List<byte>();
                // buildSend.Clear();                   
                string sendSting =textBox_sendString.Text.Trim(); //删去前导和后置空格符  
                string s = "";
                while (sendSting.Length > 1)   //奇数个16进制数据最后一个被抛弃  
                {
                    s = sendSting.Substring(0, 2);
                    buildSend.Append(s + " ");
                    bufferSend.Add(Convert.ToByte(s, 16));   //将字符s 如“1A” 转化为字节31,送入字节列表BufferSend  
                    sendSting = sendSting.Remove(0, 2);
                    sendSting = sendSting.Trim();  //删去前导空格符  
                }
                //textBox_sendString.Text = buildSend.ToString().ToUpper(); //格式化显示发送的数据  
                serialPort1.Write(bufferSend.ToArray(), 0, bufferSend.ToArray().Length); //发送数据
                //计算发送字节数
                count = bufferSend.Count; 
                sendCount += count;
                Label_sendCount.Text = "发送字节:" + sendCount.ToString(); //显示记数

            }
            //else  //asc编码直接发送,发送字符  
            //{
            //      if (checkBox_sendNewLine.Checked)  //发送新行 
            //      { 
            //          serialPort1.WriteLine(textBox_sendString.Text); 
            //          count = textBox_sendString.Text.Length + 2; 
            //      } 
            //      else 
            //      {
            //    serialPort1.Write(textBox_sendString.Text);
            //count = textBox_sendString.Text.Length;
            //    }  
            //}
            //sendCount += count;
            //Label_sendCount.Text = sendCount.ToString();

        }
    }

    //接收事件
    void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
    {
        if (textBox_sendString.Text == "D1 FF" || textBox_sendString.Text == "D3 FF" || textBox_sendString.Text == "d1 ff" || textBox_sendString.Text == "d3 ff")
        {

                Byte[] receivedData = new Byte[serialPort1.BytesToRead];        //创建接收字节数组
                serialPort1.Read(receivedData, 0, receivedData.Length);         //读取数据
                //serialPort1.DiscardInBuffer();                                  //清空SerialPort控件的Buffer
                string strRcv = null;

                for (int i = 0; i < receivedData.Length; i++) //窗体显示
                {

                    strRcv += receivedData[i].ToString("X2") + " ";  //16进制显示
                }
                data = strRcv;
                b = receivedData.Length;
                d += b;
                data = strRcv + "\r\n";
                this.Invoke(new EventHandler(DisplayText));
            }

        else
        {
            data = serialPort1.ReadExisting(); //将接收到的数据传给data
            b = data.Length;
            d += b;
            data += "\r\n";
            this.Invoke(new EventHandler(DisplayText));
        }


    }


    //HEX显示按钮的格式转换,与显示接收事件中的一样
    private void check_hexPlay_CheckedChanged(object sender, EventArgs e)
    {
        StringBuilder buildHexPlay = new StringBuilder();
        if (textBox_receive.Text.Length == 0)  //窗口为空,不需要转换  
            return;
        if (check_hexPlay.Checked)   //将字符转换为HEX格式显示  
        {
            char[] bufString = new char[textBox_receive.Text.Length];
            bufString = textBox_receive.Text.ToArray();
            foreach (char c in bufString)
            {
                if(c == '\n')
                    buildHexPlay.Append("0");
                buildHexPlay.Append(Convert.ToString(Convert.ToByte(c), 16) + " ");
            }
            textBox_receive.Text = buildHexPlay.ToString().ToUpper();

        }
        else  //将HEX转为字符显示  
        {

            string[] bufString = new string[textBox_receive.Text.Length];
            char[] split = { ' ', '\n', '\r' };    //将空格,回车符过滤,BUF:可能存在  
            bufString = textBox_receive.Text.Trim().Split(split);
            foreach (string ss in bufString)
            {
                if (ss != "")  //由于有回车符"\r\n"存在,所以得到的SS可能为""  
                    buildHexPlay.Append(Convert.ToChar(Convert.ToByte(ss, 16)));
            }
            textBox_receive.Text = buildHexPlay.ToString();
        }
    }

    //打开/关闭串口按钮事件
    private void button_openClosePort_Click(object sender, EventArgs e)
    {
        if (button_openClosePort.Text == "打开串口")
            OpenSerialPort();
        else
            CloseSerialPort();  
    }

    //清除按钮事件
    private void buttonclear_Click(object sender, EventArgs e)
    {
        textBox_receive.Clear();
        d = 0;
        receiveCount = sendCount = 0; //清空计数器
        Label_receiveCount.Text = "接收字节:0";
        Label_sendCount.Text = "发送字节:0";  //清空记数显示
    }
}

}

这样的问题,只能分析代码。与时序相关!
能不能贴出代码呢?如果不能,可以试着在关键代码处增加一些 LOG 输出来分析问题,例如:写入换行符的判断处、接收到数据结尾处、等等

qq_24075209
qq_24075209 代码贴上去了。。能帮忙看一下么
接近 6 年之前 回复

说明你的程序在分析串口协议的时候有问题。
串口数据是一个一个发过来的。怎么建立缓冲区,怎么处理换行都要自己考虑,包括停止位、波特率这些有没有搞正确。
程序不正确不一定运行的时候能暴露出来,表现为时好时坏,所以你要耐心调试。

贴代码没有什么用,这种问题必须有硬件才好调试。

另外csdn的规则有问题,即便提问者自己可以采纳问题,起码采纳的要是问题的解决方案才可以。这种胡乱贴出一些代码采纳的,只能使得内容没有价值。

Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
立即提问
相关内容推荐