windows 如何设置 CreateFile() 打开 COM 端口时将使用的 DTR/RTS 状态

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/951016/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-15 12:35:08  来源:igfitidea点击:

How to set DTR/RTS state that will be used when CreateFile() opens COM port

c++cwindowsserial-port

提问by Ed.

I wrote/support a terminal emulator called uCon (http://www.umonfw.com/ucon). Its all based on "good-ole" Win32, and is entirely in 'C'. I was recently asked to support the ability to have uCon attach to a COM port and set up DTR/RTS for purposes outside of RS232 flow control. I know I can do this after CreateFile() is called using EscapeCommFunction() and/or SetCommState(); however, these functions can only be called AFTER CreateFile() returns a handle to the opened port. Unfortunately, when CreateFile() opens the port, it sets DTR/RTS to their default state, which may (or may not) be different than the state that I wish to keep DTR in.

我编写/支持一个名为 uCon ( http://www.umonfw.com/ucon)的终端模拟器。它全部基于“good-ole”Win32,并且完全使用“C”。我最近被要求支持将 uCon 连接到 COM 端口并为 RS232 流控制之外的目的设置 DTR/RTS 的能力。我知道我可以在使用 EscapeCommFunction() 和/或 SetCommState() 调用 CreateFile() 后执行此操作;但是,这些函数只能在 CreateFile() 返回打开端口的句柄后调用。不幸的是,当 CreateFile() 打开端口时,它会将 DTR/RTS 设置为其默认状态,这可能(也可能不会)与我希望保持 DTR 的状态不同。

For example, assume the user has a board connected to the PC's serial port, and the DTR line is used to put the board in some non-standard state. With DTR inactive, the board runs "normal", but occasionally DTR-active is used to transition the hardware to some other state.

例如,假设用户有一块板卡连接到PC 的串口,DTR 线用于将板卡置于某种非标准状态。DTR 不活动时,板子运行“正常”,但偶尔 DTR-active 用于将硬件转换到其他状态。

In most cases I've seen, CreateFile() brings DTR active, then my call to clear DTR brings it back to inactive; however, that's a glitch I need to avoid. I found a function set called GetDefaultCommConfig() & SetDefaultCommConfig() but have not been able to get them to work successfully. So, my question is this...

在我见过的大多数情况下,CreateFile() 使 DTR 处于活动状态,然后我调用 clear DTR 将其恢复为非活动状态;然而,这是我需要避免的小故障。我找到了一个名为 GetDefaultCommConfig() 和 SetDefaultCommConfig() 的函数集,但未能让它们成功工作。所以,我的问题是这个......

Is there a way to pre-define the default state that will be established on the RS232 control lines when CreateFile() is called? Has anyone used GetDefaultCommConfig()/SetDefaultCommConfig() successfully?

有没有办法预定义在调用 CreateFile() 时将在 RS232 控制线上建立的默认状态?有没有人成功使用过 GetDefaultCommConfig()/SetDefaultCommConfig()?

It seems to me that this should allow me to pre-establish the value of DTR to be used when CreateFile() is called...

在我看来,这应该允许我预先建立调用 CreateFile() 时要使用的 DTR 的值......

 
int
EstablishDefaultDTR(char *comPortName, int dtr)
{
    COMMCONFIG  cc;
    DWORD   bsize = sizeof(COMMCONFIG);

    if (GetDefaultCommConfig(comPortName,&cc,&bsize) == 0) {
        ShowLastError("GetDefaultCommConfig()");
        return(-1);
    }

    if (dtr)
       cc.dcb.fDtrControl = DTR_CONTROL_ENABLE ;
    else
       cc.dcb.fDtrControl = DTR_CONTROL_DISABLE ;

    if (SetDefaultCommConfig(comPortName,&cc,bsize) == 0) {
        ShowLastError("SetDefaultCommConfig()");
        return(-1);
    }
}

But, as you may have already guessed, it doesn't. Any ideas?

但是,正如您可能已经猜到的那样,事实并非如此。有任何想法吗?

回答by dario_ramos

Might not be the fastest way, but this works:

可能不是最快的方法,但这有效:

#include <stdlib.h>
#include <stdio.h>

int
EstablishDefaultDTR(char *comPortName, int dtr){
    char commandString[256];
    if ( !system(NULL) ){
        ShowLastError("system()");
        return(-1);
    }        
    sprintf( commandString, "MODE %s dtr=%s%", comPortName, dtr? "on":"off"  );
    return system( commandString );
}

回答by Paul Mitchell

You're not initializing the COMMCONFIG structure. That could well be the problem since the documentation explicitly says that you must set dwSize at least

您没有初始化 COMMCONFIG 结构。这很可能是问题所在,因为文档明确指出您必须至少设置 dwSize

cc.dwSize = sizeof( COMMCONFIG );

cc.dwSize = sizeof( COMMCONFIG );