C# C通过串口发送数据,字节数组中的数据接收不完整
我正在开发一个GUI界面,它接收来自ATmega8A的信息。 GUI中的以下代码必须执行以下操作: Check Header:在这里,我将数据读入字节数组Byte[]测试,该测试将根据OxFF进行检查 如果header==0xFF,则读取第二个字节数组byte[]数据 请参阅下面的代码 现在,我有以下问题。如果我只发送一个数字,例如1,则该数字将显示在textBox1中,没有任何问题。然而,如果我试图发送一个像433这样的号码,我总是收到4,33正在丢失。我假设这是因为我的includeif语句,但我无法解释为什么数据会丢失C# C通过串口发送数据,字节数组中的数据接收不完整,c#,arrays,serial-port,buffer,data-loss,C#,Arrays,Serial Port,Buffer,Data Loss,我正在开发一个GUI界面,它接收来自ATmega8A的信息。 GUI中的以下代码必须执行以下操作: Check Header:在这里,我将数据读入字节数组Byte[]测试,该测试将根据OxFF进行检查 如果header==0xFF,则读取第二个字节数组byte[]数据 请参阅下面的代码 现在,我有以下问题。如果我只发送一个数字,例如1,则该数字将显示在textBox1中,没有任何问题。然而,如果我试图发送一个像433这样的号码,我总是收到4,33正在丢失。我假设这是因为我的includeif语句
namespace RS232
{
public partial class fclsRS232Tester : Form
{
string InputData = String.Empty;
string initText = "waiting...";
delegate void SetTextCallback(string text);
public fclsRS232Tester()
{
InitializeComponent();
// Nice methods to browse all available ports:
string[] ports = SerialPort.GetPortNames();
// Add all port names to the combo box:
foreach (string port in ports)
{
cmbComSelect.Items.Add(port);
}
cmbBaud.Items.Add(2400);
cmbBaud.Items.Add(9600);
cmbComSelect.SelectedIndex = 0;
cmbBaud.SelectedIndex = 1;
button4.Enabled = false;
textBox1.Text = initText;
textBox2.Text = initText;
}
private void cmbComSelect_SelectionChangeCommitted(object sender, EventArgs e)
{
if (port.IsOpen) port.Close();
port.PortName = cmbComSelect.SelectedItem.ToString();
stsStatus.Text = port.PortName + ": 9600,8N1";
// try to open the selected port:
try
{
port.Open();
button4.Enabled = true;
textBox1.Clear();
textBox2.Clear();
}
// give a message, if the port is not available:
catch
{
MessageBox.Show("Serial port " + port.PortName + " cannot be opened!", "RS232 tester", MessageBoxButtons.OK, MessageBoxIcon.Warning);
cmbComSelect.SelectedText = "";
stsStatus.Text = "Select serial port!";
}
}
private void port_DataReceived_1(object sender, SerialDataReceivedEventArgs e)
{
int bytenumber;
int bufferSize = port.BytesToRead;
byte[] test = new byte[1];
byte[] data = new byte[bufferSize];
byte[] data2 = new byte[bufferSize];
port.Read(test, 0, 1);
if (test[0] == 0xFF) //Receive X-andY- coordinates from MCU and plot the coordinates
{
bytenumber = port.Read(data, 0, bufferSize);
string info = System.Text.Encoding.ASCII.GetString(data);
this.Invoke((MethodInvoker)delegate
{
this.txtIn.Text += info;
}
}
}
}
只要接收的缓冲区中有可用的数据,就会调用DataReceived处理程序。所以,在接收到下一个突发数据之前,读取缓冲区中的所有数据,然后处理报头的有效性等。一旦收到新数据,旧数据就会被过度写入,导致数据丢失。 在您的情况下,调用port.Read仅读取1字节。我会将其更改为port.Readtest,0,bufferSize
此外,我只需将数据存储在缓冲区中,并在单独的线程上运行数据处理。在处理程序中花费的时间越多,丢失数据的可能性就越大。通过将所有数据存储到缓冲区,问题得到了解决: 私有无效端口\u DataReceived \u 1对象发送方,SerialDataReceivedEventArgs e { int字节数; 字节[]数据=新字节[10]
bytenumber = port.Read(data, 0, 10);
if (data[0] == 0xFF)
{
}
}
等等。端口包含什么类型的对象?我用以下方式定义了端口:InitializeComponent;//浏览所有可用端口的好方法:string[]ports=SerialPort.GetPortNames;//将所有端口名称添加到组合框中:foreach string port in ports{cmbComSelect.Items.Addport;}这不能是该方法中使用的端口。该变量仅存在于foreach的作用域中,并且字符串没有任何BytesToRead属性或Read方法。这完全是出于设计,您只能获得接收缓冲区中可用的字节数。通常不超过一个或两个。您必须更改代码,以便不启动处理数据,直到收到所有数据。