首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >通过CDC COM端口到Arduino的Windows COM通信

通过CDC COM端口到Arduino的Windows COM通信
EN

Stack Overflow用户
提问于 2016-04-28 11:46:57
回答 2查看 1.1K关注 0票数 3

我刚刚买了一台SparkFun Pro微(https://www.sparkfun.com/products/12640),并试图用ReadFile和WriteFile在Windows 10上与它进行通信。

我已经用Stellaris,Tiva,Arduino Mega,甚至Arduino Leonardo测试并运行了我的代码,没有什么问题(它成功了)。然而,我没有能力发送任何数据从Pro Micro或在我的计算机上使用微型USB电缆和我自己的自定义程序接收数据。我可以使用Arduino串行监视器发送和接收数据非常好。我也可以使用PuTTY终端。Arduino IDE和PuTTY中的波特率似乎对使用Pro微设备发送/接收数据的能力没有任何影响。

我希望能够使用我自己的程序发送和接收数据,因为我正在使用它作为数据记录、后处理和实时绘图/显示的服务器。如果这个项目不需要更小的硬件包,我将使用Arduino Mega,但遗憾的是,这不是一个选项。

我正在Windows 10上编译,使用Visual 2015。我还使用了带有SparkFuns插件/驱动程序的正式Arduino IDE,v1.6.7 (更新到1.6.8,有相同的问题)。

这是我连接到COM端口的代码,我尝试过各种波特率以及BAUD_XXXX宏:

代码语言:javascript
复制
*port = CreateFile(COM, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); //CreateFile(TEXT("COM8:"), ...
if (*port == INVALID_HANDLE_VALUE){
    printf("Invalid handle\n");
    return(1);
}

/// COM Port Configuration
portDCB.DCBlength = sizeof(DCB);                         ///< Initialize the DCBlength member
GetCommState(*port, &portDCB);                           ///< Get the default port setting information.
/// Change the DCB structure settings
portDCB.BaudRate = 115200;                              ///< Current baud 
portDCB.fBinary = TRUE;                                   ///< Binary mode; no EOF check 
portDCB.fParity = FALSE;                                  ///< Disable parity checking 
portDCB.fOutxCtsFlow = FALSE;                             ///< No CTS output flow control 
portDCB.fOutxDsrFlow = FALSE;                             ///< No DSR output flow control 
portDCB.fDtrControl = DTR_CONTROL_DISABLE;                ///< Disable DTR flow control type 
portDCB.fDsrSensitivity = FALSE;                          ///< DSR sensitivity 
portDCB.fTXContinueOnXoff = TRUE;                         ///< XOFF continues Tx 
portDCB.fOutX = FALSE;                                    ///< No XON/XOFF out flow control 
portDCB.fInX = FALSE;                                     ///< No XON/XOFF in flow control 
portDCB.fErrorChar = FALSE;                               ///< Disable error replacement 
portDCB.fNull = FALSE;                                    ///< Disable null stripping 
portDCB.fRtsControl = RTS_CONTROL_DISABLE;                ///< Disable RTS flow control 
portDCB.fAbortOnError = FALSE;                            ///< Do not abort reads/writes on error
portDCB.ByteSize = 8;                                     ///< Number of bits/byte, 4-8 
portDCB.Parity = NOPARITY;                                ///< 0-4 = no, odd, even, mark, space 
portDCB.StopBits = ONESTOPBIT;                            ///< 0, 1, 2 = 1, 1.5, 2 

if (!SetCommState(*port, &portDCB)){
    printf("Error Configuring COM Port\n");
    return(1);
}

GetCommTimeouts(*port, &comTimeOut);

comTimeOut.ReadIntervalTimeout = 20;
comTimeOut.ReadTotalTimeoutMultiplier = 10;
comTimeOut.ReadTotalTimeoutConstant = 100;
comTimeOut.WriteTotalTimeoutMultiplier = 10;
comTimeOut.WriteTotalTimeoutConstant = 100;

SetCommTimeouts(*port, &comTimeOut);

我的读写功能:

代码语言:javascript
复制
char inChar(HANDLE port){
    char output = 0;
    DWORD noOfBytesRead = 0;
    int retval = ReadFile(port, &output, 1, &noOfBytesRead, NULL);
    if (retval == 0) {
        return (0);
    }
    return(output);
}

void outChar(HANDLE port, char output){
    DWORD bytesTransmitted = 0;
    char buffer[] = { output, 0 };
    WriteFile(port, buffer, 1, &bytesTransmitted, NULL);
}

我用这个来测试PC上的通讯:

代码语言:javascript
复制
while (1) {
    outChar(portHandle, 'b');
    inchar = inChar(portHandle);
    printf("%c", inchar);
}

在Arduino号上:

代码语言:javascript
复制
void setup(){Serial.begin(115200);}
void loop(){
    Serial.read();
    Serial.println('a');
    delay(10);
}

Rx LED在Arduino上疯狂地闪烁,但The却什么也不做,这意味着只有数据是单向的。我做了其他测试,我发现Arduino正在读取正确的信息(如果输入字符是特定的字符,则通过闪烁LED来测试),但是它只是不会将任何东西发送到我的程序(当不使用Arduino IDE或PuTTY时,PC端)。

在PuTTY中,我能够启动与任何波特率的COM通信,而不管Arduino Serial.begin()。8个数据位,1个停止位,没有奇偶校验,没有流控制,与我在Visual中的设置相同。

编辑:我想如果我不亲自配置它,我就会放弃PuTTy遗留下来的COM配置,所以我修改了代码并删除了所有多余的内容:

代码语言:javascript
复制
/// COM Port Configuration
portDCB.DCBlength = sizeof(DCB);                         ///< Initialize the DCBlength member
GetCommState(*port, &portDCB);                           ///< Get the default port setting information.
/// Change the DCB structure settings
portDCB.BaudRate = 115200;                              ///< Current baud 
portDCB.ByteSize = 8;                                     ///< Number of bits/byte, 4-8 
portDCB.Parity = NOPARITY;                                ///< 0-4 = no, odd, even, mark, space 
portDCB.StopBits = ONESTOPBIT;                            ///< 0, 1, 2 = 1, 1.5, 2 
/*
portDCB.fBinary = TRUE;                                   ///< Binary mode; no EOF check 
portDCB.fParity = FALSE;                                  ///< Disable parity checking 
portDCB.fOutxCtsFlow = FALSE;                             ///< No CTS output flow control 
portDCB.fOutxDsrFlow = FALSE;                             ///< No DSR output flow control 
portDCB.fDtrControl = DTR_CONTROL_DISABLE;                ///< Disable DTR flow control type 
portDCB.fDsrSensitivity = FALSE;                          ///< DSR sensitivity 
portDCB.fTXContinueOnXoff = TRUE;                         ///< XOFF continues Tx 
portDCB.fOutX = FALSE;                                    ///< No XON/XOFF out flow control 
portDCB.fInX = FALSE;                                     ///< No XON/XOFF in flow control 
portDCB.fErrorChar = FALSE;                               ///< Disable error replacement 
portDCB.fNull = FALSE;                                    ///< Disable null stripping 
portDCB.fRtsControl = RTS_CONTROL_DISABLE;                ///< Disable RTS flow control 
portDCB.fAbortOnError = FALSE;                            ///< Do not abort reads/writes on error
*/

它在注释的代码中运行得很好,但是为什么呢?是什么使这款Pro微与我使用过的其他微控制器如此不同?我将逐个对它们进行测试,直到找出该由谁负责,因为只有在第一次打开和关闭PuTTY中的端口(不方便)之后才能进行连接。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-04-28 13:06:49

当您在Windows结构中禁用RTS控件时,SparkFun Pro微不喜欢它。

解决这一问题的办法是:

代码语言:javascript
复制
portDCB.fRtsControl = RTS_CONTROL_ENABLE; //was RTS_CONTROL_DISABLE
portDCB.fOutxCtsFlow = TRUE;              //was FALSE

和往常一样,忽略数据表中的重要信息是错误的,我花了几个小时阅读注册表信息,试图确认我出错的地方或原因,答案很简单,因为我们可以看到数据表中USART设备的功能列表:

代码语言:javascript
复制
USART:
...
• Flow control CTS/RTS signals hardware management
...
票数 2
EN

Stack Overflow用户

发布于 2016-04-28 12:53:06

代码语言:javascript
复制
char inChar(HANDLE port){
        char output = 0;
        DWORD noOfBytesRead = 0;
        int retval = ReadFile(port, &output, 1, &noOfBytesRead, NULL);
        if (retval == NULL) {
            return (NULL);
        }
        return(output);
    }

这是不正确的,因为您正在比较retval (即int)和NULL,并且您的函数返回NULL作为char函数的返回值。虽然我不认为这是引起报道问题的原因,但它应该改变。

看一看公认的答案here。我建议您从PC端的工作示例开始,然后将其减少到您的需要。

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

https://stackoverflow.com/questions/36913723

复制
相关文章

相似问题

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