5

我有一个 Atmel 微控制器发送我想通过 COM1 在我的 PC 上接收的数据。

当我附加一个终端程序时,数据被正确接收(它都是 ascii,除了 \n 之外都是可打印的)。

但是,我的代码似乎正在接收垃圾(非 ascii 字符)。谁能看到我做错了什么?谢谢

发送代码,仅供参考

// USART options.
static const usart_options_t USART_CONSOLE_OPTIONS =
{
    .baudrate     = 115200,
    .charlength   = 8,
    .paritytype   = USART_NO_PARITY,
    .stopbits     = USART_1_STOPBIT,
    .channelmode  = USART_NORMAL_CHMODE
};

接收代码

E_boolean OpenCom1(void)
{
   COMMTIMEOUTS timeouts;

   comPortHandle = CreateFile("COM1",  // Specify port device: default "COM1"
   GENERIC_READ | GENERIC_WRITE,       // Specify mode that open device.
   0,                                  // the device isn't shared.
   NULL,                               // the object gets a default security.
   OPEN_EXISTING,                      // Specify which action to take on file.
   0,                                  // default (not overlapped i/o).
   NULL);                              // default (hTemplate must be NULL for COM devices).

   if (comPortHandle == INVALID_HANDLE_VALUE)
      return False;

   deviceControlBlock.DCBlength = sizeof(deviceControlBlock);

    if((GetCommState(comPortHandle, &deviceControlBlock) == 0))
    {
      // CodeMe: do what?
      return False;
    }

    deviceControlBlock.BaudRate = CBR_115200;
    deviceControlBlock.StopBits = ONESTOPBIT;
    deviceControlBlock.Parity   = NOPARITY;
    deviceControlBlock.ByteSize = DATABITS_8;
    deviceControlBlock.fRtsControl = 0;

    if (!SetCommState(comPortHandle, &deviceControlBlock))
    {
      // CodeMe: do what?
      return False;
    }

    // set short timeouts on the comm port.
    timeouts.ReadIntervalTimeout = MAXDWORD;
    timeouts.ReadTotalTimeoutMultiplier = MAXDWORD;
    timeouts.ReadTotalTimeoutConstant = 1000;   // oen second
    timeouts.WriteTotalTimeoutMultiplier = 1;
    timeouts.WriteTotalTimeoutConstant = 1;
    if (!SetCommTimeouts(comPortHandle, &timeouts))
    {
      // CodeMe: do what?
      return False;
    }

   FlushFileBuffers(comPortHandle);

   PurgeComm (comPortHandle, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR);

   return True;
}//OpenCom1()

// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=
void      ReadCharacterFromCom1(INPUT char *theCharacter)
{
   DWORD numBytesRead;

   numBytesRead = 0;

   while (numBytesRead == 0)
   {
      ReadFile(comPortHandle,           // handle of file to read
               theCharacter,            // store read data here
               sizeof(char),            // number of bytes to read
               &numBytesRead,           // pointer to number of bytes actually read
               NULL);
   }

   return;
}//ReadCharacterFromCom1()
4

2 回答 2

5

使用“sizeof(char)”调用函数“ReadFile”以获取要读取的字节数。这将始终被评估为 1,可能不是您想要的值。结果是每次调用 ReadCharacterFromCom1 只会从端口读取 1 个有效字符并返回,您看到的其余部分是留在缓冲区中的垃圾,因为缓冲区不是(手动)以空值终止的。

建议你改成:

 /* ============================================================ */
DWORD ReadCharacterFromCom1(char *pszBuffer, int nMaxCharToRead)
{
    DWORD dwBytesRead = 0;
    while (dwBytesRead == 0)
    {   ReadFile(comPortHandle, // handle of file to read
            pszBuffer,  // store read data here
            nMaxCharToRead, // number of bytes to read
            &dwBytesRead,   // pointer to number of bytes actually read
            NULL);
    }
    // terminate string with null
    pszBuffer[dwBytesRead] = 0;
    return dwBytesRead;
}

// test code ------------------------
char szBuffer[512];
DWORD dwCount = ReadCharacterFromCom1(szBuffer, sizeof(szBuffer)-1);
printf(_T("Receive %d chars: <%s>"), nCount, szBuffer);
于 2013-03-04T13:27:29.073 回答
2

假设波特率、数据位数、奇偶校验和停止位数设置正确,您很可能缺少设置任何类型的流量控制。您没有(完全)向我们展示您如何初始化 DCB。

流量控制禁止发送方/接收方中的缓冲区溢出。

根据您使用的串行电缆类型以及应传输的数据类型,可以使用软流控制或硬件流控制。

硬件流控制是首选类型的流控制,因为它适用于要传输的纯 ASCII和二进制数据。它需要一个完全有线的串行连接。它也称为 RTS 和/或 DTR 流控制。

如果您只有最小的三线 RS232/V.24 电缆,您可能希望使用软件流控制(也称为 Xon/Xoff 握手)。Xon/Xoff-handshake 流控制仅适用于要传输的 ASCII 数据。要通过这种连接发送二进制数据,需要将其编码为纯 ASCII。例如,使用 base64 编码来执行此操作。

如何在windows下设置流量控制你可能想在这里阅读:http ://www.cplusplus.com/forum/windows/89698/

这个http://msdn.microsoft.com/en-us/library/ff802693.aspx可以作为参考。

于 2013-03-04T07:29:56.517 回答