简体   繁体   English

.NET中的串口通信

[英]Serial port communication in .NET

I am using C# to receive data from a serial port but there are some problems. 我使用C#从串口接收数据,但存在一些问题。 I'm new to this so I need some help. 我是新手,所以我需要一些帮助。

  1. First off all I want to know which functions are event driven: 首先,我想知道哪些函数是事件驱动的:

    \nReadExisting() ReadExisting()\nRead() 读()\nReadbyte() Readbyte() \nReadchar() Readchar()\nReadLine() 的ReadLine()\nReadto() Readto()\n
  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 C#SerialPort System.ObjectDisposedException,安全句柄已在System.DLL中关闭

None of these methods are "event driven", you'd use them in the DataReceived event. 这些方法都不是“事件驱动的”,您可以在DataReceived事件中使用它们。 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. 如果设备发送固定数量的字节,那么您将使用Read()方法读取它们。 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. 将它们存储在byte []中并在下一个DR事件中追加到它,直到你得到它们为止。

If the device sends characters rather than bytes then you can usually take advantage of the NewLine property. 如果设备发送字符而不是字节,那么您通常可以利用NewLine属性。 Set it to the character or string that terminates the response. 将其设置为终止响应的字符或字符串。 A linefeed ("\\n") is by far the most typical choice. 换行(“\\ n”)是目前最典型的选择。 Read the response with ReadLine(). 使用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. 关闭表单但不确保设备停止发送数据时,您将获得ObjectDisposed异常。 Be sure to use only BeginInvoke in the DataReceived event, not Invoke. 确保在DataReceived事件中仅使用BeginInvoke,而不是Invoke。 And don't call BeginInvoke if the form's IsDisposed property is true. 如果表单的IsDisposed属性为true,则不要调用BeginInvoke。

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. 我不能对Hans的回答添加任何内容,只是说我见过的最大陷阱之一是人们倾向于期望当DataReceived事件触发时,他们想要接收的所有字节都存在。

eg if your message protocol is 20 bytes long, the DataReceived event fires and you try to read 20 bytes. 例如,如果您的消息协议长度为20个字节,则会触发DataReceived事件并尝试读取20个字节。 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. 您需要检查正在读取的端口的BytesToRead属性,并将该数量读入缓冲区。 If and when more bytes are available, the DataReceived event will fire again. 如果有更多字节可用,DataReceived事件将再次触发。

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. 请注意,当接收的字节数至少等于串行端口的ReceivedBytesThreshold属性时,将触发DataReceived事件。 By default I believe this is set to a value of 1. 默认情况下,我认为这个值设置为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. 例如,如果将此值设置为10,则等待接收10个或更多字节时会触发事件,但不会更少。 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. 这可能会也可能不会导致问题,我个人倾向于将此属性值设置为1,这样即使只收到1个字节,所有收到的数据也会触发事件。

Do not make the mistake that this will cause the event to fire for every single byte received - it won't do that. 不要误以为这会导致事件为接收的每个字节触发 - 它不会那样做。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM