.NET 中的串行端口通信

发布于 2024-09-04 10:21:58 字数 350 浏览 4 评论 0原文

我正在使用 C# 从串行端口接收数据,但存在一些问题。我对此很陌生,所以我需要一些帮助。

  1. 首先我想知道哪些函数是事件驱动的:

    读取现有()
    读()
    读取字节() 
    读取字符()
    读取行()
    读到()
    
  2. 如何从该端口的输入流中获取所需的数据?

    我有静态大小的协议。我可以使用特殊的字符来指定协议数据的限制吗?哪个字符适合此目的?

  3. 如何处理此异常:

    <块引用>

    C# SerialPort System.ObjectDisposeException,System.DLL 中的安全句柄已关闭

I am using C# to receive data from a serial port but there are some problems. I'm new to this so I need some help.

  1. First off all I want to know which functions are event driven:

    ReadExisting()
    Read()
    Readbyte() 
    Readchar()
    ReadLine()
    Readto()
    
  2. How can I take the required data form input stream of this port?

    I have static sized protocols. Can I use a special char to specify limits of a protocol data, and which will be a suitable char for this?

  3. How do I handle this exception:

    C# SerialPort System.ObjectDisposedException, safe handle has been closed in System.DLL

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

南城旧梦 2024-09-11 10:21:59

这些方法都不是“事件驱动的”,您可以在 DataReceived 事件中使用它们。当串行端口至少有一个字节的数据可供读取时调用。

不确定“静态大小”是什么意思。如果设备发送固定数量的字节,那么您将使用 Read() 方法来读取它们。请注意返回值,您将仅获得可用的字节数。将它们存储在 byte[] 中,并在下一个 DR 事件中附加到该字节,直到获得全部。

如果设备发送字符而不是字节,那么您通常可以利用 NewLine 属性。将其设置为终止响应的字符或字符串。换行符(“\n”)是迄今为止最典型的选择。使用 ReadLine() 读取响应。在这种情况下不需要缓冲。

当您关闭表单但不确保设备停止发送数据时,您将收到 ObjectDispose 异常。确保在 DataReceived 事件中仅使用 BeginInvoke,而不是 Invoke。如果表单的 IsDispose 属性为 true,则不要调用 BeginInvoke。

None of these methods are "event driven", you'd use them in the DataReceived event. Which is called when the serial port has at least one byte of data available to read.

Not sure what "static sized" means. If the device sends a fixed number of bytes then you'd use the Read() method to read them. Pay attention to the return value, you'll get only as many bytes as are available. Store them in a byte[] and append to that in the next DR event until you've got them all.

If the device sends characters rather than bytes then you can usually take advantage of the NewLine property. Set it to the character or string that terminates the response. A linefeed ("\n") is by far the most typical choice. Read the response with ReadLine(). No buffering is required in that case.

You'll get the ObjectDisposed exception when you close a form but don't ensure that the device stops sending data. Be sure to use only BeginInvoke in the DataReceived event, not Invoke. And don't call BeginInvoke if the form's IsDisposed property is true.

苏大泽ㄣ 2024-09-11 10:21:59

我无法对汉斯的回答添加任何内容,只能说我见过的最大陷阱之一是人们倾向于期望当 DataReceived 事件触发时,他们想要接收的所有字节都存在。

例如,如果您的消息协议长度为 20 个字节,则将触发 DataReceived 事件,并且您尝试读取 20 个字节。他们可能都在那里,也可能不在那里。很可能不会,具体取决于您的波特率。

您需要检查正在读取的端口的 BytesToRead 属性,并将该数量读入缓冲区。如果有更多字节可用,DataReceived 事件将再次触发。

请注意,当要接收的字节数至少等于串行端口的 ReceivedBytesThreshold 属性时,将触发 DataReceived 事件。默认情况下,我认为该值设置为 1。

例如,如果将其设置为 10,则当有 10 个或更多字节等待接收时,该事件将触发,但不少于。这可能会或可能不会导致问题,我个人倾向于将此属性值设置为 1,以便所有接收到的数据都将触发该事件,即使只接收到 1 个字节。

不要犯这样的错误:这将导致事件为收到的每个字节而触发 - 它不会这样做。

I can't add anything much to Hans' answer except to say that one of the biggest traps I have seen is that people tend to expect that when the DataReceived event fires, all of the bytes they would like to receive are all present.

e.g. if your message protocol is 20 bytes long, the DataReceived event fires and you try to read 20 bytes. They may all be there, they may not. Pretty likely that they won't be, depending on your baud rate.

You need to check the BytesToRead property of the port you are reading from, and Read that amount into your buffer. If and when more bytes are available, the DataReceived event will fire again.

Note that the DataReceived event will fire when the number of bytes to receive is at least equal to the ReceivedBytesThreshold property of the serial port. By default I believe this is set to a value of 1.

If you set this to 10 for example, the event will fire when there are 10 or more bytes waiting to be received, but not fewer. This may or may not cause problems, and it is my personal preference to leave this property value set to 1, so that all data received will fire the event, even if only 1 byte is received.

Do not make the mistake that this will cause the event to fire for every single byte received - it won't do that.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文