关于开源串口类SerialPort,读串口返回数据时每个字符都触发一次读函数!

女神打Boss 2016-01-26 05:01:36
如题:读串口时每个字符都触发一次读函数,我怎么知道它读完了?(我不能规定返回数据的长度,和结束字符)

我是modbus rtu,如果上述问题没有好办法解决,请推荐另一个开源串口类。
...全文
1823 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
收获de季节 2016-12-01
  • 打赏
  • 举报
回复
让本线程休眠80ms都可以。不需要那么复杂
女神打Boss 2016-03-01
  • 打赏
  • 举报
回复
SerialPort类的话响应WM_COMM_RXFLAG_DETECTED消息就好了,另一边每次发送都会触发这个消息
洗洗睡去 2016-01-30
  • 打赏
  • 举报
回复
很明显是你没设置缓冲区触发阈值,mscomm控件里是setthreshold,cncom里是m_Com.SetNotifyNum(23); serialport就不知道了,http://blog.csdn.net/sunnyloves/article/details/5575995
  • 打赏
  • 举报
回复
SerialPort在串口缓冲区中每次读一个字节,通过消息的方式发送,不能判断结束,除非自己改造一下。 void CSerialPort::ReceiveChar(CSerialPort* port, COMSTAT comstat) { BOOL bRead = TRUE; BOOL bResult = TRUE; DWORD dwError = 0; DWORD BytesRead = 0; unsigned char RXBuff; for (;;) { //add by liquanhai 防止死锁 2011-11-06 if(WaitForSingleObject(port->m_hShutdownEvent,0)==WAIT_OBJECT_0) return; // Gain ownership of the comm port critical section. // This process guarantees no other part of this program // is using the port object. EnterCriticalSection(&port->m_csCommunicationSync); // ClearCommError() will update the COMSTAT structure and // clear any other errors. bResult = ClearCommError(port->m_hComm, &dwError, &comstat); LeaveCriticalSection(&port->m_csCommunicationSync); // start forever loop. I use this type of loop because I // do not know at runtime how many loops this will have to // run. My solution is to start a forever loop and to // break out of it when I have processed all of the // data available. Be careful with this approach and // be sure your loop will exit. // My reasons for this are not as clear in this sample // as it is in my production code, but I have found this // solutiion to be the most efficient way to do this. if (comstat.cbInQue == 0) { // break out when all bytes have been read break; } EnterCriticalSection(&port->m_csCommunicationSync); if (bRead) { bResult = ReadFile(port->m_hComm, // Handle to COMM port &RXBuff, // RX Buffer Pointer 1, // Read one byte &BytesRead, // Stores number of bytes read &port->m_ov); // pointer to the m_ov structure // deal with the error code if (!bResult) { switch (dwError = GetLastError()) { case ERROR_IO_PENDING: { // asynchronous i/o is still in progress // Proceed on to GetOverlappedResults(); bRead = FALSE; break; } default: { // Another error has occured. Process this error. port->ProcessErrorMessage("ReadFile()"); break; } } } else { // ReadFile() returned complete. It is not necessary to call GetOverlappedResults() bRead = TRUE; } } // close if (bRead) if (!bRead) { bRead = TRUE; bResult = GetOverlappedResult(port->m_hComm, // Handle to COMM port &port->m_ov, // Overlapped structure &BytesRead, // Stores number of bytes read TRUE); // Wait flag // deal with the error code if (!bResult) { port->ProcessErrorMessage("GetOverlappedResults() in ReadFile()"); } } // close if (!bRead) LeaveCriticalSection(&port->m_csCommunicationSync); // notify parent that a byte was received ::SendMessage((port->m_pOwner)->m_hWnd, WM_COMM_RXCHAR, (WPARAM) RXBuff, (LPARAM) port->m_nPortNr); } // end forever loop } 这是它的读取串口数据函数,其中bResult = ClearCommError(port->m_hComm, &dwError, &comstat);可以判断串口缓冲区中的字节数,读取缓冲区字节数为comstat.cbInQue。 从缓冲区读取数据函数为 bResult = ReadFile(port->m_hComm, // Handle to COMM port &RXBuff, // RX Buffer Pointer 1, // Read one byte &BytesRead, // Stores number of bytes read &port->m_ov); // pointer to the m_ov structure 其中第三个参数为读取字节的个数,SerialPort将其设为1,所以每次读一个字节,直到读完缓冲区中的数据为止。 如果想一次性读取缓冲区中的全部数据,可以将此参数设为comstat.cbInQue,第二个参数也要重新设置。
女神打Boss 2016-01-27
  • 打赏
  • 举报
回复
引用 2 楼 worldy 的回复:
modbus rtu,判断结束是比较蛋疼的,一般使用检测一定时间(比如10ms)没有再接收到数据,即判断接收结束
我发现有的自己写的串口通信代码可以判断一次发送就触发一次读函数,这个实现原理是什么
worldy 2016-01-26
  • 打赏
  • 举报
回复
modbus rtu,判断结束是比较蛋疼的,一般使用检测一定时间(比如10ms)没有再接收到数据,即判断接收结束
  • 打赏
  • 举报
回复
一般来说,传的数据应该有一定格式的,你应该按照这个来分析。

2,586

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 资源
社区管理员
  • 资源
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧