【问题标题】:Arduino and Windows serial communications issue?Arduino 和 Windows 串行通信问题?
【发布时间】:2012-01-01 17:03:16
【问题描述】:

我正在开展一个项目,该项目涉及在连接到 Arduino Mega 设备的 Windows 7 32 位平台上的 Visual Studio 2010 Proffesional 中实现的一些“c”串行通信(以控制一些硬件**与问题无关)。用于此的代码 100% 有效;我遇到的唯一问题是我的串行通信发生了一些非常有趣的事情。

Visual C 程序如下。

HANDLE hDevice = CreateFile(L"COM5",
                            GENERIC_READ | GENERIC_WRITE,
                            FILE_SHARE_READ | FILE_SHARE_WRITE,
                            NULL,
                            OPEN_EXISTING,
                            0,
                            0); //Open COM handle (create file)
if (hDevice !=INVALID_HANDLE_VALUE) //If COM3 connected
{
    printf("Com port opened\n");
    DCB lpTest;
    GetCommState(hDevice,&lpTest);
    lpTest.BaudRate = CBR_9600;
    lpTest.ByteSize = 8;
    lpTest.Parity = NOPARITY;
    lpTest.StopBits = ONESTOPBIT;
    SetCommState(hDevice,&lpTest);
    DWORD btsIO;
    WriteFile(hDevice,c1,strlen(c1),&btsIO,NULL);
    CloseHandle(hDevice);
}

这个程序的输出是一个文本字符串,我对它 100% 满意(应该以 Null 结尾,有 x 个字符等)。

在Serial Communicator 中键入从这个程序获得的结果,它似乎不起作用!使用 COM 间谍程序,我能够从终端应用程序中获取“握手”协议。

但是,与 Arduino 板的通信似乎在 HyperTerminal 上工作,而不是在 Serial Communicator 或任何其他串行应用程序上(没有握手等在 Arduino 板上完成**不相关)。

以下“握手”是从超级终端获得的(这有效!!)

*
COM port is opened
In/out queue size 8192/8192
Baud rate 9600
DTR on
Data bits=8, Stop bits=1, Parity=None
Set chars: Eof=0x00, Error=0x00, Break=0x00, Event=0x00, Xon=0x11, Xoff=0x13
Handflow: ControlHandShake=(DTR_CONTROL, CTS_HANDSHAKE, ERROR_ABORT), FlowReplace=    (TRANSMIT_TOGGLE, RTS_HANDSHAKE, XOFF_CONTINUE), XonLimit=80, XoffLimit=200
Set timeouts: ReadInterval=10, ReadTotalTimeoutMultiplier=0, ReadTotalTimeoutConstant=0,     WriteTotalTimeoutMultiplier=0,     WriteTotalTimeoutConstant=5000
*

这是来自串行通讯器(它不起作用;不正确且不一致的数字):

*
COM port is opened
In/out queue size 2048/2048
Baud rate 9600
RTS off
DTR off
Data bits=8, Stop bits=1, Parity=None
Set chars: Eof=0x00, Error=0x00, Break=0x00, Event=0x00, Xon=0x11, Xoff=0x13
Handflow: ControlHandShake=(), FlowReplace=(), XonLimit=80, XoffLimit=200
Set timeouts: ReadInterval=0, ReadTotalTimeoutMultiplier=0, ReadTotalTimeoutConstant=0,     WriteTotalTimeoutMultiplier=0, WriteTotalTimeoutConstant=0
*

我显然可以看到差异,但需要知道如何使 Arduino 板独立于这些“握手”协议。 (DTR、计时等)

这是来自我的 Visual Studio 程序(不起作用;不正确且不一致的数字)

*
COM port is opened
Baud rate 9600
RTS off
DTR off
Data bits=8, Stop bits=1, Parity=None
Set chars: Eof=0x00, Error=0x00, Break=0x00, Event=0x00, Xon=0x11, Xoff=0x13
Handflow: ControlHandShake=(), FlowReplace=(), XonLimit=80, XoffLimit=200
*

因此,我想让 Arduino 板远离 DTR 和所有握手,因为我希望最终实现直接从 Visual Studio 与 Arduino 板“对话”。

*****更新*** ****

感谢您的建议,我不明白为什么开源硬件需要这么多握手。也就是说,为什么只有最差的串行终端程序才能在串行通信器、高级串行监视器、术语、终端等似乎不起作用?

我已经更新了我的代码以准确地镜像超级终端(完成所有握手),但它似乎不起作用!

这是更新的代码片段:

HANDLE hDevice = CreateFile(L"COM5",GENERIC_READ | GENERIC_WRITE,FILE_SHARE_READ |     FILE_SHARE_WRITE,NULL,OPEN_EXISTING,0,0); //Open COM handle (create file)
if (hDevice !=INVALID_HANDLE_VALUE) //If COM3 connected
{
    printf("Com port opened\n"); //Show it's open
    DCB lpTest;
    // Initialize the DCBlength member.
    lpTest.DCBlength = sizeof (DCB);
    GetCommState(hDevice,&lpTest); //com state
    lpTest.BaudRate = CBR_9600;//load baud
    lpTest.ByteSize = 8;// load no. bits
    lpTest.Parity = NOPARITY;//parity
    lpTest.StopBits = ONESTOPBIT;//stop bits

    lpTest.fBinary = FALSE;            // Binary mode; no EOF check
    lpTest.fOutxCtsFlow = TRUE;         // No CTS output flow control
    lpTest.fOutxDsrFlow = FALSE;         // No DSR output flow control
    lpTest.fDtrControl = DTR_CONTROL_ENABLE;  // DTR flow control type
    lpTest.fDsrSensitivity = FALSE;      // DSR sensitivity
    lpTest.fTXContinueOnXoff = TRUE;     // XOFF continues Tx
    lpTest.fOutX = FALSE;                // No XON/XOFF out flow control
    lpTest.fInX = FALSE;                 // No XON/XOFF in flow control
    lpTest.fErrorChar = FALSE;           // Disable error replacement
    lpTest.fNull = FALSE;                // Disable null stripping
    //lpTest.fRtsControl = RTS_CONTROL_ENABLE; //// RTS flow control
    lpTest.fAbortOnError = TRUE;        // Do not abort reads/writes on error
    SetCommState(hDevice,&lpTest);
    DWORD btsIO;
    //ETC
}

结果与超级终端的工作结果完全相同,只是没有计时条件。但是,在关闭端口之前,我在此代码之后使用了 1 秒延迟。

我的 write 语句有问题吗?

WriteFile(hDevice,c1,strlen(c1),&btsIO,NULL); //Write string to serial

似乎我在做一些根本性的错误,我找不到它!

************ *UPDATE2********** *

我偶然发现了一些东西,如何配置我的程序以单独发送每个字符?

Visual Studio 不允许我在代码中删除 Null 或发送一个字符:

 WriteFile(hDevice,c1,strlen(c1),&btsIO,NULL);//WRITE STRING TO SERIAL

我该如何解决这个问题?似乎 Arduino 板一次只接受一个字符。

我已将字符变量编辑为一个字符等!

*********UPDATE3************** ******

这是监视来自 Visual Studio 2010(或串行通信器)和超级终端的通信的结果。 问题是一次发送一点!

超级终端:

Baud rate 9600
DTR on
Data bits=8, Stop bits=1, Parity=None
Set chars: Eof=0x00, Error=0x00, Break=0x00, Event=0x00, Xon=0x11, Xoff=0x13
Handflow: ControlHandShake=(DTR_CONTROL, CTS_HANDSHAKE, ERROR_ABORT), FlowReplace=    (TRANSMIT_TOGGLE, RTS_HANDSHAKE, XOFF_CONTINUE), XonLimit=80, XoffLimit=200
Set timeouts: ReadInterval=10, ReadTotalTimeoutMultiplier=0,     ReadTotalTimeoutConstant=0, WriteTotalTimeoutMultiplier=0, WriteTotalTimeoutConstant=5000

和程序/串行通信:

Baud rate 9600
DTR on
Data bits=8, Stop bits=1, Parity=None
Set chars: Eof=0x00, Error=0x00, Break=0x00, Event=0x00, Xon=0x11, Xoff=0x13
Handflow: ControlHandShake=(DTR_CONTROL, CTS_HANDSHAKE, ERROR_ABORT), FlowReplace=    (TRANSMIT_TOGGLE, RTS_HANDSHAKE, XOFF_CONTINUE), XonLimit=80, XoffLimit=200

程序代码中的 X 秒等待。

【问题讨论】:

  • 汉斯感谢您的建议。我已经将我的 VS“程序”配置为镜像超级终端(com 程序工作),这正是我帖子的更新部分中的代码。超级终端是否将每个字节和其他字节作为一个组发送? (我将如何纠正这个?

标签: c windows visual-studio-2010 serial-port arduino


【解决方案1】:

自从我上次进行串行工作以来已经有很长时间了 - 但当时非常很清楚您计算机上的软件必须完全按照所需的硬件设备。您的非工作示例没有提出 DTR 或 RTS,而这正是董事会似乎需要的。

由于全功能计算机上的软件通常比嵌入式板上的硬件更容易修改,因此有必要查看串行软件中可用的配置选项——任何可以接受的软件都具有这些要摆弄的设置。如果不是,我喜欢QmodemProComm,尽管我有朋友坚持认为Telix 是更好的工具。 (我有一些 Telix 的贸易战脚本很棒……)

【讨论】:

  • 感谢您的建议。我已经将“程序”配置为镜像超级终端(com 程序正在工作),我的帖子的更新部分中的代码正是如此。超级终端是否将每个字节和其他字节作为一个组发送? (我将如何纠正这个?)
  • 嗯,它是一个串口设备;根据定义,无论操作系统可能代表您执行的任何 IO 缓冲如何,发送给它的每个字符都一次发送一个位,用于所有八位。请注意,您仍然在更新的代码中注释掉了RTS——如果您从未提出RTS,那么设备和计算机可能永远不会认为另一端已准备好发送。您确定诊断工具的输出在工作工具和非工作工具之间是相同的吗?
  • samrnold,甩手一模一样!! “update3 above”(在 VS10 的代码中实现的延迟除外)。主要问题是字符的发送。出于某种未知原因,我的 Arduino Mega 板一次只接收一个字符(使用超级终端,发送一个等待发送下一个等待..'x' ....'1'...'2'.. 等等)VS10程序和串行通信器等都发送字符串“x123y543”
  • 如果您的工具显示您有相同的设置,那么我完全没有想法。 (请注意,您粘贴的最后一个代码示例仍然将 RTS 注释掉...)
  • 谢谢,我知道,如果未注释(启用)它会创建超级终端没有的(发送握手请求)。我曾尝试使用 RTS,但它仍然无法正常工作。我认为arduino缓冲区有问题(串行缓冲区最多可容纳128个(位或字节不会产生差异,128位/ 8 = 16字节>>然后等待发送)
【解决方案2】:

作为一个建议:如果你学习了一些 C# 并使用了 .net API,那么访问串口会很容易......

【讨论】:

  • 注意到了同样的事情.. C# 目前的答案。谢谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多