C#串口的奇怪行为

时间:2017-11-13 18:40:15

标签: c# serial-port

我从简单的程序中得到奇怪的行为,我正在用它来学习如何使用串口。该表单只有一个串口控件和一个TextBox。因为它只是一个测试程序,所以我禁用了线程调用检查。 我忘了提到,我正在使用微控制器发送1000字节的数据(读取EEPROM)。 奇怪的是,当我读取数据并将其直接附加到DataReceived事件中的文本框时,一切都很好,但是当我第一次将值传递给int []数组时,然后使用循环将它们转换为HEX格式的字符串并将它们附加到TextBox,值之间有一些零。

一些带有结果的代码。

案例1:读取数据并直接附加到TextBox

private void sp1_DataReceived(object sender, SerialDataReceivedEventArgs e)
    {
        while (sp1.BytesToRead > 0)
        {
            textBox1.AppendText(sp1.ReadByte().ToString("X")+ " ");
        }

    }

结果是(好吧,部分内容,正如我所说,有1000个字节需要接收......)

0 1 2 3 4 5 6 7 8 9 A B C D E F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F 60 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F 70 71 72 73 74 75 76 77 78 79 7A 7B 7C 7D 7E 7F 80 81 82 83 84 85 86 87 88 89 8A 8B 8C 8D 8E 8F 90 91 92 93 94 95 96 97 98 99 9A 9B 9C..... and so on

案例2:首先将值存储到int数组中,然后将它们转换为字符串,并附加到TextBox

 private void sp1_DataReceived(object sender, SerialDataReceivedEventArgs e)
    {
        int[] buffer = new int[1000];
        int i = 0;
        while (sp1.BytesToRead > 0)
        {
            //textBox1.AppendText(sp1.ReadByte().ToString("X")+ " ");
            buffer[i] = sp1.ReadByte();
            i++;
        }
        int j = 0;
        while (j < 1000)
        {
            textBox1.AppendText(buffer[j].ToString("X"));
            j++;
        }

我在随机位置获得了很多0,并且它读取的数据比循环中的1000多了

0123456789ABCDEF101112131415161718191A1B1C1D1E1F00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C7D7E7F808182838485868788898A8B8C8D8E8F909192939495969798999A9B9C9D9E9FA0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6C7C8C9CACBCCCDCECFD0D1D2D3D4D5D6D7D8D9DADBDCDDDEDFE0E1E2E3E4E5E6E7E8E9EAEBECEDEEEFF0F1F2F3F4F5F6F7F8F9FAFBFCFDFEFF0123456789ABCDEF101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C7D7E7F808182838485868788898A8B8C8D8E8F909192939495969798999A9B9C9D9E9FA0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6C7C8C9CACBCCCDCECFD0D1D2D3D4D5D6D7D8D9DADBDCDDDEDFE0E1E2E3E4E5E6E7E8E9EAEBECEDEEEFF0F1F2F3F4F5F6F7F8F9FAFBFCFDFEFF0123456789ABCDEF101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C7D7E7F808182838485868788898A8B8C8D8E8F909192939495969798999A9B9C9D9E9FA0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6C7C8C9CACBCCCDCECFD0D1D2D3D4D5D6D7D8D9DADBDCDDDEDFE0E1E2E3E4E5E6E7E8E9EAEBECEDEEEFF0F1F2F3F4F5F6F7F8F9FAFBFCFDFEFF0123456789ABCDEF101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C7D7E7F808182838485868788898A8B8C8D8E8F909192939495969798999A9B9C9D9E9FA0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6C7C8C9CACBCCCDCECFD0D1D2D3D4D5D6D7D8D9DADBDCDDDEDFE0E1E2E3E4E5E6E7000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

这种奇怪行为可能是什么原因? 提前致谢

1 个答案:

答案 0 :(得分:1)

sp1_DataReceived通常不会被调用一次。通常,您的计算机处理收到的数据的速度比收这意味着在某些时候循环

while (sp1.BytesToRead > 0)
在收到所有1000个字节之前剩下

。不久之后,sp1_DataReceived再次被调用,因为现在有更多的1000字节可用。由于您的第一个实现只附加了字符,因此它很重要。但是您的第二个实现会有所不同,因为您总是在文本中附加1000个字符。这可能会导致1000个字符的倍数结果,并附加零。

要解决您的问题,您需要组合多个事件的字节。一种解决方案可能是使用像

这样的列表
private List<byte> buffer = new List<byte>();
private void sp1_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
    while (sp1.BytesToRead > 0)
    {
        buffer.Add(sp1.ReadByte());
    }

    //Print if all bytes are available
    if (buffer.Count >= 1000)
    {
        //Join the bytes to a string using LINQ
        textBox1.Text = String.Join("", buffer.Select(b => b.ToString("X")));
        buffer.Clear();
    }
}

或类似

的数组
private byte[] buffer = new byte[1000];
private int bufferIndex = 0;
private void sp1_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
    while (sp1.BytesToRead > 0 && bufferIndex  < 1000)
    {
        buffer[bufferIndex ] = sp1.ReadByte();
        bufferIndex ++;
    }

    //Print if all bytes are available
    if (bufferIndex  >= 1000)
    {
        //Join the bytes to a string using LINQ
        textBox1.Text = String.Join("", buffer.Select(b => b.ToString("X")));
        bufferIndex = 0;
    }
}

请注意,这只是一些想法和示例实现。由于我不知道您是否也在端口接收其他消息,因此无法提供完美的合适解决方案来解决您的问题。