5

COM1を介してPCで受信したいデータを送信するAtmelミロコントローラーがあります。

ターミナルプログラムを接続すると、データは正しく受信されます(\ nを除いて、すべてASCIIで、すべて印刷可能です)。

しかし、私のコードはジャンク(非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

関数「ReadFile」は、読み取るバイト数の「sizeof(char)」を使用して呼び出されます。これは常に1と評価され、おそらく意図した値ではありません。その結果、ReadCharacterFromCom1を呼び出すたびに、ポートから有効な文字が1つだけ読み取られて返されます。残りは、バッファーが(手動で)nullで終了しないため、バッファーに残っているジャンクです。

次のように変更することをお勧めします。

 /* ============================================================ */
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フロー制御とも呼ばれます。

最小限の3線式RS232/V.24ケーブルのみを使用している場合は、ソフトウェアフロー制御(Xon / Xoffハンドシェイクとも呼ばれます)を使用することをお勧めします。Xon / Xoff-ハンドシェイクフロー制御は、転送されるASCIIデータに対してのみ機能します。このような接続を介してバイナリデータを送信するには、純粋なASCIIにエンコードする必要があります。これを行うには、たとえばbase64エンコーディングを使用します。

ここで読みたいウィンドウの下でフロー制御を設定する方法:http ://www.cplusplus.com/forum/windows/89698/

このhttp://msdn.microsoft.com/en-us/library/ff802693.aspxが参照として役立つ場合があります。

于 2013-03-04T07:29:56.517 に答える