PC通过串口读取rs232条码扫描枪扫描的条码问题
底存实际传输我不太懂,从网上找了一些代码,自己试验了一下,可以读出来,是用的异步读取模式,但现在有一个问题,我重复扫描相同条码100次,会有20到30次读取不准,发生截断,一个条码作两次读出来。
直接上代码,
我用的是COM1口,基本设置如下:
dcb.BaudRate = 9600; //波特率为9600
dcb.ByteSize = 8;//每个字节有8位
dcb.Parity = NOPARITY; //无奇偶校验位
dcb.StopBits = ONESTOPBIT; //一个停止位
//设定超时
COMMTIMEOUTS TimeOuts;
TimeOuts.ReadIntervalTimeout = MAXDWORD;
TimeOuts.ReadTotalTimeoutMultiplier=1000;
TimeOuts.ReadTotalTimeoutConstant=1000;
//在读一次输入缓冲区的内容后读操作就立即返回,
//而不管是否读入了要求的字符。
//设定写超时
TimeOuts.WriteTotalTimeoutMultiplier=50;
TimeOuts.WriteTotalTimeoutConstant=5000;
读取代码
UINT __cdecl OnWatchCom(LPVOID lparam){ CBillDlg *pDlg = (CBillDlg *)lparam; if(pDlg == NULL) return -1; CString strResult; char buff[128] = {0}; while(pDlg->m_IsWatching) { if(pDlg->m_Com.ReadCom(buff,128,2000)) { pDlg->m_Com.ClearComBuf(PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR); strResult.Format(_T("%s"),buff); if(!strResult.IsEmpty()) { pDlg->m_strBillNo = strResult; pDlg->UpdateData(0); } } Sleep(50); } return 0;}BOOL CComport::ReadCom(char *buff, int nlen, int dwMiniTimeout){ if(!IsOpen()) return FALSE; OVERLAPPED m_osRead; memset(&m_osRead,0,sizeof(OVERLAPPED)); m_osRead.hEvent=CreateEvent(NULL,TRUE,FALSE,NULL); COMSTAT ComStat; DWORD dwErrorFlags; memset(buff,'\0',nlen); DWORD dwBytesRead=nlen;//读取的字节数 BOOL bReadStat; ClearComErr(&dwErrorFlags,&ComStat); dwBytesRead=min(dwBytesRead, (DWORD)ComStat.cbInQue); bReadStat=ReadFile(m_hCom,buff,dwBytesRead,&dwBytesRead,&m_osRead); if(!bReadStat) { if(GetLastError()==ERROR_IO_PENDING)//GetLastError()函数返回ERROR_IO_PENDING,表明串口正在进行读操作 { //GetOverlappedResult(m_hCom,&m_osRead,&dwBytesRead,TRUE); WaitForSingleObject(m_osRead.hEvent,dwMiniTimeout); //使用WaitForSingleObject函数等待,直到读操作完成或延时已达到2秒钟 //当串口读操作进行完毕后,m_osRead的hEvent事件会变为有信号 //ResetEvent(m_osRead.hEvent); } } CloseHandle(m_osRead.hEvent); return TRUE;}
3 WaitCommEvent 无限等待可读事件 你这里用循环不是浪费cpu么
4 ClearComErr 取得可读的数据的大小
5 ReadFile 在异步模式下100%错误的
6 GetOverlappedResult 无限等待读事件完成
这个模式下WaitCommEvent 会被卡住 你要停止线程运行 给WaitCommEvent的事件信号 让他完成等待
[解决办法]
不管用不用注册事件的方式,调用ReadFile只要收到数据就能读出来的,至于数据长度取决于收到多少了。
假如你在WriteFile之后等的时间够长,估计每次都能读全,这是效率明显下降了。。
[解决办法]
循环读,然后检测返回的数据中如果有0x0D,则返回开始读到的数据
[解决办法]
有一个CSerialPort的类,是用线程的。在界面中用消息得到数据,再自己拼条码试试。
[解决办法]
总觉得你的写法好怪。不要拍我:)