首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >无法在COM端口上正确使用windows.h ReadFile。WriteFile似乎运转良好

无法在COM端口上正确使用windows.h ReadFile。WriteFile似乎运转良好
EN

Stack Overflow用户
提问于 2015-03-25 13:21:44
回答 1查看 1.6K关注 0票数 0

我正在尝试使用windows.h库通过RS232与设备(SCPI通信)进行通信。我看过几个教程和指南,介绍了如何设置它,并认为我的代码应该正确工作。我可以使用WriteFile向设备发送数据。但是,我无法使用ReadFile接收任何数据(ReadFile不会生成错误,但缓冲区大小为0)。这是我的代码:

代码语言:javascript
运行
复制
#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: %d\n", GetLastError ()); system ("pause"); return;
  }

  // Get & Set CommState
  DCB port_configuration;
  int err = GetCommState (rs232, &port_configuration);
  if (err <= 0)
  {
    printf ("fail GetCommState: %d\n", 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 SetCommState\n"); 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: %d\n", 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: %d\n", GetLastError ()); CloseHandle (rs232); system ("pause"); return;
  }
  printf ("written %d characters: %s\n", 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: %d\n", GetLastError ()); Sleep (250); continue;
    }
    printf ("read %d characters: %s\n", buffer_size_r, buffer_r);
    Sleep (250);
  }

  CloseHandle (rs232);
  system ("pause");
}

下面是有关我的设置的更多信息:

  • 我使用的是Windows7 x64和2013
  • 该项目被编译为Win32控制台。
  • 我使用FTDI Chipi-X USB到COM端口转换器电缆。
  • 我试过连接Newport运动控制器和Thorlabs控制器

以下是我到目前为止尝试过的一些事情:

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

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

有人能帮我一下吗?

编辑:

  1. 我使用以下示例创建了一个新的CLR/C++测试应用程序:https://msdn.microsoft.com/en-us/library/system.io.ports.serialport(v=vs.110).aspx。这再次给出了同样的问题,即无法接收请求。
  2. 我尝试过从Roline到RS232电缆: HyperTerminal工作,而我的编程不工作。底层硬件或驱动程序可能不是这里的问题。
EN

回答 1

Stack Overflow用户

发布于 2015-03-27 11:55:15

我解决了这个问题:

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

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29256890

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档