如何使用 Windows API 将空字符发送到串行端口?

发布于 2024-07-10 13:18:42 字数 895 浏览 5 评论 0原文

我正在开发一个 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 技术交流群。

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

发布评论

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

评论(6

瑕疵 2024-07-17 13:18:42

我以前做过 Windows 串行端口编程,并且确信我能够通过串行端口发送空字符(否则各种文件传输协议将无法工作)。 我可以想到两种可能的解释:

  1. 接收设备正在使用在第一个空字符处停止的方法打印接收到的数据。 您如何确定传输设备在第一个空值处终止? 问题可能出在更远的地方吗?
  2. 串行驱动程序损坏。 这不太可能,但却是一个可能的解释。 如果您使用一些狡猾的专有第三方串行端口及其驱动程序,那么它们可能会受到怀疑。 如果您使用标准内置串行端口和普通 Windows 驱动程序,那么这可能不是问题。

我刚刚快速浏览了一下 RapidQ,还有第三种可能的解释:

  1. RapidQ 在调用 Win32 API 函数的过程中可能执行的封送处理可能会因要发送的数据中嵌入空字符而出现问题。 我对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:

  1. The receiving device is printing the data it received using a method that stops at the first null character. How are you determining that the transmitting device is terminating at the first null? Could the problem be somewhere further down the line?
  2. The serial driver is broken. This is rather unlikely, but is a possible explanation. If you are using some dodgy proprietary third party serial port and its drivers, then they might be suspect. If you are using a standard built-in serial port with the normal Windows drivers, then this is probably not a problem.

I just had a quick look at RapidQ and there's a third possible explanation:

  1. The marshaling that RapidQ may do in the process of calling Win32 API functions may have trouble with embedded null characters in the data to send. I don't know anything about RapidQ, but this is yet another link in the chain that must be considered.
旧话新听 2024-07-17 13:18:42

格雷格可能是正确的,但我还会检查您的 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.

臻嫒无言 2024-07-17 13:18:42

我过去使用过 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.

雨落□心尘 2024-07-17 13:18:42

如果这些都没有帮助,你可以随时做我做的事情。 使用 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.

九八野马 2024-07-17 13:18:42

要通过串行发送 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

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