无法在COM端口上正确使用windows.h ReadFile.WriteFile似乎工作正常



我正在尝试使用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压电控制器

以下是我迄今为止尝试过的东西:

  1. 更新Chipi-X VCOM的驱动程序
  2. 将COMMTIMEOUTS更改为在线指南中所示的各种不同值
  3. 使用超级终端,我能够与设备进行完全的来回通信。如果我使用自己的程序发送请求设备的命令,例如"*IDN?\n",那么我自己的ReadFile将不会返回任何内容。但是,当我再次连接超级终端时,我可以按ENTER键接收请求的信息
  4. 使用SetupComm()更改缓冲区大小
  5. 将ReadFile缓冲区大小更改为每次1字节
  6. 按照本指南中的说明执行OVERLAPPED方法:https://msdn.microsoft.com/en-us/library/ff802693.aspx.它给出了与上面的非重叠代码完全相同的问题:windows函数不会产生错误,但读取缓冲区将保持为空
  7. 我试着用不同的设备进行通信,这很有趣:我再次能够使用超级终端进行完全的来回通信。每当我使用自己的程序发送时,我总是会收到使用ReadFile发送回的确切字符串。同样,可以通过重新连接超级终端来检索实际请求的信息

在我看来,缓冲区有一些问题,但我不知道是什么。我也不确定超级终端是否能够获取几秒钟前通过不同COM端口连接请求的信息。这个问题可能与我的编码有关,因为超级终端工作得很好,但如果我将我的代码与网上找到的其他代码进行比较,我似乎找不到我的代码有什么问题。

有人能帮我吗?

编辑:

  1. 我使用以下示例创建了一个新的CLR/C++测试应用程序:https://msdn.microsoft.com/en-us/library/system.io.ports.serialport(v=vs.110).aspx。这再次出现了无法接收请求的完全相同的问题
  2. 我试过Roline USB到RS232的电缆:超级终端可以工作,但我的编程不可以。底层硬件或驱动程序可能不是问题所在

我解决了问题:

我忘记在命令结束时发送回车(\r)。显然,在实际解析请求之前,我测试的两个设备都在等待组合。通过使用超级终端,我可以将附加到\r\n当前COM端口输出缓冲区,并获得延迟的结果。

最新更新