当前位置: 首页 > 编程语言 > C#

如何在C#中向串口设备发送字节?分享

时间:2023-04-11 02:49:20 C#

C#中如何将字节发送到串口设备?我有一个设备使用串口(通过USB适配器)连接到我的PC。我很难在C#中正确使用它。我知道它工作正常,因为供应商的软件运行正常。我还知道,由于重复发送“OK”的测试模式,我能够使用我的代码接收数据。这是我的代码:私有SerialPort端口;publicSerialConnection(){this.port=newSerialPort("COM3",38400,Parity.None,8,StopBits.One);this.port.WriteTimeout=2000;port.ReadTimeout=2000;这个.port.Open();this.port.DataReceived+=newSerialDataReceivedEventHandler(port_DataReceived);}publicvoidSendCommand(byte[]command){this.port.Write(command,0,command.Length);字符串字符="";foreach(bytecharbyteincommand)chars+=(char)charbyte;Console.WriteLine("->"+字符);}voidport_DataReceived(objectsender,SerialDataReceivedEventArgse){stringdata=this.port.ReadLine();Console.WriteLine("<-"+数据);目前我正在使用另一种测试模式,它应该回显它接收到的任何内容。所以我用以下字节调用SendCommand:byte[]{0x50,0x69,0x6E,0x67}但似乎没有任何东西被发回。我不知道接下来要尝试什么。有没有人有什么建议?对于附带问题,我发布了一些PortMon日志。我认为它们在这里也可能有用,所以它们在这里:供应商软件-过滤掉所有IOCTL_SERIAL_GET_COMMSTATUS条目我的脚趾要尝试每个RS-232设备都需要使用某种流量控制机制来通知正在进行的通信的相对部分。有三种基本机制:(开始升级)遗留应用程序中的初始队列长度和超时:1IOCTL_SERIAL_SET_QUEUE_SIZEInSize:1024OutSize:10242IOCTL_SERIAL_SET_TIMEOUTRI:2000RM:0RC:2000WM:0WC:2000而你没有'设置它们。尝试使用SerialPort.WriteBufferSize和SerialPort.ReadBufferSize设置队列大小。还可以使用SerialPort.ReadTimeout和SerialPort.WriteTimeout来设置超时。(最后更新)在你的情况下,遗留应用程序会:12IOCTL_SERIAL_CLR_RTS13IOCTL_SERIAL_SET_DTR当你这样做时:12IOCTL_SERIAL_CLR_RTS13IOCTL_SERIAL_CLR_DTR你没有设置DTR(数据终端就绪)信号,所以设备不期望串行上的任何数据行或命令。所以将SerialPort.DtrEnable设置为true。第二个问题是你没有打开握手。旧版应用程序:16IOCTL_SERIAL_SET_HANDFLOW摇动:1替换:0XonLimit:0XoffLimit:018IOCTL_SERIAL_SET_RTS...21IOCTL_SERIAL_CLR_RTS当您这样做时:16IOCTL_SERIAL_SET_HANDFLOW摇动:0替换:0XonLimit:4096Xoffshakeial9通过HandSakePort打开它。RequestToS此外,您似乎经常打开、关闭和重新配置串行端口。尝试设置端口,然后在整个会话中使用相同的SerialPort实例。不要尝试将其重新打开,因为这会导致重新配置物理端口引脚的状态。串行通信不是黑魔法,但它对设置非常敏感,各种设备需要特殊设置和处理。正确的命令时间也可能是一个问题。如果您的设备确实有一些技术文档,请阅读两次并在第一次阅读时遵循。至少应该正确记录握手模式、命令等。如果您没有任何文档,请尝试一项一项地减少差异。更新:发送和接收数据。您写道,您发送了命令“Ping”(从十六进制解码为ASCII)。但是,您没有提到发送和命令终止序列。通常,串行设备期望序列结束序列(通常是CRLF)作为命令的终止。在设备收到包括行尾在内的完整命令之前,它无法回复。您正在通过调用ReadLine来处理数据接收事件-但是,在您不能指望整行数据的地方(即包括行尾以检测COMlete行)。您应该检查提供的事件参数并逐字节读取输入。创建一个提供自定义发送命令、接收响应、发送数据、接收数据功能的包装类是个好主意。包装器必须在内部与其余代码异步工作。这样您将拥有可用的自定义API和良好的串行端口处理。请注意,SerialPort.NewLine属性用于指定行尾序列的外观。(在你提到的另一个问题中,你试图将它设置为一个特殊的字符集。那真的是错误的。)曾经有一段时间我是一个串行通信英雄(那是我们没有vmware的日子,但是有两台486供电的PC和一对直接连接的调制解调器,用于开发和调试通信应用程序:-)),但我希望这至少能有所帮助。最后但同样重要的是,一些常用术语:您是否尝试过更改握手属性?在接受数据之前,设备可能需要在控制引脚上进行一些握手。您应该打开RtsEnable或DtrEnable属性,当设备无法在线检测到这些信号时,设备将忽略您发送的任何内容,并且不会发回任何内容。将Handshake属性设置为RTS应该已经完成??了。请注意,ReadLine()方法会阻塞,直到它获得一个换行符。你没有发送一个,所以你不会收回它。使用Read()将是一个更好的测试。首先使用已知的工作程序进行一些基本的故障排除,消除接线问题、错误的波特率或设备根本不回音。使用超级终端或腻子。Tom,我遇到了类似的问题,我敢打赌ReadLine()只会在收到rn或.NET认为是新行的内容后返回。在您的日志中,我没有看到Winbird报告任何换行符,我相信APP正在逐字节读取,而不是等待换行符。所以你可以给它发送很多字节的数据,它会一直阻塞直到它收到正确的换行符。因此,请尝试SerialPort.Read,对于初学者,一次读取1个字节,publicintRead(byte[]buffer,intoffset,intcount)如果这不能解决问题,您可能需要考虑以下我的一些问题添加一些Thread.Sleep()来解决问题,因为我意识到PC的UART速度不够快,无法通过RS232/RS485端口正确传输数据,也不能在打开端口后等待几毫秒。我还建议您宁愿创建一个单独的线程来处理串行通信而不是使用SerialDataReceivedEventHandler,创建一个发送缓冲区,它以正确的增量发送而不会阻塞您的应用程序,还读取数据并将接收到的字节附加到缓冲区,直到您已经收到足够的数据。您还需要第二个串行设备来捕获数据,以确保您的C#应用程序正在传输正确的数据。要消除握手问题,只需连接PIN2,3+PIN5(GND)进行测试。希望对您有所帮助C#学习教程就是这样:如何在C#中将字节发送到串行设备?如果所有分享的内容对你有用,需要进一步了解C#学习教程,希望大家多多关注。本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处: