搜索
bottom↓
回复: 15

API方式调用串口,PL2303会蓝屏,其它正常,会是.....

[复制链接]

出0入0汤圆

发表于 2014-9-16 09:25:39 | 显示全部楼层 |阅读模式
此程序是我自己参考了VictorComm(VCL控件)写的串口程序,使用时除2303会蓝屏(不管什么系统,WIN7也蓝),其它类型端口使用正常
发上来让大家看看会有什么问题
先谢了
初始化:
  1. SerialPort::SerialPort(char* portname,int baudrate,CTCParity parity,CTCStopBits stopbits,BYTE ByteSize)
  2.     {
  3.                 //char tmp[50];
  4.             _Opened       = false;
  5.             _bFromHandle  = false;
  6.             _DisableWrite = false;
  7.         _isReading    = false;
  8.                 std::string tmp = std::string(portname).substr(3);
  9.             _PortNo     = atoi(tmp.c_str());    //"COM1"
  10.             _PortName   = std::string(portname);

  11.         _HwInSize   = 1200;
  12.             _HwOutSize  = 1200;

  13.             //---- DCB settings ----//
  14.             memset(&_dcb, 0, sizeof(DCB)); //Clear DCB
  15.             _dcb.DCBlength = sizeof(DCB);  //DWORD: sizeof(DCB)

  16.             _dcb.BaudRate  = baudrate; //DWORD: current baud rate
  17.             _dcb.Parity    = parity;   //BYTE : 0-4=no,odd,even,mark,space
  18.             _dcb.ByteSize  = ByteSize;          //BYTE : number of bits/byte, 4-8
  19.             _dcb.StopBits  = stopbits; //BYTE : 0,1,2 = 1, 1.5, 2

  20.             _dcb.fBinary = true;  //DWORD: binary mode, no EOF check
  21.                 if(parity!=NoParity)
  22.                 {
  23.                         _dcb.fParity = true; //DWORD: enable parity checking
  24.                 }
  25.                 else
  26.                 {
  27.                         _dcb.fParity = false; //DWORD: enable parity checking
  28.                 }

  29.             _dcb.fOutxCtsFlow    = false;              //DWORD: CTS output flow control
  30.             _dcb.fOutxDsrFlow    = false;              //DWORD: DSR output flow control
  31.             _dcb.fDtrControl     = DTR_CONTROL_ENABLE; //DWORD: DTR flow control type
  32.             _dcb.fDsrSensitivity = false;              //DWORD: DSR sensitivity

  33.             _dcb.fTXContinueOnXoff = false;              //DWORD: XOFF continues Tx
  34.             _dcb.fOutX             = false;              //DWORD: XON/XOFF out flow control
  35.             _dcb.fInX              = false;              //DWORD: XON/XOFF in flow control
  36.             _dcb.fErrorChar        = false;              //DWORD: enable error replacement
  37.             _dcb.fNull             = false;              //DWORD: enable null stripping
  38.             _dcb.fRtsControl       = RTS_CONTROL_ENABLE; //DWORD: RTS flow control
  39.             _dcb.fAbortOnError     = false;              //WORD : abort reads/writes on error

  40.             _dcb.XonLim            = 2048; //0xffff; //WORD : transmit XON threshold
  41.             _dcb.XoffLim           =  512; //0xffff; //WORD : transmit XOFF threshold

  42.             _dcb.XonChar           = 0x11; //char : Tx and Rx XON character
  43.             _dcb.XoffChar          = 0x13; //char : Tx and Rx XOFF character
  44.             _dcb.ErrorChar         = 0;    //char : error replacement character
  45.             _dcb.EofChar           = 0;    //char : end of input character
  46.             _dcb.EvtChar           = 0;    //char : received event character

  47.               //---- Variables ----//
  48.             _ModemStatus     = 0;   //MS_CTS_ON | MS_DSR_ON | MS_RING_ON | MS_RLSD_ON
  49.             _Handle          = INVALID_HANDLE_VALUE;

  50.             _ReadThreadId       = -1;
  51.             _RunReadThread      =  0;
  52.             _ReadThreadRunning  =  0;

  53.             _WriteThreadId      = -1;
  54.             _RunWriteThread     =  0;
  55.             _WriteThreadRunning =  0;

  56.         _dwTimerInterval     = 10;    //5 ms
  57.         _FrameReceiveTimeOutCnt=0;
  58.         _iSkipTimerEvents    = 0;     //no skip
  59.         _bTimerThreadRunning = false; //not running
  60.         _bRunTimerThread     = true;  //run enabled
  61.             _hKillRead          =  0;
  62.             _hKillWrite         =  0;
  63.             _hSyncWrite         =  0;

  64.             memset(&_ReadOS, 0, sizeof(OVERLAPPED));
  65.             memset(&_WriteOS, 0, sizeof(OVERLAPPED));

  66.         _ReadBuffer = new CircularBuffer();
  67.         _WriteBuffer = new CircularBuffer();
  68.         _ReadFrameBuffer = new CircularBuffer();

  69.         _hFrameReceivedEvent = CreateEvent(NULL, false, false, NULL); //Create Auto-Reset Event
  70.         _isFrameMode = false;
  71.         _hSemaphore = CreateSemaphore(NULL,1, 1, NULL);
  72.     }
复制代码



打开串口:
  1. bool SerialPort::Open(bool isFrameMode)
  2.     {
  3.             if(!_Opened)
  4.             {
  5.                     CTErrorCode ecErrCode = SerialPort::COMM_NOERROR;
  6.                     if((!ecErrCode) && (!_bFromHandle)) //如果已知句柄,不需要打开端口
  7.                     {
  8.                                 wchar_t *sDeviceName = new wchar_t[50];
  9.                             wsprintf(sDeviceName,L"\\\\.\\COM%d",_PortNo);
  10.                             _Handle=CreateFile(sDeviceName, GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING,
  11.                                                             FILE_ATTRIBUTE_NORMAL|FILE_FLAG_OVERLAPPED, NULL);
  12.                             if(_Handle==INVALID_HANDLE_VALUE)
  13.                             {
  14.                                     ecErrCode = SerialPort::COMM_OPENPORT; //不能打开端口
  15.                     LOG(ERROR)<<"SerialPort::Open->ecErrCode:不能打开端口";
  16.                             }
  17.                     }
  18.                     if((!ecErrCode) && (!SetCommMask(_Handle, EV_RXFLAG/*0x1fb*/)))
  19.                     {
  20.                             ecErrCode = SerialPort::COMM_SETMASK; //不能设置端口事件MASK
  21.                 LOG(ERROR)<<"SerialPort::Open->ecErrCode:不能设置端口事件MASK";
  22.                     }

  23.                     if((!ecErrCode) && (!_bFromHandle)) //如果已知句柄,不需要设置缓存
  24.                     {
  25.                             if(!SetupComm(_Handle, _HwInSize, _HwOutSize))
  26.                             {
  27.                                     ecErrCode = SerialPort::COMM_BUFSIZE; //不能设置端口缓存
  28.                     LOG(ERROR)<<"SerialPort::Open->ecErrCode:不能设置端口缓存";
  29.                             }
  30.                     }

  31.                     if(!ecErrCode)
  32.                     {
  33.                             if(!_bFromHandle)
  34.                             {
  35.                                     //设置预先设定的 DTR 和 RTS 值
  36.                                     if(_dcb.fDtrControl != DTR_CONTROL_HANDSHAKE)
  37.                                     {
  38.                                             _dcb.fDtrControl = DTR_CONTROL_DISABLE;
  39.                                     }
  40.                                     if((_dcb.fRtsControl != RTS_CONTROL_HANDSHAKE) && (_dcb.fRtsControl != RTS_CONTROL_TOGGLE))
  41.                                     {
  42.                                             _dcb.fRtsControl = RTS_CONTROL_DISABLE;
  43.                                     }

  44.                                     DCB dcb = _dcb; //设定串口参数
  45.                                     if(!SetCommState(_Handle, &dcb))
  46.                                     {
  47.                                             ecErrCode = SerialPort::COMM_SETSTATE; //不能设置端口参数
  48.                         LOG(ERROR)<<"SerialPort::Open->ecErrCode:不能设置端口参数";
  49.                                     }
  50.                             }
  51.                             else //如果已知句柄,不需要设置参数
  52.                             {
  53.                                     DCB dcb;
  54.                                     if(GetCommState(_Handle, &dcb))
  55.                                     {
  56.                                             dcb.fAbortOnError = false;
  57.                                             if(!SetCommState(_Handle, &dcb))
  58.                                             {
  59.                                                     ecErrCode = SerialPort::COMM_SETSTATE; //不能设置端口参数
  60.                             LOG(ERROR)<<"SerialPort::Open->ecErrCode:不能设置端口参数";
  61.                                             }
  62.                                     }
  63.                                     else
  64.                                     {
  65.                                             ecErrCode = SerialPort::COMM_GETSTATE; //不能得到端口参数
  66.                         LOG(ERROR)<<"SerialPort::Open->ecErrCode:不能得到端口参数";
  67.                                     }
  68.                             }
  69.                     }

  70.                     if(!ecErrCode)
  71.                     {
  72.                             memset(&_ReadOS, 0, sizeof(OVERLAPPED));
  73.                             _ReadOS.hEvent = CreateEvent(NULL,true,false,NULL);
  74.                             _hKillRead = CreateEvent(NULL,true,false,NULL);

  75.                             if((!_hKillRead) || (!_ReadOS.hEvent))
  76.                             {
  77.                                     ecErrCode = SerialPort::COMM_CRRDEVENT; //不能创建端口异步读事件
  78.                     LOG(ERROR)<<"SerialPort::Open->ecErrCode:不能创建端口异步读事件";
  79.                             }
  80.                     }

  81.                     if(!ecErrCode)
  82.                     {
  83.                             memset(&_WriteOS, 0, sizeof(OVERLAPPED));
  84.                             _WriteOS.hEvent = CreateEvent(NULL, true, false, NULL);
  85.                             _hSyncWrite = CreateEvent(NULL, true, false, NULL);
  86.                             _hKillWrite = CreateEvent(NULL, true, false, NULL);

  87.                             if((!_hKillWrite) || (!_hSyncWrite) || (!_WriteOS.hEvent))
  88.                             {
  89.                                     ecErrCode = SerialPort::COMM_CRWREVENT; //不能创建端口异步写事件
  90.                     LOG(ERROR)<<"SerialPort::Open->ecErrCode:不能创建端口异步写事件";
  91.                             }
  92.                     }

  93.                     if(!ecErrCode)
  94.                     {
  95.                             _RunReadThread = 1;
  96.                             if((_ReadThreadId=_beginthread(_ReadThread, 4096, this))==-1)
  97.                             {
  98.                                     _RunReadThread = 0;
  99.                                     ecErrCode = SerialPort::COMM_CRRDTHREAD; //不能创建端口读线程
  100.                     LOG(ERROR)<<"SerialPort::Open->ecErrCode:不能创建端口读线程";
  101.                             }
  102.                     }

  103.                     if(!ecErrCode)
  104.                     {
  105.                             _RunWriteThread = 1;
  106.                             if((_WriteThreadId=_beginthread(_WriteThread, 4096, this))==-1)
  107.                             {
  108.                                     _RunWriteThread = 0;
  109.                                     ecErrCode = SerialPort::COMM_CRWRTHREAD; //不能创建端口写线程
  110.                     LOG(ERROR)<<"SerialPort::Open->ecErrCode:不能创建端口写线程";
  111.                             }
  112.                     }

  113.                     if(!ecErrCode)
  114.                     {
  115.                             SetThreadPriority((HANDLE)_ReadThreadId,THREAD_PRIORITY_HIGHEST);
  116.                             //SetThreadPriority((HANDLE)_WriteThreadId,THREAD_PRIORITY_HIGHEST);

  117.                             _Opened = true;
  118.                             _DisableWrite = false;

  119.                             DWORD dwMs; //MS_CTS_ON | MS_DSR_ON | MS_RING_ON | MS_RLSD_ON
  120.                             if(GetCommModemStatus(_Handle, &dwMs)) //Get modem status after port opened
  121.                             _ModemStatus = dwMs;

  122.                 if(isFrameMode)
  123.                 {
  124.                     _isFrameMode = true;
  125.                     //init timer
  126.                     _hTimerEvent = CreateEvent(NULL, false, false, NULL); //Create Auto-Reset Event
  127.                     _hFrameReceivedEvent = CreateEvent(NULL, false, false, NULL); //Create Auto-Reset Event
  128.                     _hTimerThreadId = _beginthread(_fnTimerThread, 4096, this);
  129.                 }
  130.                 return true;
  131.                     }
  132.                     else
  133.                     {
  134.                             Close();
  135.                             //throw std::exception(_PortName.c_str(),ecErrCode);
  136.                 return false;
  137.                     }
  138.             }
  139.     }
复制代码



两种方式读线程:
  1. #ifdef READTHREAD_ON_EVENT
  2. ////////////////////////////////////////////////
  3.         /*
  4.          *
  5.          * 事件方式收取串口数据
  6.          *
  7.          * */
  8.         void SerialPort::_ReadThread(void *Param)
  9.         {
  10.                   SerialPort *Comm = (SerialPort *) Param;
  11.                   Comm->_ReadThreadRunning = 1;

  12.                   COMSTAT ComStat;
  13.                   const int RecvBufSize = 2048;
  14.                   char RecvBuf[RecvBufSize];
  15.                   DWORD dwErrorFlag, dwBytes, BytesToRead, BytesRemain;

  16.                   OVERLAPPED os;
  17.                   DWORD dwEvtMask, dwModemStatus;

  18.                   os.hEvent = CreateEvent(NULL, true, false, NULL);
  19.                   if(os.hEvent)
  20.                    {
  21.                          DWORD dwMask = EV_RXCHAR|EV_TXEMPTY|EV_ERR
  22.                                                                                    /*: EV_RXCHAR|EV_TXEMPTY|EV_CTS|EV_DSR|EV_RING|EV_RLSD|EV_RXFLAG|EV_RX80FULL|EV_ERR*/;
  23.                          if(SetCommMask(Comm->_Handle, dwMask))
  24.                           {
  25.                                 HANDLE StatusWaits[2] = {Comm->_hKillRead, os.hEvent};

  26.                                 while(Comm->_RunReadThread)
  27.                                  {
  28.                                    dwEvtMask = 0;
  29.                                    if(!WaitCommEvent(Comm->_Handle, &dwEvtMask, &os))
  30.                                         {
  31.                                           if(GetLastError() == ERROR_IO_PENDING)
  32.                                            {
  33.                                                  if(WaitForMultipleObjects(2, StatusWaits, false, INFINITE) == WAIT_OBJECT_0)
  34.                                                    break;
  35.                                            }
  36.                                         }

  37.                                    if(!Comm->_RunReadThread)
  38.                                          break;

  39.                                    if(dwEvtMask & EV_RXCHAR)
  40.                                         {
  41.                                           ClearCommError(Comm->_Handle, &dwErrorFlag, &ComStat);
  42.                                           BytesRemain = ComStat.cbInQue;

  43.                                           while(BytesRemain>0)
  44.                                            {
  45.                                                  BytesToRead = BytesRemain<RecvBufSize?BytesRemain:RecvBufSize;

  46.                                                  if(ReadFile(Comm->_Handle, RecvBuf, BytesToRead, &dwBytes, &Comm->_ReadOS))
  47.                                                   {
  48.                                                         Comm->_ReadBuffer->In(RecvBuf, dwBytes);
  49.                                                         BytesRemain-=dwBytes;
  50.                                                   }
  51.                                                  else
  52.                                                   {
  53.                                                         DWORD dwError = GetLastError();
  54.                                                         if(dwError==ERROR_IO_PENDING)
  55.                                                          {
  56.                                                            if(GetOverlappedResult(Comm->_Handle, &Comm->_ReadOS, &dwBytes, false))
  57.                                                                 {
  58.                                                                   Comm->_ReadBuffer->In(RecvBuf, dwBytes);
  59.                                                                   BytesRemain-=dwBytes;
  60.                                                                 }
  61.                                                          }
  62.                                                   }
  63.                                            }
  64.                                         }

  65.                                    if(dwEvtMask & EV_TXEMPTY)
  66.                                         {

  67.                                         }

  68.                                    if(dwEvtMask & EV_ERR)
  69.                                         {
  70.                                           ClearCommError(Comm->_Handle, &dwErrorFlag, &ComStat);
  71.                                         }

  72.                                  }
  73.                           }

  74.                          CloseHandle(os.hEvent);
  75.                    }

  76.                   Comm->_ReadThreadRunning = 0;
  77.         }
  78. #else
  79. ////////////////////////////////////////////////
  80.         /*
  81.          *
  82.          * 查询方式收取串口数据
  83.          *
  84.          * */
  85.     void SerialPort::_ReadThread(void *Param)
  86.     {
  87.         SerialPort *Comm = (SerialPort *) Param;
  88.             Comm->_ReadThreadRunning = 1;

  89.         const int RecvBufSize = 2048;
  90.             char RecvBuf[RecvBufSize];
  91.             DWORD   dwErrorFlag, dwBytes, BytesRemain, BytesToRead;
  92.         COMSTAT ComStat;

  93.         while(Comm->_RunReadThread)
  94.                 {
  95.                         if(!Comm->_RunReadThread)
  96.                                 break;
  97.             ClearCommError(Comm->_Handle, &dwErrorFlag, &ComStat);
  98.             BytesRemain = ComStat.cbInQue;
  99.             while(BytesRemain>0)
  100.             {
  101.                 BytesToRead = BytesRemain<RecvBufSize?BytesRemain:RecvBufSize;
  102.                             if(ReadFile(Comm->_Handle, RecvBuf, BytesToRead, &dwBytes, &Comm->_ReadOS))
  103.                             {
  104.                     Comm->_ReadBuffer->In(RecvBuf,dwBytes);
  105.                     BytesRemain-=dwBytes;
  106.                             }
  107.                 Sleep(0);
  108.             }
  109.             Sleep(10);
  110.                 }
  111.         Comm->_ReadThreadRunning = 0;
  112.     }
  113. #endif
复制代码



写线程:
  1. void SerialPort::_WriteThread(void *Param)
  2.     {
  3.         SerialPort *Comm = (SerialPort *) Param;
  4.             Comm->_WriteThreadRunning = 1;
  5.         const int SendBufSize = 512;
  6.             char SendBuf[SendBufSize];
  7.             DWORD BytesSent=0, BytesToSend=0;

  8.             COMSTAT ComStat;
  9.             DWORD dwErrorFlag, dwBytesWr;

  10.             DWORD dwSingled;
  11.             HANDLE MainWaits[2] = {Comm->_hKillWrite, Comm->_hSyncWrite};
  12.             HANDLE OvlWriteWaits[2] = {Comm->_hKillWrite, Comm->_WriteOS.hEvent};

  13.             while(Comm->_RunWriteThread)
  14.             {
  15.                     dwSingled = WaitForMultipleObjects(2, MainWaits, false, INFINITE);
  16.                     if((!Comm->_RunWriteThread) || (dwSingled==WAIT_OBJECT_0))
  17.                             break;
  18.                     ResetEvent(Comm->_hSyncWrite);

  19.                     if(BytesSent<BytesToSend)
  20.                     {
  21.                             if(WriteFile(Comm->_Handle, SendBuf+BytesSent, BytesToSend-BytesSent, &dwBytesWr, &Comm->_WriteOS))
  22.                             {
  23.                                     BytesSent+=dwBytesWr;
  24.                     //LOG(INFO)<<"SerialPort::_WriteThread->dwBytesWr:"<<dwBytesWr;
  25.                             }
  26.                             else if(GetLastError()==ERROR_IO_PENDING)
  27.                             {
  28.                                     dwSingled = WaitForMultipleObjects(2, OvlWriteWaits, false, INFINITE);
  29.                                     if((!Comm->_RunWriteThread) || (dwSingled==WAIT_OBJECT_0))
  30.                                             break;
  31.                                     if(GetOverlappedResult(Comm->_Handle, &Comm->_WriteOS, &dwBytesWr, false))
  32.                                             BytesSent+=dwBytesWr;
  33.                             }
  34.                             if(BytesSent<BytesToSend)
  35.                             {
  36.                                     SetEvent(Comm->_hSyncWrite);
  37.                             }
  38.                             Sleep(0);
  39.                     }
  40.             else if(Comm->_WriteBuffer->Count()>0)
  41.                     {
  42.                             BytesSent = 0;
  43.                             BytesToSend = Comm->_WriteBuffer->Out(SendBuf, SendBufSize);
  44.                             SetEvent(Comm->_hSyncWrite);
  45.                     }
  46.             }

  47.             Comm->_WriteThreadRunning = 0;
  48.     }
复制代码



帧读取:
  1. void SerialPort::_TimerThread(void)
  2.     {
  3.         DWORD dwWait;
  4.         const long BufSize = 20480;
  5.         char Buf[BufSize];
  6.         volatile long nRead;
  7.         //std::string sss;
  8.         //__try
  9.         {
  10.             _bTimerThreadRunning = true;
  11.             while(_bRunTimerThread)
  12.             {
  13.                 dwWait = (_Opened && _isFrameMode) ? _dwTimerInterval : INFINITE;
  14.                 WaitForSingleObject(_hTimerEvent,dwWait);

  15.                 if((_Opened&&_bRunTimerThread) && (_isFrameMode))
  16.                 {
  17.                     //如果这个_dwTimerInterval时间内没有收到数据,那就收超时,产生一个_OnFrameReceivedEventHandler事件
  18.                     nRead = Read(Buf,BufSize);
  19.                     if(nRead==0)
  20.                     {
  21.                         if(_isReading)
  22.                         {
  23.                             _FrameReceiveTimeOutCnt++;
  24.                             if(_FrameReceiveTimeOutCnt>5)//如果没读到数据超过5次,认为帧超时
  25.                             {
  26.                                 //LOG(INFO)<<"_TimerThread.SetEvent._FrameReceiveTimeOutCnt:"<<_FrameReceiveTimeOutCnt;
  27.                                 SetEvent(_hFrameReceivedEvent);
  28.                                 _FrameReceiveTimeOutCnt=0;
  29.                             }
  30.                         }
  31.                     }
  32.                     else if(nRead>0)//如果读到数据了,那就写到帧缓冲区中,并清掉超时计数器
  33.                     {
  34.                         _isReading = true;
  35.                         _ReadFrameBuffer->In(Buf,nRead);
  36.                         _FrameReceiveTimeOutCnt=0;
  37.                     }
  38.                 }
  39.             }
  40.         }
  41.         //__finally
  42.         {
  43.             _bTimerThreadRunning = false;
  44.         }
  45.     }
复制代码

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

阿莫论坛20周年了!感谢大家的支持与爱护!!

你熬了10碗粥,别人一桶水倒进去,淘走90碗,剩下10碗给你,你看似没亏,其实你那10碗已经没有之前的裹腹了,人家的一桶水换90碗,继续卖。说白了,通货膨胀就是,你的钱是挣来的,他的钱是印来的,掺和在一起,你的钱就贬值了。

出0入0汤圆

发表于 2014-9-16 10:04:23 | 显示全部楼层
本帖最后由 shh6899 于 2014-9-16 10:06 编辑

用ACCESSPORT+USB转串口,也会出现,应该是运行过程中句柄不存在,导致非法操作。

出0入0汤圆

 楼主| 发表于 2014-9-16 10:29:58 | 显示全部楼层
shh6899 发表于 2014-9-16 10:04
用ACCESSPORT+USB转串口,也会出现,应该是运行过程中句柄不存在,导致非法操作。
...

可以正常发送,一有返回数据就会蓝

出0入0汤圆

 楼主| 发表于 2014-9-16 10:34:15 | 显示全部楼层
有个情况是:如果先用串口调试软件打一一下串口就可以正常使用了,所以应该是初始化方面有问题
头像被屏蔽

出0入0汤圆

发表于 2014-9-16 10:46:23 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽

出0入0汤圆

 楼主| 发表于 2014-9-16 11:01:13 | 显示全部楼层
csaaa 发表于 2014-9-16 10:46
应该是接收线程中的出的问题。造成蓝屏的话一般都是对通道的读写操作出了问题,这个问题是底层出错,所以才 ...


你好:
通过测试
  1.         /*
  2.          *
  3.          * 查询方式收取串口数据
  4.          *
  5.          * */
  6.     void SerialPort::_ReadThread(void *Param)
  7.     {
  8.         SerialPort *Comm = (SerialPort *) Param;
  9.             Comm->_ReadThreadRunning = 1;

  10.         const int RecvBufSize = 2048;
  11.             char RecvBuf[RecvBufSize];
  12.             DWORD   dwErrorFlag, dwBytes, BytesRemain, BytesToRead;
  13.         COMSTAT ComStat;

  14.         while(Comm->_RunReadThread)
  15.                 {
  16.                         if(!Comm->_RunReadThread)
  17.                                 break;
  18.             ClearCommError(Comm->_Handle, &dwErrorFlag, &ComStat);
  19.             BytesRemain = ComStat.cbInQue;
  20.                         LOG(INFO)<<"BytesRemain:"<<BytesRemain;
  21.            /*while(BytesRemain>0)
  22.             {
  23.                 BytesToRead = BytesRemain<RecvBufSize?BytesRemain:RecvBufSize;
  24.                             if(ReadFile(Comm->_Handle, RecvBuf, BytesToRead, &dwBytes, &Comm->_ReadOS))
  25.                             {
  26.                     Comm->_ReadBuffer->In(RecvBuf,dwBytes);
  27.                     BytesRemain-=dwBytes;
  28.                             }
  29.                 Sleep(0);
  30.             }*/
  31.             Sleep(10);
  32.                 }
  33.         Comm->_ReadThreadRunning = 0;
  34.     }
复制代码

那段程序注掉没有蓝,里面只有ReadFile会有问题了,其它没有关键的东西
现在应该怎么调试呢,参数 Comm->_ReadOS的初始化为:
  1. if(!ecErrCode)
  2.                     {
  3.                             memset(&_ReadOS, 0, sizeof(OVERLAPPED));
  4.                             _ReadOS.hEvent = CreateEvent(NULL,true,false,NULL);
  5.                             _hKillRead = CreateEvent(NULL,true,false,NULL);

  6.                             if((!_hKillRead) || (!_ReadOS.hEvent))
  7.                             {
  8.                                     ecErrCode = SerialPort::COMM_CRRDEVENT; //不能创建端口异步读事件
  9.                     LOG(ERROR)<<"SerialPort::Open->ecErrCode:不能创建端口异步读事件";
  10.                             }
  11.                     }
复制代码
头像被屏蔽

出0入0汤圆

发表于 2014-9-16 11:16:39 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽

出0入0汤圆

 楼主| 发表于 2014-9-16 12:11:22 | 显示全部楼层
csaaa 发表于 2014-9-16 11:16
可能发生了读取异常,这个异常可能是USB设备本身不支持空数据造成的。
参考这个写法:
while (gPort != INV ...

你好:
读之前是判断了的,
现在测试结果是
  1. while(BytesRemain>0)
  2.             {
  3.                 BytesToRead = BytesRemain<RecvBufSize?BytesRemain:RecvBufSize;
  4.                             if(ReadFile(Comm->_Handle, RecvBuf, BytesToRead, &dwBytes, /*&Comm->_ReadOS*/NULL))
  5.                             {
  6.                     Comm->_ReadBuffer->In(RecvBuf,dwBytes);
  7.                     BytesRemain-=dwBytes;
  8.                                         LOG(INFO)<<"dwBytes:"<<dwBytes;
  9.                             }
  10.                                 else
  11.                                 {
  12.                                         LOG(INFO)<<"ReadFile Error:"<<GetLastError();
  13.                                         break;
  14.                                 }
  15.                 Sleep(0);
  16.             }
复制代码

把最后的参数换成NULL不蓝了,但收不到数据,并收到一个错误 代码为87,参数错误。
换成&Comm->_ReadOS就蓝屏

I0916 12:02:45.095777  5240 EMeterProtocol.cpp:301] EMeterProtocol::Port:COM8:2400
I0916 12:02:45.095777  5240 EMeterProtocol.cpp:302] EMeterProtocol::SendLen:11
I0916 12:02:45.095777  5240 EMeterProtocol.cpp:307] Buffer->Len:11        FE FE 68 06 01 01 00 00 01 8C 16
I0916 12:02:45.097776  5404 SerialPort.cpp:597] BytesRemain:0
I0916 12:02:45.107777  5404 SerialPort.cpp:597] BytesRemain:2
I0916 12:02:45.107777  5404 SerialPort.cpp:609] ReadFile Error:87
I0916 12:02:45.117777  5404 SerialPort.cpp:597] BytesRemain:5
I0916 12:02:45.117777  5404 SerialPort.cpp:609] ReadFile Error:87
I0916 12:02:45.127779  5404 SerialPort.cpp:597] BytesRemain:7
I0916 12:02:45.127779  5404 SerialPort.cpp:609] ReadFile Error:87

出0入0汤圆

 楼主| 发表于 2014-9-16 12:29:37 | 显示全部楼层
csaaa 发表于 2014-9-16 11:16
可能发生了读取异常,这个异常可能是USB设备本身不支持空数据造成的。
参考这个写法:
while (gPort != INV ...

下面是事件方式收:
把ReadFile(Comm->_Handle, RecvBuf, BytesToRead, &dwBytes, /*&Comm->_ReadOS*/NULL)
最后换成NULL 还是87错误,没有蓝屏。


  1.         /*
  2.          *
  3.          * 事件方式收取串口数据
  4.          *
  5.          * */
  6.         void SerialPort::_ReadThread(void *Param)
  7.         {
  8.                   SerialPort *Comm = (SerialPort *) Param;
  9.                   Comm->_ReadThreadRunning = 1;

  10.                   COMSTAT ComStat;
  11.                   const int RecvBufSize = 2048;
  12.                   char RecvBuf[RecvBufSize];
  13.                   DWORD dwErrorFlag, dwBytes, BytesToRead, BytesRemain;

  14.                   OVERLAPPED os;
  15.                   DWORD dwEvtMask, dwModemStatus;

  16.                   os.hEvent = CreateEvent(NULL, true, false, NULL);
  17.                   if(os.hEvent)
  18.                    {
  19.                          DWORD dwMask = EV_RXCHAR|EV_TXEMPTY|EV_ERR
  20.                                                                                    /*: EV_RXCHAR|EV_TXEMPTY|EV_CTS|EV_DSR|EV_RING|EV_RLSD|EV_RXFLAG|EV_RX80FULL|EV_ERR*/;
  21.                          if(SetCommMask(Comm->_Handle, dwMask))
  22.                           {
  23.                                 HANDLE StatusWaits[2] = {Comm->_hKillRead, os.hEvent};

  24.                                 while(Comm->_RunReadThread)
  25.                                  {
  26.                                    dwEvtMask = 0;
  27.                                    if(!WaitCommEvent(Comm->_Handle, &dwEvtMask, &os))
  28.                                         {
  29.                                           if(GetLastError() == ERROR_IO_PENDING)
  30.                                            {
  31.                                                  if(WaitForMultipleObjects(2, StatusWaits, false, INFINITE) == WAIT_OBJECT_0)
  32.                                                    break;
  33.                                            }
  34.                                         }

  35.                                    if(!Comm->_RunReadThread)
  36.                                          break;

  37.                                    if(dwEvtMask & EV_RXCHAR)
  38.                                         {
  39.                                           ClearCommError(Comm->_Handle, &dwErrorFlag, &ComStat);
  40.                                           BytesRemain = ComStat.cbInQue;
  41.                                           LOG(INFO)<<"BytesRemain:"<<BytesRemain;
  42.                                           while(BytesRemain>0)
  43.                                            {
  44.                                                  BytesToRead = BytesRemain<RecvBufSize?BytesRemain:RecvBufSize;

  45.                                                  if(ReadFile(Comm->_Handle, RecvBuf, BytesToRead, &dwBytes, /*&Comm->_ReadOS*/NULL))
  46.                                                   {
  47.                                                         Comm->_ReadBuffer->In(RecvBuf, dwBytes);
  48.                                                         BytesRemain-=dwBytes;
  49.                                                         LOG(INFO)<<"dwBytes:"<<dwBytes;
  50.                                                   }
  51.                                                  else
  52.                                                   {
  53.                                                         DWORD dwError = GetLastError();
  54.                                                         if(dwError==ERROR_IO_PENDING)
  55.                                                          {
  56.                                                            if(GetOverlappedResult(Comm->_Handle, &Comm->_ReadOS, &dwBytes, false))
  57.                                                                 {
  58.                                                                   Comm->_ReadBuffer->In(RecvBuf, dwBytes);
  59.                                                                   BytesRemain-=dwBytes;
  60.                                                                   LOG(INFO)<<"dwBytes:"<<dwBytes;
  61.                                                                 }
  62.                                                          }
  63.                                                         else
  64.                                                         {
  65.                                                                 LOG(INFO)<<"GetLastError:"<<dwError;
  66.                                                                 break;
  67.                                                         }
  68.                                                   }
  69.                                            }
  70.                                         }

  71.                                    if(dwEvtMask & EV_TXEMPTY)
  72.                                         {

  73.                                         }

  74.                                    if(dwEvtMask & EV_ERR)
  75.                                         {
  76.                                           ClearCommError(Comm->_Handle, &dwErrorFlag, &ComStat);
  77.                                         }

  78.                                  }
  79.                           }

  80.                          CloseHandle(os.hEvent);
  81.                    }

  82.                   Comm->_ReadThreadRunning = 0;
  83.         }
复制代码





I0916 12:25:12.381836  1452 EMeterProtocol.cpp:301] EMeterProtocol::Port:COM8:2400
I0916 12:25:12.381836  1452 EMeterProtocol.cpp:302] EMeterProtocol::SendLen:11
I0916 12:25:12.381836  1452 EMeterProtocol.cpp:307] Buffer->Len:11        FE FE 68 06 01 01 00 00 01 8C 16
I0916 12:25:12.385838  3200 SerialPort.cpp:531] BytesRemain:1
I0916 12:25:12.385838  3200 SerialPort.cpp:556] GetLastError:87
I0916 12:25:12.390837  3200 SerialPort.cpp:531] BytesRemain:2
I0916 12:25:12.390837  3200 SerialPort.cpp:556] GetLastError:87
I0916 12:25:12.394837  3200 SerialPort.cpp:531] BytesRemain:3
I0916 12:25:12.394837  3200 SerialPort.cpp:556] GetLastError:87
I0916 12:25:12.398838  3200 SerialPort.cpp:531] BytesRemain:4

出0入0汤圆

发表于 2014-9-16 12:43:00 来自手机 | 显示全部楼层
你是黑客的节奏呀,啥系统都蓝

出0入0汤圆

 楼主| 发表于 2014-9-16 12:48:39 | 显示全部楼层
刚才事件方式的参数换成&Comm->_ReadOS可以正常读写了
这段程序是前两天刚改出来的,还没来得急测试,因为怕蓝屏,所以就懒了,现在发现正常的
附完整程序

谢谢csaaa

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
头像被屏蔽

出0入0汤圆

发表于 2014-9-16 14:58:22 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽

出0入0汤圆

 楼主| 发表于 2014-9-16 15:30:41 | 显示全部楼层
csaaa 发表于 2014-9-16 14:58
嗯。恭喜解决问题。蓝屏都是底层的硬件级IO错误,一般的内存操作错误都不会蓝屏的。 ...

谢谢,可能是USB转串口的驱动写的不健壮。

出0入0汤圆

发表于 2014-9-20 19:27:22 | 显示全部楼层
pl2303有问题                  这个芯片水货很多

出0入0汤圆

 楼主| 发表于 2014-9-21 10:06:49 | 显示全部楼层
sj1125055001 发表于 2014-9-20 19:27
pl2303有问题                  这个芯片水货很多

程序修改后可以正常使用了

出0入0汤圆

发表于 2014-9-21 11:23:47 | 显示全部楼层
这个不错,很多项目会用到串口通讯,从底层做起可很灵活应用,学习了。
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-10-3 03:23

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表