如何使用 Windows API 将空字符发送到串行端口?
我正在开发一个 Windows 实用程序,它使用标准 COM 端口与一些自定义硬件进行通信。 通信协议(不受我的控制)要求我发送和接收原始 8 位数据字节。
我当前正在使用以下 Windows API 函数将数据发送到 COM 端口:
WriteFile(hFile, lpBuffer, numberOfBytesToWrite, ...)
其中 hFile
是对正确打开的 COM 端口的引用,lpBuffer
是一个字节数组我已存储在内存中。 该代码可以完美运行,直到需要将空字符(ASCII 零)发送到设备。 一旦检测到空字符,WriteFile
就会停止发送,因为它假定已到达字符串末尾。 即使我正确设置了numberOfBytesToWrite
,也会发生这种情况。
如何使用 Windows API 将原始数据发送到 COM 端口? 我更愿意使用类似于 WriteFile
的标准 API 调用,但我愿意接受建议。
我目前正在使用 RapidQ 来构建该实用程序,但它所做的只是直接调用 Windows API 函数。
编辑:我的设置包括一台通过串行端口连接到自定义硬件模块的 Windows PC。 该模块有一个小屏幕,我可以在上面查看传输的字符。 我已经使用另一个第三方实用程序测试了此设置。 我能够使用这个第三方程序与模块进行通信,并且空字符正确显示。 在我自己的程序中,当我使用 WriteFile
时,传输流中任何位置的空字符都会阻止发送流的其余部分。
I am working on a Windows utility program which communicates with some custom hardware using a standard COM port. The communication protocol (which is out of my control) requires me to transmit and receive raw 8-bit data bytes.
I am currently using the following Windows API function to send data to the COM port:
WriteFile(hFile, lpBuffer, numberOfBytesToWrite, ...)
where hFile
is a reference to the properly opened COM port, and lpBuffer
is an array of bytes that I have stored in memory. The code works perfectly until a null character (ASCII zero) needs to be sent to the device. WriteFile
stops sending as soon as it detects the null character because it assumes that it has reached the end of the string. This happens even though I set numberOfBytesToWrite
properly.
How can I send raw data to the COM port using the Windows API? I would prefer to use a standard API call similar to WriteFile
, but I am open to suggestions.
I am currently using RapidQ to build the utility, but all it does is call the Windows API function directly.
Edit: My setup consists of a Windows PC connected via serial port to the custom hardware module. The module has a small screen on which I am able to view the transmitted characters. I have tested this setup with another third-party utility program. I am able to communicate with the module using this third party program, and null characters show up properly. In my own program, when I use WriteFile
, a null character anywhere in the transmit stream stops the rests of the stream from being sent.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
我以前做过 Windows 串行端口编程,并且确信我能够通过串行端口发送空字符(否则各种文件传输协议将无法工作)。 我可以想到两种可能的解释:
我刚刚快速浏览了一下 RapidQ,还有第三种可能的解释:
I've done Windows serial port programming before, and am sure that I have been able to send null characters through the serial ports (various file transfer protocols wouldn't have worked otherwise). I can think of two possible explanations:
I just had a quick look at RapidQ and there's a third possible explanation:
Win32 中的串行通信
Serial Communications in Win32
格雷格可能是正确的,但我还会检查您的 com 端口设置。 确保您的 DCB 设置正确。 查找 SetCommState 和 GetCommState 以获取信息。
通常,串行是 8N1,但您的设备可能使用其他奇偶校验或停止位配置等。
像 Greg 一样,我自己在串行方面做了很多工作,这通常可能是问题的根源......尝试使用 RS485 和不正确的 DCB 结构进行通信...呵呵..
Larry
PS:如果您还没有,我建议您购买一个好的串行分线盒。 我在房子周围有一个,它会向您显示所有通信期间所有线路上的所有信号,并且是一个非常强大的调试工具。
Greg is probably correct, but I would also check on your com port settings. Make sure your DCB settings are set properly. Look up SetCommState, and GetCommState for information.
Normally, Serial is 8N1, but your device might be using some other parity, or stop bit configuration, etc.
Like Greg, I've done a lot of work over serial myself, and this can often be the source of problems... Try talking with RS485 and an incorrect DCB structure... heh..
Larry
PS: If you don't already have one, I'd recommend getting yourself a good serial break-out box. I have one somewhere around the house, and it will show you what all the signals are, on all the lines during all of your communications, and is a very powerful debugging tool.
我过去使用过 WriteFile,它对于空字节工作得很好。 我会深入研究 RapidQ,这可能是问题所在。
I have used WriteFile in the past and it worked fine with null bytes. I would dig into RapidQ, it could be the problem.
如果这些都没有帮助,你可以随时做我做的事情。 使用 Greg 的 COMM 代码来测试设备。 还记得 Qmodem 吗? :) 非常好的测试/调试串行例程的工具。 您甚至可以使用 Qmodem 和一个简单的 Qmodem 脚本来读取另一个盒子上的 COM 端口(或同一盒子中的另一个端口),并打印出发送的每个字符的十六进制值。 等一下。 Qmodem 具有内置功能。:) 使用调试 ASCII 仿真,它将显示通过串行端口的每个字符的十六进制值。 然后,您至少可以验证您的代码是否正常工作。
现在,问题。 WriteFile 是在遇到 NULL 时返回,还是只是坐等,永远不会返回?
如果它永远不会返回,那么它可能不是您的代码。 WriteFile 仅在发送完所有 dwBytesToWrite 或出现错误时才返回。 还有什么,它正在尝试写入,但另一端出现故障。
If none of this helps, you can always do what I do. Use Greg's COMM code to test the device with. Remember Qmodem? :) Very nice tool for testing/debugging serial routines. You ccould even use Qmodem and a simple Qmodem script to read the COM port on another box (or another port in the same box), and print out the hex value of every char sent. Oh wait. Qmodem has that built in. :) Use the Debug ASCII emulation and it will show the hex values of every char that comes across the serial port. Then, you could at least verify if your code is working correctly or not.
Now, Question. Does WriteFile return when it hits the NULL, or does it just sit and wait, and never return?
If it never returns, then it may not be your code. WriteFile only returns when it has sent all dwBytesToWrite, or if there is an error. Anything else, and it's TRYING to write, but there is a failure on the other end.
要通过串行发送 NULL 字符,您可以使用 setEndOfFile() 函数,将端口处理程序作为文件提供。
如果您有太多 NULL 数据需要发送,这可能并不理想,但这是一种解决方法。
函数详细信息
To send a NULL character through serial you can use the setEndOfFile() function, giving the port handler as file.
If you have too many NULL data to send it's probably not ideal, but it's a workaround.
Function details