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]