如何用串口发送和接收文件?   
哪位能给个源程序?   
[email protected]
小弟是初学者,多谢各位了

解决方案 »

  1.   

    http://msdn.microsoft.com/library/default.asp?url=/library/en-us/comm98/html/vbobjComm.asp
      

  2.   

    HANDLE hCom;
    OVERLAPPED Write_OS, Read_OS, OS;//打开串口  
    int OpenComm(char *DeviceName)
    {
    hCom = CreateFile(DeviceName, GENERIC_READ | GENERIC_WRITE,0,NULL,OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL|FILE_FLAG_OVERLAPPED,NULL);          //创建串口,异步方式
    if (hCom == INVALID_HANDLE_VALUE)
    return -1;                    //打开串口失败
    else
    {
    SetCommMask( hCom, EV_RXCHAR|EV_TXEMPTY ); //设置串口事件
    SetupComm( hCom, 4096,4096);                            //设置读写缓冲区大小
    PurgeComm( hCom, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR );

    memset(&Write_OS,0,sizeof(OVERLAPPED));
    memset(&Read_OS,0,sizeof(OVERLAPPED));
    memset(&OS,0,sizeof(OVERLAPPED));

    COMMTIMEOUTS comTimeOut;                                //设置超时
    comTimeOut.ReadIntervalTimeout = MAXDWORD;
    comTimeOut.ReadTotalTimeoutMultiplier = 3000;
    comTimeOut.ReadTotalTimeoutConstant = 200;
    comTimeOut.WriteTotalTimeoutMultiplier = 300;
    comTimeOut.WriteTotalTimeoutConstant = 200;
    SetCommTimeouts(hCom,&comTimeOut);


    Read_OS.Internal = 0;
    Read_OS.InternalHigh = 0;
    Read_OS.Offset = 0;
    Read_OS.OffsetHigh = 0; //设置结构

    Write_OS.Internal = 0;
    Write_OS.InternalHigh = 0;
    Write_OS.Offset = 0;
    Write_OS.OffsetHigh = 0; //设置结构 Read_OS.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
    Write_OS.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);


    DCB dcb;
    GetCommState(hCom, &dcb );                               //串口设置
    dcb.BaudRate = 9600;
    dcb.ByteSize = 8; 
    dcb.Parity = NOPARITY;
    dcb.StopBits = ONESTOPBIT;
    dcb.fBinary = TRUE;
    dcb.fParity = FALSE;
    SetCommState( hCom, &dcb );


    return 0;
    }
    }例如:
    char comm[4]="COM1"; 
    OpenComm(comm);
    //关闭串口
    void CloseComm()
    {
    WaitForSingleObject(hReadThread, INFINITE);
    CloseHandle(hReadThread);
    CloseHandle(hCom);
    }//读取数据
    int ReadComm()
    {
    Read_OS = {0};
    DWORD dwRes;
    BYTE Buffer[255];
    DWORD dwDataRead; ResetEvent(Read_OS.hEvent);
    if ( NULL == Read_OS.hEvent) 
    return -1; if (ReadFile(hCom, Buffer, 3, NULL, &Read_OS)) 
    return 0; //成功读出
    else
    {
    dwRes = WaitForSingleObject(Read_OS.hEvent, 5000); //设置5秒超时
    switch(dwRes)
    {
    case WAIT_OBJECT_0:
    if (!GetOverlappedResult(hCom, &Read_OS, &dwDataRead, TRUE)) 
    {
    //操作失败,可用GetLastError()获取失败信息
    return 1;
    }
    else
    {
    //成功
    return 0;
    }
    break;
    case WAIT_TIMEOUT:
    //超时
    return 2;
    break;
    default:
    break;
    }
    } CloseHandle(Read_OS.hEvent);
    return 0;
    }
    //写数据
    int WriteComm()
    {
    Write_OS = {0};
    DWORD dwRes;
    BYTE Buffer[255];
    DWORD dwDataRead; ResetEvent(Write_OS.hEvent);
    if (NULL == Write_OS.hEvent) 
    return -1; if(WriteFile(hCom, Buffer, 3, NULL, &Write_OS))
    return 0; //成功
    else
    {
    dwRes = WaitForSingleObject(&Write_OS, 5000); //设置5秒超时
    switch(dwRes)
    {
    case WAIT_OBJECT_0:
    if (!GetOverlappedResult(hCom, &Write_OS, &dwDataRead, TRUE)) 
    {
    //操作失败,可用GetLastError()获取失败信息
    return 1;
    }
    else
    {
    //成功
    return 0;
    }
    break;
    case WAIT_TIMEOUT:
    //超时
    return 2;
    break;
    default:
    break;
    }
    } CloseHandle(Read_OS.hEvent);
    return 0;
    }
      

  3.   

    首先,在对话框中创建通信控件,若Control工具栏中缺少该控件,可通过菜单Project --> Add to Project --> Components and Control插入即可,再将该控件从工具箱中拉到对话框中。此时,你只需要关心控件提供的对 Windows 通讯驱动程序的 API 函数的接口。换句话说,只需要设置和监视MSComm控件的属性和事件。  打开所需串口后,需要考虑串口通信的时机。在接收或发送数据过程中,可能需要监视并响应一些事件和错误,所以事件驱动是处理串行端口交互作用的一种非常有效的方法。使用 OnComm 事件和 CommEvent 属性捕捉并检查通讯事件和错误的值。发生通讯事件或错误时,将触发 OnComm 事件,CommEvent 属性的值将被改变,应用程序检查 CommEvent 属性值并作出相应的反应// 若是在SDI中使用该控件则要调用下两句,在对话框程序中该语句有MFC自己创建
    // 所以不用人为添加DWORD style=WS_VISIBLE;
    m_MSComm.Create(NULL,style,CRect(0,0,0,0),this,IDC_MSCOMM1);// 串口控件的初始化DWORD style=WS_VISIBLE;
    m_MSComm.Create(NULL,style,CRect(0,0,0,0),this,IDC_MSCOMM1);
    if(m_MSComm.GetPortOpen()) //如果串口是打开的,则行关闭串口
    {
     m_MSComm.SetPortOpen(FALSE);
    }m_MSComm.SetCommPort(1); //选择COM1
    m_MSComm.SetInBufferSize(1024); //接收缓冲区
    m_MSComm.SetOutBufferSize(1024);//发送缓冲区
    m_MSComm.SetInputLen(0);//设置当前接收区数据长度为0,表示全部读取
    m_MSComm.SetInputMode(1);//以二进制方式读写数据
    m_MSComm.SetRThreshold(1);//接收缓冲区有1个及1个以上字符时,将引发接收数据的OnComm事件
    m_MSComm.SetSettings("9600,n,8,1");//波特率9600无检验位,8个数据位,1个停止位if(!m_MSComm.GetPortOpen())//如果串口没有打开则打开
     m_MSComm.SetPortOpen(TRUE);//打开串口
    else
     m_MSComm.SetOutBufferCount(0);// 控件事件的响应声明
    // *.h
    //{{AFX_MSG(CGolfView)afx_msg BOOL OnComm();
    DECLARE_EVENTSINK_MAP()
    //}}AFX_MSG// *.cppBEGIN_EVENTSINK_MAP(CGolfView, CView)
    //{{AFX_EVENTSINK_MAP(CAboutDlg)
    ON_EVENT(CGolfView, IDC_MSCOMM1, 1 /* OnComm */, OnComm, VTS_NONE)
    //}}AFX_EVENTSINK_MAP
    END_EVENTSINK_MAP()// 控件事件的响应
    BOOL CGolfView::OnComm()
    {
     VARIANT variant_inp;
     COleSafeArray safearray_inp;
     LONG len,k;
     BYTE rxdata[2048]; //设置BYTE数组 An 8-bit integerthat is not signed.
     CString strtemp;
     switch(m_MSComm.GetCommEvent())
     {
      case 1: // comEvSend发送数据
       break;
      case 2: // comEvReceive读取数据
       // MessageBox(_T("读取数据事件"), _T("TRACE"), MB_OK);
       variant_inp=m_MSComm.GetInput(); //读缓冲区
       safearray_inp=variant_inp; //VARIANT型变量转换为ColeSafeArray型变量
       len=safearray_inp.GetOneDimSize(); //得到有效数据长度
       // 接受数据
       for(k=0; k<len; k++)
       {
        safearray_inp.GetElement(&k,rxdata+k); //转换为BYTE型数组
        BYTE bt=*(char*)(rxdata+k); //字符型
        strtemp.Format("%c",bt); //将字符送入临时变量strtemp存放
        recd+=strtemp;
       }   // UpdateData(TRUE);
     
       break;
      default: // 传输事件出错
       m_MSComm.SetOutBufferCount(0);
       break;
      }
     UpdateData(FALSE); //更新图象内容
     return TRUE;
    }
      

  4.   

    谢谢楼上的兄弟,小弟想知道,
    如果接收文件的话,用户需要选择文件存放路径的话应该怎么写呢?
    另外下面的代码请各位帮忙。。
    if(buf[0]=='0')   //判断如果一帧数据第一字符是'0'的话就接收此文件
    {  
       //程序调到下一句的时候点确定会死掉大侠救命啊     
       if (AfxMessageBox("要接收文件吗?",NULL,MB_ICONWARNING|MB_OKCANCEL)==IDOK)
       {
           CFile cf;
           //BOOL fWriteState;
           DWORD dwBytesRead;
           DWORD dwCharToRead;
       
           dwCharToRead=0;
           dwCharToRead=(DWORD)cf.GetLength();
           cf.Seek(0,CFile::begin);
           dwBytesRead=0;
       
           if(m_pSerial->m_hComm!=INVALID_HANDLE_VALUE&&dwCharToRead!=0)
           {
    char* buf=new char[dwCharToRead];
    cf.Read(buf,dwCharToRead);
    if(!fReadState)
    {
      //AfxMessageBox(_T("无法向端口写入数据!"));
              }
    delete[] buf;
       }
    cf.Close();
    return dwBytesRead;
    continue; 
         // return;
      }
    }
    else
            { 

             }