我有一个微控制器项目向我的 PC 发送长度为 8 字节的串行数据帧,我使用 PC 串行监视器工具监视来自微控制器的数据帧,所有数据看起来都不错,每个 8 字节帧似乎一直在发送此模式中的数据长度为 8 字节。
我遇到的问题如下:
每次我读取串行数据时,结构的 8 字节数据帧中的第一个字节都不存在。
例子:
每个循环如下:
微控制器发送 8 字节帧:01 FF 8E 01 00 00 00 0A
第一次循环迭代。
.NET 串行端口接收数据帧:01 00 00 00 00 00 00 00
读取(buff, 0, 8); 读取 1 字节读取
第二次循环迭代。
.NET 串行端口接收数据帧:FF 8E 01 00 00 00 0A 00 (7 字节读取)
读取(buff, 0, 8); 读取 7 字节读取
我期望 sr.Read(buff, 0, 8) 在每次循环迭代时总是读取 8 字节的长度。
这是我用来从串行端口读取的代码
static void Main(string[] args)
{
using (SerialPort sr = new SerialPort("COM5"))
{
sr.BaudRate = 9600;
sr.DataBits = 8;
sr.Parity = Parity.None;
sr.StopBits = StopBits.One;
sr.Open();
StringBuilder sb = new StringBuilder();
while (true)
{
byte[] buff = new byte[8];
int r = sr.Read(buff, 0, 8);
Console.WriteLine("Number of bytes read : " + r);
for (int i = 0; i < buff.Length; i++)
{
var hex = string.Format("{0:x2}", buff[i]);
sb.Append(hex.ToUpper());
sb.Append(" ");
}
Console.WriteLine(sb);
sb.Clear();
}
}
先感谢您。
感谢您的反馈,每个人都非常有用。
我为 8 字节帧重构了缓冲逻辑,如下所示:
一切似乎都与我从端口监视器上看到的数据模式同步,最重要的是,来自微控制器的数据模式。
仍然缺少重要方面:
- 帧 CRC。
- 验证每个字节的顺序。
.......等等
这是更新的代码
static void Main(string[] args) { using (SerialPort sr = new SerialPort("COM5")) { sr.BaudRate = 9600; sr.DataBits = 8; sr.Parity = Parity.None; sr.StopBits = StopBits.One; sr.Handshake = Handshake.None; sr.DtrEnable = false; sr.Open(); sr.ReceivedBytesThreshold = 1; StringBuilder sb = new StringBuilder(); byte[] buff = new byte[8]; byte[] temp_buffer = new byte[8]; while (true) { int r = sr.Read(temp_buffer, 0, 8); Console.WriteLine("Number of bytes read : " + r); // 1 - byte from the serial frame ? if (r == 1) { buff[0] = temp_buffer[0]; } // 7 - bytes from the serial frame ? if (r == 7) { // get the remaining 7 - bytes for (int i = 0; i <= temp_buffer.Length - 1; i++) { if (i != 0) buff[i] = temp_buffer[i]; // construct a complete frame } // okay, we ready to display the 8-byte serial frame. for (int i = 0; i < buff.Length; i++) { var hex = string.Format("{0:x2}", buff[i]); sb.Append(hex.ToUpper()); sb.Append(" "); } Console.WriteLine(sb); sb.Clear(); } } } }
这里还有一个修改版本,读取一个 16 字节的串行帧。
using (SerialPort sr = new SerialPort("COM5"))
{
sr.BaudRate = 9600;
sr.DataBits = 8;
sr.Parity = Parity.None;
sr.StopBits = StopBits.One;
sr.Open();
sr.ReceivedBytesThreshold = 1;
StringBuilder sb = new StringBuilder();
byte[] io_buffer = new byte[16];
byte[] temp_buffer = new byte[16];
do
{
int data_length = sr.Read( temp_buffer, 0, 16 );
// 1 - Byte from the serial frame ?
if ( data_length == 1 && temp_buffer[ 0 ] == 0x28 )
{
io_buffer[ 0 ] = temp_buffer[ 0 ];
}
// 15 - Bytes from the serial frame ?
if (data_length == 15 && temp_buffer[14] == 0x29)
{
// Here we construct the 16- byte frame.(start from 1 as we already have our start frame stored) "x028" => ")"
for ( int i = 1; i < temp_buffer.Length; i++ )
{
io_buffer[ i ] = temp_buffer[ i - 1 ];
}
// okay, we ready to display the 16-byte serial frame.
for ( int i = 0; i < io_buffer.Length; i++ )
{
var hex = string.Format( "{0:x2}", io_buffer[ i ] );
sb.Append( hex.ToUpper() );
sb.Append( " " );
}
Console.WriteLine(sb);
sb.Clear();
}
} while (sr.IsOpen);
这里是16字节的帧输出,第4字节表示从(I/O 4通道模数转换器)的通道0到3
28 FF FF 00 01 DB 00 00 00 00 00 00 0E 00 00 29
28 FF FF 01 01 02 00 00 00 00 00 00 0E 00 00 29
28 FF FF 02 01 02 00 00 00 00 00 00 0E 00 00 29
28 FF FF 03 01 A8 00 00 00 00 00 00 0E 00 00 29