【问题标题】:Getting DTR and RTS pin of serial port in C on Windows platformWindows平台C语言获取串口DTR和RTS引脚
【发布时间】:2019-12-19 11:02:14
【问题描述】:

windows平台下如何获取串口的DTR和RTS状态?我想读取这两个引脚的当前状态(ON 或 OFF)。

我可以使用:

EscapeCommFunction(hSerial,SETRTS);

但我不知道如何读取 pin 状态。

由于在 Linux 上,可以使用以下代码完成,我认为它在技术上是可行的:

int status=0;
ioctl(fd, TIOCMGET, &status);
return status & TIOCM_RTS;

【问题讨论】:

  • DeviceIoControl() this ioctl code。这是相当危险的,驱动程序可能不会实现它。

标签: windows serial-port windev


【解决方案1】:

使用inc\api\ntddser.h API 和winioctl.h,您可以访问 DTR 和 RTS 状态。调用DeviceIoControl,设置第二个参数为IOCTL_SERIAL_GET_DTRRTS

呼叫:

DeviceIoControl(
    handle, // handle returned by CreateFile
    IOCTL_SERIAL_GET_DTRRTS,
    NULL,
    0,
    &Status, // pointer to a DWORD variable 1
    sizeof(Status),
    &unused, // pointer to a DWORD variable
    pOverlapped // optional pointer to overlapped buffer (may be NULL)
);

关于DeviceIoControlhere的文档。

【讨论】:

    【解决方案2】:

    除非你主动改变信号线,否则是否使用 DCB 中设置的值?
    除此之外,您自己控制信号线,因此每次更改时都要记住它。

    只要您打开串口,您就拥有一切控制权,其他一切都不会改变。
    现在没有人使用握手或切换模式吗?

    SetDefaultCommConfigW function

    BOOL SetDefaultCommConfigW(
      LPCWSTR      lpszName,
      LPCOMMCONFIG lpCC,
      DWORD        dwSize
    );
    

    SetCommConfig function

    BOOL SetCommConfig(
      HANDLE       hCommDev,
      LPCOMMCONFIG lpCC,
      DWORD        dwSize
    );
    

    GetCommConfig function

    BOOL GetCommConfig(
      HANDLE       hCommDev,
      LPCOMMCONFIG lpCC,
      LPDWORD      lpdwSize
    );
    

    COMMCONFIG structure

    typedef struct _COMMCONFIG {
        ...
      DCB   dcb;
        ...
    } COMMCONFIG, *LPCOMMCONFIG;
    

    DCB structure

    typedef struct _DCB {
      DWORD DCBlength;
        ...
      DWORD fDtrControl : 2;
        ...
      DWORD fRtsControl : 2;
        ...
    } DCB, *LPDCB;
    
    DTR_CONTROL_DISABLE   0x00
    DTR_CONTROL_ENABLE    0x01
    DTR_CONTROL_HANDSHAKE 0x02
    
    RTS_CONTROL_DISABLE   0x00
    RTS_CONTROL_ENABLE    0x01
    RTS_CONTROL_HANDSHAKE 0x02
    RTS_CONTROL_TOGGLE    0x03
    

    如果您仍想这样做,请使用 @Hans Passant 评论的 DeviceIoControl()。
    但是,不能保证它得到适当的支持,因为大多数人不会使用它。

    Device Input and Output Control (IOCTL)
    DeviceIoControl function

    以下是 DISK 驱动器的示例 DeviceIoControl 调用,但您可以通过将这些参数中的每一个更改为与串行端口的 IOCTL_SERIAL_GET_DTRRTS 相关的参数来调用它。
    Calling DeviceIoControl

    Serial Device Control Requests
    IOCTL_SERIAL_GET_DTRRTS IOCTL

    【讨论】:

    • 我使用了没有握手的串行 COM。我已经记住了每次更改引脚时的状态,但并不完全令人满意。你的回答不清楚,也没有澄清我的问题。有可能是或否吗?如果是,请提供示例代码。
    • 该问题没有详细说明“不完全令人满意”的情况。那么就没有人能够回答了。我的回答是,除非您使用其他方式,例如 RS232C 线路监视器、协议分析仪或示波器,否则标准 COM 端口 API 的确切状态是未知的。您所能做的就是记住您指定的内容并根据它做出决定。
    • "您所能做的就是记住您指定的内容并据此做出决定。" => 来源?顺便说一句,在Linux下是可以的。
    • 因为微软的 API 文档中没有描述。 Communications Functions 对于 DTR/RTS,只有 API 可以获取 DCB 配置。如果您是设备驱动程序创建者,您将是@Hans Passant 评论的 IOCTL 的实施者,而不是用户。而如果你是应用程序员,DTR/RTS 是一个输出引脚,如果它处于正常状态,它会按照你指定的方式工作,所以如果你记得你指定的内容,就不需要获取那个状态。
    猜你喜欢
    • 1970-01-01
    • 2021-07-31
    • 2019-01-25
    • 2014-08-16
    • 2019-01-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-26
    相关资源
    最近更新 更多