我正在尝试使用windows.h库通过RS232与设备通信(SCPI通信)。我看了一些关于如何设置的教程和指南,认为我的代码应该能正确工作。我可以使用WriteFile将数据发送到设备。但是,我无法使用ReadFile接收任何数据(ReadFile不会生成错误,但缓冲区大小为0)。这是我的代码:
#include <stdio.h>
#include <windows.h>
void main ()
{
// CreateFile
HANDLE rs232 = CreateFileA ("\\.\COM1", GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0);
if (rs232 == INVALID_HANDLE_VALUE)
{
printf ("fail CreateFile: %dn", GetLastError ()); system ("pause"); return;
}
// Get & Set CommState
DCB port_configuration;
int err = GetCommState (rs232, &port_configuration);
if (err <= 0)
{
printf ("fail GetCommState: %dn", GetLastError ()); CloseHandle (rs232); system ("pause"); return;
}
port_configuration.BaudRate = 19200;
port_configuration.ByteSize = 8;
port_configuration.Parity = 0;
port_configuration.StopBits = 0;
port_configuration.DCBlength = sizeof (port_configuration);
err = SetCommState (rs232, &port_configuration);
if (err <= 0)
{
printf ("fail SetCommStaten"); CloseHandle (rs232); system ("pause"); return;
}
// SetCommTimeouts
COMMTIMEOUTS timeout_configuration;
timeout_configuration.ReadIntervalTimeout = 1;// MAXDWORD;
timeout_configuration.ReadTotalTimeoutMultiplier = 1;// 0;
timeout_configuration.ReadTotalTimeoutConstant = 1;// 0;
timeout_configuration.WriteTotalTimeoutMultiplier = 1;// 0;
timeout_configuration.WriteTotalTimeoutConstant = 1;// 0;
err = SetCommTimeouts (rs232, &timeout_configuration);
if (err <= 0)
{
printf ("fail SetCommTimeouts: %dn", GetLastError ()); CloseHandle (rs232); system ("pause"); return;
}
// WriteFile
DWORD buffer_size_w;
char buffer_w[128] = "*IDN?n";
err = WriteFile (rs232, buffer_w, strlen (buffer_w), &buffer_size_w, 0);
if (err <= 0)
{
printf ("fail WriteFile: %dn", GetLastError ()); CloseHandle (rs232); system ("pause"); return;
}
printf ("written %d characters: %sn", buffer_size_w, buffer_w);
// ReadFile
for (int x = 0; x < 10; ++x)
{
DWORD buffer_size_r;
char buffer_r[128] = {0};
err = ReadFile (rs232, buffer_r, 128, &buffer_size_r, 0);
if (err <= 0)
{
printf ("fail ReadFile: %dn", GetLastError ()); Sleep (250); continue;
}
printf ("read %d characters: %sn", buffer_size_r, buffer_r);
Sleep (250);
}
CloseHandle (rs232);
system ("pause");
}
以下是关于我的设置的更多信息:
- 我使用的是Windows 7 x64和Microsoft Visual Studio 2013
- 该项目被编译为Win32控制台
- 我使用FTDI Chipi-X USB到COM端口转换器电缆
- 我试着连接Newport运动控制器和Thorlabs压电控制器
以下是我迄今为止尝试过的东西:
- 更新Chipi-X VCOM的驱动程序
- 将COMMTIMEOUTS更改为在线指南中所示的各种不同值
- 使用超级终端,我能够与设备进行完全的来回通信。如果我使用自己的程序发送请求设备的命令,例如"*IDN?\n",那么我自己的ReadFile将不会返回任何内容。但是,当我再次连接超级终端时,我可以按ENTER键接收请求的信息
- 使用SetupComm()更改缓冲区大小
- 将ReadFile缓冲区大小更改为每次1字节
- 按照本指南中的说明执行OVERLAPPED方法:https://msdn.microsoft.com/en-us/library/ff802693.aspx.它给出了与上面的非重叠代码完全相同的问题:windows函数不会产生错误,但读取缓冲区将保持为空
- 我试着用不同的设备进行通信,这很有趣:我再次能够使用超级终端进行完全的来回通信。每当我使用自己的程序发送时,我总是会收到使用ReadFile发送回的确切字符串。同样,可以通过重新连接超级终端来检索实际请求的信息
在我看来,缓冲区有一些问题,但我不知道是什么。我也不确定超级终端是否能够获取几秒钟前通过不同COM端口连接请求的信息。这个问题可能与我的编码有关,因为超级终端工作得很好,但如果我将我的代码与网上找到的其他代码进行比较,我似乎找不到我的代码有什么问题。
有人能帮我吗?
编辑:
- 我使用以下示例创建了一个新的CLR/C++测试应用程序:https://msdn.microsoft.com/en-us/library/system.io.ports.serialport(v=vs.110).aspx。这再次出现了无法接收请求的完全相同的问题
- 我试过Roline USB到RS232的电缆:超级终端可以工作,但我的编程不可以。底层硬件或驱动程序可能不是问题所在
我解决了问题:
我忘记在命令结束时发送回车(\r)。显然,在实际解析请求之前,我测试的两个设备都在等待组合。通过使用超级终端,我可以将附加到\r\n当前COM端口输出缓冲区,并获得延迟的结果。