遇到一个难题,请教高手指导一二。就是用多线程开发一个串行通讯程序。主要就是从串口收发数据,不知道是不是应该使用异步方式、还是同步方式,使用查询方式,还是用自动信号方式或自动中断方式处理数据。希望高手提示一下流程,要用到那些知识,要是能详细的说明开发流程,本人感激不尽!!!!

解决方案 »

  1.   

    如果是一问一答(命令方式)方式,用同步就可以了。writefile()完之后readfile()就可以了
      

  2.   

    是,我忘了你要同时操作多路串口了,给你一个我程序的一部分吧,是一个线成的代码,包括了异步打开串口等。打开操作已经被封装,但是流程比较清晰
    DWORD WINAPI ThreadCommProc( LPVOID lpParameter)
    {
     CDeviceDlg *pParentWnd;
     BYTE gtitem[]={0x01},buscode[9],buf[300];
     char CommPort[20]={"\\\\.\\"},mp[50];
         int redo,status,ret,iwait,iGTdivice, retvalue;
         unsigned short elapsed_time;
     struct _timeb  start, finish;
         double  timediff;
     // 8-7
     CRecord m_record;
     
     pParentWnd=(CDeviceDlg *) lpParameter;
     
     //打开串口
         strcpy(CommPort,"\\\\.\\");
     strcat(CommPort,pParentWnd->CommPort);
         if (pParentWnd->m_comm.open(CommPort,115200,1)!=1){
    SetEvent(pParentWnd->ExitedEvent);
    AfxMessageBox("不能打开串口",MB_OK);
            return 0;
         }
         
     //设置字符事件
     pParentWnd->m_comm.SetEventChar(0x02);
     //清串口
     pParentWnd->m_comm.PurgeIn();
     status=0;
     iwait=0;
     iGTdivice = 0;
     while(WaitForSingleObject(pParentWnd->ExitEvent,0)==WAIT_TIMEOUT)
     {   
     // 屏蔽在与采集盒通讯前与采集器的握手   // 2002-2-1
    /*
     if (status==0)
     {
     if (!initdevice(pParentWnd)) {
     if (iwait==0) { 
     pParentWnd->PostMessage(WM_APP_ERRORMSG,1,(LPARAM)"  等待与采集器通讯...");
     }
     continue;
     }
     pParentWnd->PostMessage(WM_APP_SIGNAL,1,2);
     status=1;
     iwait=1;
     }
    */
     //置RTS-发送请求线为低
     memset(buf, 0, 300); // 清缓冲区 2002-7-22  pParentWnd->m_comm.SetRTS(0);
     pParentWnd->PostMessage(WM_APP_SIGNAL,1,0);
     if (iwait == 0)
     {
     pParentWnd->PostMessage(WM_APP_ERRORMSG,1,(LPARAM)"  等待与采集盒通讯...(请检查采集盒是否上电或串口是否连接)");
     iwait = 1;
     }
             
     if (!ReceiveHandshake(pParentWnd))  continue;
     _ftime( &start);
             
     pParentWnd->m_time.SetWindowText("");
     pParentWnd->PostMessage(WM_APP_ERRORMSG,0,0);
     //点采集器灯   // 2002-2-1
     if (iGTdivice == 0)
     {
     pParentWnd->PostMessage(WM_APP_SIGNAL,1,2);
     iGTdivice = 1;
     }
     //点采集灯
     pParentWnd->PostMessage(WM_APP_SIGNAL,2,2);
             //发启动采集命令
     redo=0;

     /*----------通讯问题主要发生在发送启动采集命令和接收应答---------*/
     SendStartGTCmd(pParentWnd,1,gtitem);
     Sleep(5);
     do{
     ret=ReceiveGTStatusInfo(buf,pParentWnd);
     
     if (ret==2)
     break;
     if (ret==0)
     SendSynHead(pParentWnd);
     // 判断采集盒是否为空 2002-7-19  if (ret==-1) {
     SendNak(pParentWnd);
     break;
     }
     }while ((ret!=1)&&(redo++<3));
     /*----------- 2002-7-22------------*/  if (ret!=1) {
     //灭采集灯
         pParentWnd->PostMessage(WM_APP_SIGNAL,2,1);
     if (ret==2) {
     pParentWnd->PostMessage(WM_APP_ERRORMSG,1,(LPARAM)"  采集盒内没有文件!");
     continue;
     } else {
     pParentWnd->PostMessage(WM_APP_ERRORMSG,1,(LPARAM)"  与采集盒通讯发生错误,请拔出采集盒重试!");
     continue;
     }
     }  if (buf[2]!=0x01) {
     //灭采集灯
         pParentWnd->PostMessage(WM_APP_SIGNAL,2,1);
     pParentWnd->PostMessage(WM_APP_ERRORMSG,1,(LPARAM)"  采集盒状态不正确,不能采集数据");
     continue;
     }  SendAck(pParentWnd);  // 2002-7-17
             //pParentWnd->PostMessage(WM_APP_ITEMNUM,(WPARAM)buf[3],0);
                 
     //接收数据
     memset(buscode,0,9);
     
     retvalue = ReceiveGtData(buscode,pParentWnd);
             if (retvalue == 1)
     {
     _ftime( &finish);
     if (finish.millitm>=start.millitm)
     {
     timediff=difftime(finish.time,start.time);
     elapsed_time=finish.millitm-start.millitm;
     }
     else
     {
     timediff=difftime(finish.time-1,start.time);
     elapsed_time=finish.millitm-start.millitm+1000;
     }
     sprintf(mp,"%6.0f.%d秒",timediff,elapsed_time);
     pParentWnd->m_time.SetWindowText(mp);
     pParentWnd->PostMessage(WM_APP_ERRORMSG,0,NULL);
     }
     else
     {
     if (retvalue == 10)
     {
     pParentWnd->PostMessage(WM_APP_SIGNAL,2,1);
     pParentWnd->PostMessage(WM_APP_ERRORMSG,1,(LPARAM)"  采集盒内数据不完整!");
     continue;
     }
     else
     {
     pParentWnd->PostMessage(WM_APP_SIGNAL,2,1);
     pParentWnd->PostMessage(WM_APP_SETPRGPOS,0,0);
     pParentWnd->PostMessage(WM_APP_ERRORMSG,1,(LPARAM)"  采集时发生错误,请重采!");
     // 8-7
     m_record.DeleteErrFile();
     continue;
     }
     }
     //灭采集灯
     pParentWnd->PostMessage(WM_APP_SIGNAL,2,1);
     pParentWnd->PostMessage(WM_APP_SETPRGPOS,0,0);
     pParentWnd->PostMessage(WM_APP_ERRORMSG,1,(LPARAM)"  数据成功采集!");
     }  pParentWnd->m_comm.Purge();
         pParentWnd->m_comm.Close();
         SetEvent(pParentWnd->ExitedEvent);  return 0;
    }