KyKiske22 2015-06-19 02:21 采纳率: 0%
浏览 781

求助 ,关于C# winform窗体串口在读取一组参数后再一次读取另一组参数的问题

有两个按钮,一个是“开启基本数据按钮设为button1”,另一个是“读取ListBox内部
数据的内容“设为button2,设定是先开启button1接收基本数据后才能开启button2接
收ListBox内的数据,接收协议一共有5位,分别是报头,符号位,数据位,数据位,校验位(没有长度位),当开启button1后界面上的基本数据的TextBox值会不断发生变化。
。当点击button2后(会有个“正在发送,请等待5s”的一个winform窗口弹出。当第二
次再次接收到数据后,会把协议转换成数据添加到ListBox中,但问题来了:为什么有时
点击button2后接收到的数据中ListBox的第一行数据有时是0没收到数据,有时候会读
到数???????????????????
我这里button1的基本原理是给控制器发送一个协议,控制器收到后吧几个基本数据的
协议发送给winform窗口并将协议转换为基本数据记录到TextBox内,这时数据是无限
接收的,从而几个基本数据会不断地有变化。button2和button1原理类似都是发送一
个协议而给ListBox发送数据,发送完成后退出窗口,ListBox的所有行的值都变化之后
继续接收button1的基础数据。
接收代码:
int S, A, B, C, D;
private List memory = new List(4096);
private byte[] bufferbyte = new byte[5];
private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
if (Closing) return;
Control.CheckForIllegalCrossThreadCalls = false;
int n = comm.BytesToRead;
Byte[] bytes = new Byte[n];
r_count += n;//记录接收的字节
comm.Read(bytes, 0, n);
try
{
this.Invoke((EventHandler)delegate
{
if (n > 0)
{
#region 协议解析/分析数据
//<协议解析>

bool data_1_catched = false;//缓存记录数据是否捕获到

memory.AddRange(bytes);//缓存数据
while (memory.Count >= 2)//至少要包含头(1字节)+校验(1字节)

{
if (memory[0] == 0x88)
{
if (memory.Count < 5)
break;
//<数据校验>
if ((memory[4] != (memory[1] + memory[2] + memory[3]) % 256) &&
(memory[4] != (memory[1] - 128 + memory[2] + memory[3]) % 256))
{
memory.RemoveRange(0, 5);
continue;
}
memory.CopyTo(0, bufferbyte, 0, 5);
data_1_catched = true;
memory.RemoveRange(0, 5);
//<分析数据>

if (data_1_catched)
{
#region 接收协议定义,用于将协议转化为数据
.............................
#endregion
#region 将基本数据转化并填充到TextBox
.............................
#endregion
#region 将ListBox数据协议转化并填充到ListBox
.............................
#endregion
}
}
});
Button1方法比较简单,就是两句话:
SendData("88", "FF", "01", "01", "01", 10);//是发送协议方法 周期为10ms
comm.DataReceived += new SerialDataReceivedEventHandler(serialPort1_DataReceived);

                    Button2方法:
                     private void ReadListBoxData_Click(object sender, EventArgs e)
                    {
                     WaitingForm waitf = new WaitingForm();
            waitf.ShowIcon = false;
            waitf.label1.Text = "正在处理,请稍后......";
            waitf.Show();
            //如果不加上此句话,新窗体加载的内容都在队列中等待而不会绘制,从而导致新窗体没有内容。加上的话,新窗体会重新绘制
            Application.DoEvents();
            for (int ti = 0; ti < 4; ti++)
            {
                SendData("88", "FF", "04", "04", "07", 1000);
            }
            Thread.Sleep(4000);
            if (IsNull(bufferbyte) == true)
            {
                MessageBox.Show("重复超时,重新读取");
            }
            waitf.Dispose();
                            //接受完ListBox的数据后,继续接收基本数据
                            SendData("88", "FF", "01", "01", "01", 10);//
         comm.DataReceived += new SerialDataReceivedEventHandler(serialPort1_DataReceived);
                    }
                    最大的问题再说一下,就是ListBox的第一行数据有的时候能收到数有时候收不到数,但是自己通过把数据转化到字符串框之后,发现第一列的协议都没有问题,

怀疑是和之前的基本数据协议的尾端发生冲突了,求解决办法??
现在有一个方法是协商控制器,在发送第一组数据之前添加个5位保护协议。有没有
更好的方法???

  • 写回答

1条回答 默认 最新

  • 你知我知皆知 2024-08-04 00:17
    关注

    以下回答参考 皆我百晓生券券喵儿 等免费微信小程序相关内容作答,并由本人整理回复。

    这个问题涉及到多个方面,包括通信协议、数据结构设计以及线程管理等。以下是一些建议来帮助你解决问题:

    1. 通信协议优化

      • 首先,检查你的通信协议是否有重叠的地方,例如在头部或校验位上。
      • 如果存在重叠,尝试调整协议格式以避免冲突。
    2. 数据结构与布局优化

      • 为了减少数据传输过程中的延迟,可以考虑使用更紧凑的数据结构,或者对数据进行压缩。
      • 在ListBox中,可能需要考虑如何有效地存储和组织数据,以便在多次接收之间保持一致性。
    3. 线程管理和同步

      • 使用锁机制或其他同步技术来确保在接收过程中只有一个线程能够访问数据缓冲区。
      • 对于多个线程之间的数据同步,可以考虑使用消息传递机制,例如信号量或条件变量。
    4. 错误处理

      • 在发送数据前,添加适当的错误处理逻辑,防止由于数据丢失或错误导致的数据不一致。
    5. 调试工具和日志

      • 使用调试工具和日志查看器来跟踪数据流,找出任何可能导致数据异常的情况。
    6. 代码审查

      • 寻找其他开发人员的意见和建议,他们可能会提供不同的视角和解决方案。
    7. 性能测试

      • 使用性能测试工具(如.NET Performance Profiler)来评估程序的性能,特别是对于复杂的数据交换情况。

    请注意,以上建议可能需要根据具体情况进行修改。如果你已经尝试了这些步骤,并且仍然遇到问题,可能需要进一步深入研究,例如调用堆栈追踪或使用调试助手。

    评论

报告相同问题?

悬赏问题

  • ¥30 求给定范围的全体素数p的(p-2)的连乘积
  • ¥15 VFP如何使用阿里TTS实现文字转语音?
  • ¥100 需要跳转番茄畅听app的adb命令
  • ¥50 寻找一位有逆向游戏盾sdk 应用程序经验的技术
  • ¥15 请问有用MZmine处理 “Waters SYNAPT G2-Si QTOF质谱仪在MSE模式下采集的非靶向数据” 的分析教程吗
  • ¥50 opencv4nodejs 如何安装
  • ¥15 adb push异常 adb: error: 1409-byte write failed: Invalid argument
  • ¥15 nginx反向代理获取ip,java获取真实ip
  • ¥15 eda:门禁系统设计
  • ¥50 如何使用js去调用vscode-js-debugger的方法去调试网页