inkfish321 发表于 2013-2-22 13:54:41

VC 下串口读总是失败,谁做过的指点一下。

int COMIO_ReadByte(char * pData, unsigned int dwMilliseconds)
{
    BOOLbResult = TRUE;
    BOOLbRead = TRUE;
        int dwResult;

    DWORD dwError = 0;

    COMSTAT comstat;
    OVERLAPPED gOverlapped;

    LPDWORD nBytesWritten;

        char RXBuff;
    DWORD BytesRead = 0;
       
    if(hDev == INVALID_HANDLE_VALUE)
    {
                ProcessErrorMessage("COMIO_ReadByte()");
                return -1;
    }
    // set up overlapped structure fields
    gOverlapped.Internal   = 0;
    gOverlapped.InternalHigh = 0;
    gOverlapped.Offset       = 0;
    gOverlapped.OffsetHigh   = 0;
    gOverlapped.hEvent       = CreateEvent(NULL, TRUE, FALSE, NULL);


        dwResult = -1;

    bResult = ClearCommError(hDev, &dwError, &comstat);       
        TRACE2("comstat.cbInQue = %d\r\n", comstat.cbInQue);
        if(comstat.cbInQue >0)
    {
      while(bRead)
      {

              bResult = ReadFile(hDev, &RXBuff, 1, &BytesRead, &gOverlapped);
            if (!bResult)
            {               
                switch (dwError = GetLastError())
               {
                  case ERROR_IO_PENDING:
                  {       
                                          switch(WaitForSingleObject(gOverlapped.hEvent, dwMilliseconds))
                                          {
                                               
                                                  case WAIT_OBJECT_0:
                                                          TRACE4("%s %s %d\r\n", __FILE__, __FUNCTION__, __LINE__);
                                                          break;

                            case WAIT_TIMEOUT:
                                                          TRACE4("%s %s %d\r\n", __FILE__, __FUNCTION__, __LINE__);
                              bRead = FALSE;
                                       
                              break;
                                             }//end switch
                                             CancelIo(hDev);
                         break;

                  }
                  default:
                  {
                        break;
                  }

               }
               bResult = ClearCommError(hDev, &dwError, &comstat);       
            }
            else
            {   
                TRACE2("RXBuff = %2x \r\n", RXBuff);
                *pData = RXBuff;
                dwResult = 0;
                bRead = FALSE;
            }
      }
        }
    ResetEvent(gOverlapped.hEvent);       
    CloseHandle(gOverlapped.hEvent);
        return dwResult;

}

intCOMIO_Read(void * pData,            // Output
                unsigned int dwLen,            // Input
                unsigned int *pLength,         // Output
                unsigned int dwMilliseconds)   // Input
{
    BOOLbResult = TRUE;
        BOOLbRead = TRUE;

        int dwResult;
        unsigned int delay = dwMilliseconds;

    DWORD dwError = 0;
        DWORD dwMask;


        LPDWORD nBytesWritten;
       
    COMSTAT comstat;
    OVERLAPPED gOverlapped;
        char RXBuff;
   
    if(hDev == INVALID_HANDLE_VALUE)
    {
                ProcessErrorMessage("COMIO_Read()");
                return -1;
    }
       
    // set up overlapped structure fields
   
    gOverlapped.Internal   = 0;
    gOverlapped.InternalHigh = 0;
    gOverlapped.Offset       = 0;
    gOverlapped.OffsetHigh   = 0;
    gOverlapped.hEvent       = CreateEvent(NULL, TRUE, FALSE, NULL);
   

        dwResult = -1;
        bResult = ClearCommError(hDev, &dwError, &comstat);       
        if(!WaitCommEvent(hDev, &dwMask, &gOverlapped))
        {
                        switch (dwError = GetLastError())
                        {
                                case ERROR_HANDLE_EOF:
                                {
                                        // we have reached the end of the file
                                        // during the call to ReadFile
                                        break;
                                }
                                case ERROR_IO_PENDING:
                                {
                                        // asynchronous i/o is still in progress
                                        switch(WaitForSingleObject(gOverlapped.hEvent, dwMilliseconds))
                                        {
                                               
                                                case WAIT_OBJECT_0:
                                                        TRACE4("%s %s %d\r\n", __FILE__, __FUNCTION__, __LINE__);
                                                        GetOverlappedResult(hDev, &gOverlapped, (LPDWORD)&nBytesWritten, TRUE);
                                                        break;
                                                case WAIT_TIMEOUT:
                                                        TRACE4("%s %s %d\r\n", __FILE__, __FUNCTION__, __LINE__);
                            break;
                                       }//end switch
                                       CancelIo(hDev);
                                       break;
       
                                }//end case
                                default:
                                        CancelIo(hDev);
                                        break;
                        }
       
        }
        ResetEvent(gOverlapped.hEvent);
    CloseHandle(gOverlapped.hEvent);
       
    while(bRead)
    {
      if(UartReceiver.mReceiveState == RECEIVE_PACK_HEAD_1)
      {
          dwResult = COMIO_ReadByte(&RXBuff, 50);
      }
                else
                {
                  dwResult = COMIO_ReadByte(&RXBuff, 5000);
                  
                }
                if(dwResult == 0)
                {
            ProcessPackReceiv(RXBuff);
                }
                else
                {
                  bRead = FALSE;
                }
        }
            
        if((UartReceiver.mReceiveState == RECEIVE_PACK_END) &&
          (pData != NULL) &&
          (pLength != NULL))
        {
          *pLength = UartReceiver.mPackLength + PACK_HEAD_LENGTH + PACK_LEN_LENGTH;
      memcpy(pData, UartReceiver.mReceiveBuffer, *pLength);
                dwResult = 0;
        }
        if((UartReceiver.mReceiveState == RECEIVE_PACK_END) ||
                (UartReceiver.mReceiveState == RECEIVE_PACK_ERROR))
        {
          UartReceiver.mReceiveState = RECEIVE_PACK_HEAD_1;
        }

        return dwResult;
}

SPORTLIB_API int ReadPack(void * pData,            // Output
                unsigned int dwLen,            // Input
                unsigned int *pLength,         // Output
                unsigned int dwMilliseconds)
{
        return COMIO_Read(pData, dwLen, pLength, dwMilliseconds);
}

SPORTLIB_API intWriteFlash( unsigned int address, unsigned char * inputData, unsigned short len)
{
        unsigned short pkgAllLen,temp;
        unsigned int bytes;
        unsigned char *buffer;
   
        pkgAllLen = len + PACK_HEAD_LENGTH + PACK_LEN_LENGTH + COMMAND_LENGTH
                        + FLASH_ADDRESS_LENG + WRITE_FLASH_DATA_LENG + CRC_LENGTH;;
        buffer = (unsigned char *)malloc(pkgAllLen);

    buffer = PACK_HEAD_1_FLAG;
    buffer = PACK_HEAD_2_FLAG;

    temp = pkgAllLen - PACK_HEAD_LENGTH - PACK_LEN_LENGTH;
    Buffer_Write_Half_Word(temp, &buffer);
    buffer = FLASH_WRITE;
    Buffer_Write_Word(address, &buffer);
        Buffer_Write_Half_Word(len, &buffer);
        memcpy(&buffer, inputData, len);

    if (SendPack(buffer) == -1)
    {           
      TRACE1("WriteFlash:write command failed!\n");
      if(buffer)
                  free(buffer);
      return ERROR1_WRITE_FLASH;
    }
    if(buffer)
      free(buffer);

    pkgAllLen = PACK_HEAD_LENGTH + PACK_LEN_LENGTH + COMMAND_LENGTH + CRC_LENGTH;
       
    UartReceiver.mReceiveState = RECEIVE_PACK_HEAD_1;
       
    if(ReadPack(RCV_BUF, pkgAllLen, &bytes, 5000) == -1)
    {
      TRACE1("WriteFlash: write answer error 1 !\n");

      return ERROR2_WRITE_FLASH;
    }

    if((bytes < pkgAllLen) ||        (RCV_BUF != ACK))
    {
      TRACE1("WriteFlash: write answer error 2!\n");
      return ERROR3_WRITE_FLASH;
    }

    return 0;       

}

程序在频繁操作串口接收时容易出错,主要问题是当调用SendPack发送出写FLASH命令后MCU已经接收到命令,但是调用ReadPack有时候会接收不到数据,
if(comstat.cbInQue >0) 条件不成立。ReadPack(RCV_BUF, pkgAllLen, &bytes, 5000)等待了5秒。过后在其它地方调用ReadPack,又能接收到,表明MCU是有应答的。
页: [1]
查看完整版本: VC 下串口读总是失败,谁做过的指点一下。