用的Microsoft Visual Studio 2010,是关于串口调试助手接收到的数据换行的问题,
在调试的时候都正常,是在每句结尾插入换行符,但是实际运行就变成隔几个字符就出现一个换行,一条数据分了好几行,这是为什么呢?
能帮我看看是哪里的问题么?代码如下:
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 输出来分析问题,例如:写入换行符的判断处、接收到数据结尾处、等等
说明你的程序在分析串口协议的时候有问题。
串口数据是一个一个发过来的。怎么建立缓冲区,怎么处理换行都要自己考虑,包括停止位、波特率这些有没有搞正确。
程序不正确不一定运行的时候能暴露出来,表现为时好时坏,所以你要耐心调试。
贴代码没有什么用,这种问题必须有硬件才好调试。
另外csdn的规则有问题,即便提问者自己可以采纳问题,起码采纳的要是问题的解决方案才可以。这种胡乱贴出一些代码采纳的,只能使得内容没有价值。