写了一个PC与单片机的串口通信程序.为了防止串口出错在每个数据帧之前都要初始化一次串口,所以串口初始化函数频繁被调用..现在程序运行一段时间后初始化串口程序就会出错返回 INVALID_HANDLE_VALUE .单步调试的时候好像又没有这个问题.我在想是不是因为初始化过于频繁造成的.在程序中加了Sleep(1)函数也不行也不能Sleep(1)过长这样程序效率太低..现在不知道到底是什么原因造成的creatfile()错误.
现在的通信协议是这样的。上位机每100MS给下位机发送一个检测数据,下位机如果收到这个数据着不复位。如果一段时间没有收到这个数据则复位串口一次。下位机收到数据后会发送一个确认数据到上位机。上位机发送完一帧数据之后便停止发送等待下位机的确认信号。如果收到确认信号则开始下一帧发送。如果在一段时间内没有收到下位机的确认信号则重发数据。在发送每一帧数据前初始化一次串口这样保证串口在发送数据前的正确性。想法是如果串口有问题则初始化串口会失败。
对于每一帧数据前初始化一次串口这个问题现在存在疑问。是不是初始化串口正确就一定能保证串口是畅通的。???
项目很急,跪求大侠的意见.
初始化串口程序如下:(没有加入收发缓冲区初始化以及清空操作是因为已经在另外的函数中完成一次.不需要频繁操作)
BOOL CSerialPort::InitPort_Send(CWnd* pPortOwner, // the owner (CWnd) of the port (receives message) UINT portnr, // portnumber (1..4) UINT baud, // baudrate char parity, // parity UINT databits, // databits UINT stopbits, // stopbits DWORD dwCommEvents, // EV_RXCHAR, EV_CTS etc UINT writebuffersize) // size to the writebuffer { //AfxMessageBox( "INIT ");
m_pOwner = pPortOwner; m_nPortNr = portnr; m_dwCommEvents = dwCommEvents;
BOOL bResult = FALSE; char *szPort = new char[50]; char *szBaud = new char[50]; EnterCriticalSection(&m_csCommunicationSync); // if the port is already opened: close it if (m_hComm != NULL) { CloseHandle(m_hComm); m_hComm = NULL; }
Sleep(1);
// prepare port strings sprintf(szPort, "COM%d ", portnr); sprintf(szBaud, "baud=%d parity=%c data=%d stop=%d ", baud, parity, databits, stopbits);
// get a handle to the port m_hComm = CreateFile(szPort, // communication port string (COMX) GENERIC_READ ¦ GENERIC_WRITE, // read/write types 0, // comm devices must be opened with exclusive access NULL, // no security attributes OPEN_EXISTING, // comm devices must use OPEN_EXISTING FILE_FLAG_OVERLAPPED, // Async I/O 0); // template must be 0 for comm devices
if (m_hComm == INVALID_HANDLE_VALUE) { // port not found delete [] szPort; delete [] szBaud;
LeaveCriticalSection(&m_csCommunicationSync);
Flag_stop = TRUE;
return FALSE; }
// set the timeout values m_CommTimeouts.ReadIntervalTimeout = MAXDWORD; m_CommTimeouts.ReadTotalTimeoutMultiplier = MAXDWORD; m_CommTimeouts.ReadTotalTimeoutConstant = 20; m_CommTimeouts.WriteTotalTimeoutMultiplier = 1000; m_CommTimeouts.WriteTotalTimeoutConstant = 1000;
// configure if (SetCommTimeouts(m_hComm, &m_CommTimeouts)) { if (SetCommMask(m_hComm, dwCommEvents)) { if (GetCommState(m_hComm, &m_dcb)) { m_dcb.EvtChar = 'q '; m_dcb.fRtsControl = RTS_CONTROL_ENABLE; // set RTS bit high! if (BuildCommDCB(szBaud, &m_dcb)) { if (SetCommState(m_hComm, &m_dcb)) ; // normal operation... continue else ProcessErrorMessage( "SetCommState() "); } else ProcessErrorMessage( "BuildCommDCB() "); } else ProcessErrorMessage( "GetCommState() "); } else ProcessErrorMessage( "SetCommMask() "); } else ProcessErrorMessage( "SetCommTimeouts() ");
delete [] szPort; delete [] szBaud;
// release critical section LeaveCriticalSection(&m_csCommunicationSync);
TRACE( "Initialisation for communicationport %d completed.\nUse Startmonitor to communicate.\n ", portnr);
Flag_stop = FALSE; return TRUE; } |