分类:
2008-10-14 15:00:21
多线程,多接收模式串口类 LsComm 之二
作者:
if(this->IsOverlapped()) { this->m_hWriteEvent= ::CreateEvent(NULL,true,false,NULL); if(this->m_hCloseEvent==NULL) return false; this->m_WriteOverlapped.hEvent = this->m_hWriteEvent; }2.ERR : 修改了 ManualReceiveByQuery 模式下,发送会出现不动的情况。
dwWriteBytes= this->m_pPort->Write(pBuf,Count);
前,串口已经设置中断,所以需要等待中断事件发生。
修改: 去掉中断设置的代码
this->m_pPort->GetSerialPort()->SetMask(dwStoredFlags);
3.ERR : 打开一个计算机上不存在的串口的时候没有异常捕获。
原因: 没有捕获 CserialPort 抛出的 CserialException 异常
修改: 不过对于异常的处理改为不抛出异常,不知道是否妥当?
try { this->m_pPort->Open(nPort,dwBaud,spParity,DataBits,spStopbits,spFC,m_IsOverlapped); } catch(CSerialException* pE) { //AfxMessageBox(pE->GetErrorMessage()); pE->Delete(); return false; }4.ERR : 感觉 AutoReceiveByBreak 意义不大应该去掉
this->m_ComPort.GetSerialPort()->Close();收发数据的时候就会产生异常。但是由于使用别人的CserialPort类 ,比较
void OnReceiveData(LPVOID pSender,void* pBuf,DWORD InBufferCount) {//在此处理要接收的数据 }(2)然后,打开串口,监听Com2
this->m_ComPort.Open(2,LsComm::CComPort::AutoReceiveBySignal ); this->m_ComPort.SetReceiveFunc((FOnReceiveData)OnReceiveData,this);(3)发送:
char a[10000];//字符数组 BYTE b[10000];//字节数组 memset(a,''''a'''',sizeof(a)); memset(b,0x0b,sizeof(b)); this->m_ComPort.Output(a,sizeof(a)); //发送字符数组 this->m_ComPort.Output(b,sizeof(b)); //发送字节数组感觉在C里面是不分 char 和字节的,像 char c=’a’;和char c=0x61;是一样的,只不过 char 只能取字符类型范围,超过就被截短。
void OnComBreak(LPVOID pSender,DWORD dwMask,COMSTAT stat) { //deal with the break of com here switch(dwMask) { case EV_BREAK: { break; } case EV_CTS: //在这里处理CTS信号 { break; } } }3. greatim:DataWaiting 是有什么用的??在例子程序里没有引用到。而且在 Open 的函数里,CreateEvent 被屏蔽了,是否代表 DataWaiting 这函数不能使用呢? DataWaiting 和 Attech 有什么关系?
BOOL CSerialPort::DataWaiting(DWORD dwTimeout) { ASSERT(IsOpen()); ASSERT(m_hEvent); //Setup to wait for incoming data DWORD dwOldMask; GetMask(dwOldMask); SetMask(EV_RXCHAR);//1.设置接收中断事件 //Setup the overlapped structure OVERLAPPED o; o.hEvent = m_hEvent; //Assume the worst; BOOL bSuccess = FALSE; DWORD dwEvent; bSuccess = WaitEvent(dwEvent, o);//2. 设置监听 if (!bSuccess) {//3.dwTimeOut为所等待的时间,有数据收到,返回发现数据 if (WaitForSingleObject(o.hEvent, dwTimeout) == WAIT_OBJECT_0) { DWORD dwBytesTransferred; GetOverlappedResult(o, dwBytesTransferred, FALSE); bSuccess = TRUE; } } //Reset the event mask SetMask(dwOldMask); return bSuccess; }这好像与 Attach 没什么关系吧?
BOOL bSuccess = ReadFile(m_hComm, lpBuf, dwCount, &dwBytesRead, &overlapped); dwSignaledHandle=::WaitForMultipleObjects(3,WaitHandles,false,INFINITE);
或
this->m_pPort->GetSerialPort()->GetOverlappedResult(overlapped,this->m_InBufferCount,false)
这个两个函数
WaitForMultipleObject
或
GetOverlappedResult)
它会以 COMMTIMEOUTS 中设置的 timeout 来返回吗?也就是说 Overlapped 中的 Event 是在什么时候激活的?
答:这个问题我以前没有仔细考虑,真是不好意思。好像 COMMTIMEOUTS的TimeOut 仅对 ReadFile,WriteFile 起作用,具体可以看 MSDN 中 COMMTIMEOUTS 的描述
。
WaitForSingleObject(m_ReadOverlapped.hEvent,dwMilliseconds)==WAIT_OBJECT_0)
会等待 m_ReadOverlapped.hEvent 事件置信号标志的时候返回。那么读取
时间什么时候返回呢,找了下面的一段话:
When reading from a communications device, the behavior of ReadFile is governed by the current communication time-outs as set and retrieved using the SetCommTimeouts and GetCommTimeouts functions. Unpredictable results can occur if you fail to set the time-out values. For more information about communication time-outs, see COMMTIMEOUTS.
可见 SetCommTimeouts 对这 ReadFile 起作用,也就是对 m_ReadOverlapped.hEvent 起作用。因此定时间接收模式在 COMMTIMEOUTS 时也会置读事件的 hEvent,所以等待
时间的限制就有可能不太准确。
6. Hi_nihaoma:为什么我使用重叠方式打开串口,根据示例:
for(int j= 0; j< 10; j++) { if (!port2.Write(pBuf, 10000, overlapped)) { DWORD dwBytesWritten; WaitForSingleObject(event, INFINITE); port2.GetOverlappedResult(overlapped, dwBytesWritten, TRUE); } if (!port2.Read(pBuf, 10, overlapped)) { DWORD dwBytesRead; if (WaitForSingleObject(event,1000) == WAIT_OBJECT_0) { TRACE(_T("Data was read from the serial port\n")); port2.GetOverlappedResult(overlapped,dwBytesRead,FALSE); } else TRACE(_T("No data was read from the serial port\n")); } port2.SetMask(EV_TXEMPTY); port2.WaitEvent(dwMask,overlapped); } port2.GetOverlappedResult(overlapped,dwBytesRead,FALSE); dwByteRead= 4啊???急急急!!!答:感觉可能是接收的问题,不能所有容纳发送的全部数据,而引发异常吧。看你这行port2.Write(pBuf, 10000, overlapped);一次发送这么大的数据量 ,是不是这的问题, 我的计算机上只有一个串口,把2,3口连接后收发数据测试了一下。一次发送超过100个就会发生读地址错误,但是低于这个速率就没问题。可能是接收的速度跟不上吧 。具体问题正在找。