【发布时间】:2018-11-04 13:23:56
【问题描述】:
我正在制作一个项目,该项目意味着 PIC18F4610 通过 Zigbee 无线 UART 与带有无线 Zigbee 模块的 USB 串行端口进行通信。当我按下 PIC 上的按钮时,它会向 USB 端口上的另一个 Zigbee 模块无线发送一个 10 字节的数据包(字节)。 它发送的数据包是 0A 01 80 90 A0 B0 C0 D0 E0 F0。 如果我在 PC 上使用任何像 RealTerm 这样的终端程序,我会收到发送的确切字节包。 但是,在我的程序中,我(通常)得到以下数据包: 3F 3F 0A 01 80 90 A0 B0 C0 D0 E0 F0 包括发送的良好数据包,但开头有两个 3F(即,发送的是 12 个字节而不是 10 个字节)。我可以通过程序来克服这个问题,但有时它只在开头放置一个 3F,而其他的它在数据包项目之间滑动一个 3F。没有丢包项,只是到处加3F(只有一两个),一般在开头。 我已经检查了编码,因为 3F 是当找不到一个字符进行编码时,但它似乎没问题,因为它确实收到了 F0。 串行端口在接收到发送的数据包时是打开的。它的配置:
ST.puertoserie.PortName = "COM1";
ST.puertoserie.BaudRate = 9600;
ST.puertoserie.Parity = (Parity) 1;
ST.puertoserie.DataBits = 8;
ST.puertoserie.StopBits = (StopBits) 1;
ST.puertoserie.Encoding = System.Text.Encoding.GetEncoding(28591);
已定义 DataReceived 事件处理程序,并在串行端口接收字节时触发。
ST.puertoserie.DataReceived += new SerialDataReceivedEventHandler(RecepcionBytePuertoSerie);
事件处理程序(ST 是我拥有的一个全局类,包括一些变量和串行端口):
private void RecepcionBytePuertoSerie(object sender, SerialDataReceivedEventArgs e)
{
while(ST.puertoserie.BytesToRead > 0) {
ST.rxcadena[ST.rxindex] = (byte) ST.puertoserie.ReadByte();
ST.rxindex++;
}
byte[] kprueba = new byte[ST.rxindex];
for (int t = 0; t < ST.rxindex; t++) { kprueba[t] = ST.rxcadena[t]; }
MessageBox.Show(BitConverter.ToString(kprueba).Replace("-", " ")); // Display bytes in message box
ST.rxindex = 0;
ST.puertoserie.DiscardInBuffer();
}
关于为什么会发生这种情况的任何线索?我已经尝试了各种各样的东西,但没有办法。终端仿真器正确接收。程序中必须有一些潜在的原因,等等。现在程序只用一个简单的形式来做这件事,直到我可以让串行通信工作。无线似乎不是问题(隐藏代码或任何东西),因为终端仿真器准确接收 PIC 发送的内容。由于终端仿真器正确接收,Windows 似乎也不是问题。 任何线索/帮助? 保罗
【问题讨论】:
-
它确实像编码问题一样大声嘎嘎,但 sn-p 无法解释。通过修复此代码中的可见错误来取得成功。您必须删除 DiscardInBuffer() 调用,它会随机丢弃数据。并且 ST.rxindex = 0 分配需要正确完成,现在它完全是偶然的。通过计算字节数或采用允许您始终检测消息的开始和结束的协议来做到这一点。
-
.NET
SerialPort类是我曾经使用过的 buggiest pieces of bad code 之一。有时它工作,有时它不 - 它与一些设备合作,而另一些则没有。不止一次,我不得不放弃它并转向不同的解决方案。可能是您的实现有问题,但我个人已经达到了SerialPort类的目的,我已经停止给予它怀疑的好处。 -
至少,根据上面的链接,尝试重写以避免使用
DataReceived事件和BytesToRead属性。如果您必须使用SerialPort类,最好将所有处理放入其自己的线程并运行循环以在该线程上同步服务端口。这可以让您绕过 .NET 类中最严重的问题。
标签: c#