【问题标题】:WriteFile doesnt work without debug没有调试,WriteFile 不起作用
【发布时间】:2015-05-12 14:53:46
【问题描述】:

我正在尝试向我的 arduino 发送参数。所以我做了这个代码:

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

 HANDLE serialPortHandler;
 char *comPort[8] =  {"1", "2", "3", "4", "5", "6", "7", "8"};
 char comPortName[5] = "COM";
 int i = 1;

int openPort(char *name){

    serialPortHandler = CreateFile(name, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0);
    if(serialPortHandler == INVALID_HANDLE_VALUE){
        return -1;
    }else{
        DCB dcb;
       FillMemory(&dcb, sizeof(dcb), 0);
       if (!GetCommState(serialPortHandler, &dcb)){
          return -1;
       }

       dcb.BaudRate = CBR_9600 ;

       if (!SetCommState(serialPortHandler, &dcb)){
            return -1;
       }
    }
    return 1;
}

int writePort(char *lpBuf,DWORD dwToWrite){
        DWORD dwWritten;
     if(WriteFile(serialPortHandler, lpBuf, dwToWrite, &dwWritten, NULL)){
            while(dwWritten < dwToWrite);
            printf("User: %s, %d", lpBuf, dwWritten);  
            return 0;                                                                            
     }else{
           printf("Error");
           CloseHandle(serialPortHandler);
           return 1;
     }
     return 0;                               
}




int main(int argc, char *argv[]){
    if(argc != 2)
            return 1;
    strcat(comPortName, comPort[0]);
    while(openPort(comPortName) < 0 && i < sizeof(comPort) / sizeof(int)){
        comPortName[3] = *comPort[i];
        //printf("%s", comPortName);
        i++;
        Sleep(0);
    }if(i >= sizeof(comPort) / sizeof(int)){
         printf("Cannot Find Port");
         scanf("%d");
         return 1;
    }
    printf("Port %s Is Opened - BaudRate 9600\n", comPortName);
    printf("Sent Frequency: %s\n", argv[1]);
    writePort(argv[1], strlen(argv[1]));
} 

但只有当我在调试模式下运行它并在 WriteFile 等待片刻时它才有效。如果我从 cmd 运行它,它不会输出到我的 arduino。

【问题讨论】:

  • while(dwWritten &lt; dwToWrite); - 如果条件为真,它将永远循环。这是故意的吗?
  • dwWritten 是函数的输出,因此它可以随时间变化。变量是发送的字节数。所以 while 循环正在增加,当函数发送所有循环时,dwWritten 将等于 dwToWrite 并且它将继续。
  • WriteFile() 只是将字节复制到驱动程序的传输缓冲区中,实际传输它们需要大量时间。如果调试器不会减慢您的程序,则在您调用 WriteFile() 后端口将立即关闭。因为您的程序会立即终止。这可以防止发送那些缓冲的字节。为 dwWritten 毫秒调用 Sleep() 很麻烦,但可能有效,最好在循环中调用 ClearCommError(),这样您就可以看到 COMSTAT.cbOutQue 字段达到 0。现在您知道传输缓冲区是空的,因此可以关闭港口。
  • 我将 WriteFile 之后的 else 更改为如下所示: else{ do{ ClearCommError(serialPortHandler, &lpErr, &lpStat); }while(lpStat.cbOutQue > 0); fRes =真; }
  • @TatGonen 不,它不能改变,除非你调用函数。

标签: c serial-port arduino port communication


【解决方案1】:

WriteFile 函数具有异步运行的能力。你检查过这个案例吗?

发件人:https://msdn.microsoft.com/en-us/library/windows/desktop/aa365747(v=vs.85).aspx

如果函数失败或异步完成,则返回值为零 (FALSE)。要获取扩展错误信息,请调用 GetLastError 函数。

当下列情况之一发生时,WriteFile 函数返回:

  • 请求的字节数已写入。
  • 读取操作释放管道读取端的缓冲区空间(如果写入被阻止)。有关详细信息,请参阅管道部分。
  • 正在使用异步句柄,并且正在异步进行写入。
  • 出现错误。

(元:我猜不能引用项目符号列表)

【讨论】:

  • 他没有在异步模式下打开端口,所以你引用的点不适用。
  • @MatteoItalia - 啊,我被“如果我在调试模式下运行它并等待片刻就可以工作”所吸引,这让 async 听起来像是一个很好的嫌疑人,但需要一个异步句柄,所以你可能是对的。
【解决方案2】:

问题是启动这两件事需要时间: 1.SetCommState(serialPortHandler, &dcb)

所以我之前添加了睡眠,它解决了问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-10-25
    • 1970-01-01
    • 2013-03-17
    • 2020-06-30
    • 2017-03-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多