症状:1,不插串口也可以打开串口,参数设置:m_pSerial->OpenPort(this,1,9600,NOPARITY,8,ONESTOPBIT)2,我设置了超时的,但在写串口的时候,程序执行到WriteFile就死掉了,没有响应了。

解决方案 »

  1.   

    打开串口的方法:
    BOOL CCESeries::OpenPort(void * pOwner,
     UINT portNo , /*串口号*/
     UINT baud , /*波特率*/
     UINT parity , /*奇偶校验*/
     UINT databits , /*数据位*/
     UINT stopbits    /*停止位*/
     )
    {
    DCB commParam;
    TCHAR szPort[15]; ASSERT(pOwner!=NULL);
    m_pOwner = pOwner;

    // 已经打开的话,直接返回
    if (m_hComm != INVALID_HANDLE_VALUE)
    {
    return TRUE;
    }

    //设置串口名
    wsprintf(szPort, L"COM%d:", portNo);
    //打开串口
    m_hComm = CreateFile(
    szPort,
    GENERIC_READ | GENERIC_WRITE, //允许读和写
    0, //独占方式(共享模式)
    NULL,
    OPEN_EXISTING, //打开而不是创建(创建方式)
    0,
    NULL 
    );

    if (m_hComm == INVALID_HANDLE_VALUE)
    {
    // 无效句柄,返回。
    TRACE(_T("CreateFile 返回无效句柄\n"));
    return FALSE;

    }

    // 得到打开串口的当前属性参数,修改后再重新设置串口。
    if (!GetCommState(m_hComm,&commParam))
    {
    //关闭串口
    CloseHandle (m_hComm);
    m_hComm = INVALID_HANDLE_VALUE;
    return FALSE;
    }

    //设置串口参数
    commParam.BaudRate = baud; // 设置波特率 
    commParam.fBinary = TRUE; // 设置二进制模式,此处必须设置TRUE
    commParam.fParity = TRUE; // 支持奇偶校验 
    commParam.ByteSize = databits; // 数据位,范围:4-8 
    commParam.Parity = parity; // 校验模式
    commParam.StopBits = stopbits; // 停止位 

    commParam.fOutxCtsFlow = FALSE; // No CTS output flow control 
    commParam.fOutxDsrFlow = FALSE; // No DSR output flow control 
    commParam.fDtrControl = DTR_CONTROL_ENABLE; 
    // DTR flow control type 
    commParam.fDsrSensitivity = FALSE; // DSR sensitivity 
    commParam.fTXContinueOnXoff = TRUE; // XOFF continues Tx 
    commParam.fOutX = FALSE; // No XON/XOFF out flow control 
    commParam.fInX = FALSE; // No XON/XOFF in flow control 
    commParam.fErrorChar = FALSE; // Disable error replacement 
    commParam.fNull = FALSE; // Disable null stripping 
    commParam.fRtsControl = RTS_CONTROL_ENABLE; 
    // RTS flow control 
    commParam.fAbortOnError = FALSE; // 当串口发生错误,并不终止串口读写

    //设置串口参数
    if (!SetCommState(m_hComm, &commParam))
    {
    TRACE(_T("SetCommState error"));
    //关闭串口
    CloseHandle (m_hComm);
    m_hComm = INVALID_HANDLE_VALUE;
    return FALSE;
    }

        //设置串口读写时间
    COMMTIMEOUTS CommTimeOuts;
    GetCommTimeouts (m_hComm, &CommTimeOuts);
    CommTimeOuts.ReadIntervalTimeout = MAXDWORD;  
    CommTimeOuts.ReadTotalTimeoutMultiplier = 0;  
    CommTimeOuts.ReadTotalTimeoutConstant = 0;    
    CommTimeOuts.WriteTotalTimeoutMultiplier = 10;  
    CommTimeOuts.WriteTotalTimeoutConstant = 1000;  
    if(!SetCommTimeouts( m_hComm, &CommTimeOuts ))
    {
    TRACE( _T("SetCommTimeouts 返回错误") );
    //关闭串口
    CloseHandle (m_hComm); m_hComm = INVALID_HANDLE_VALUE;
    return FALSE;
    }

    //指定端口监测的事件集
    SetCommMask (m_hComm, EV_RXCHAR);
    //分配串口设备缓冲区
    SetupComm(m_hComm,512,512);
    //初始化缓冲区中的信息
    PurgeComm(m_hComm,PURGE_TXCLEAR|PURGE_RXCLEAR);

    CString strEvent;
    strEvent.Format(L"Com_ReadCloseEvent%d",portNo);
    m_hReadCloseEvent = CreateEvent(NULL,TRUE,FALSE,strEvent); //创建串口读数据监听线程
    m_hReadThread = CreateThread(NULL,0,ReadThreadFunc,this,0,&m_dwReadThreadID);

    TRACE(_T("串口打开成功"));
    m_bOpened = TRUE;
    return TRUE;
    }
      

  2.   

    写串口的方法:
    BOOL CCESeries::WriteSyncPort(const BYTE*buf , DWORD bufLen)
    {
    DWORD dwNumBytesWritten;
    DWORD dwHaveNumWritten =0 ; //已经写入多少

    int iInc = 0; //如果3次写入不成功,返回FALSE
    ASSERT(m_hComm != INVALID_HANDLE_VALUE);
    do
    {
    if (WriteFile (m_hComm, //串口句柄 
    buf+dwHaveNumWritten, //被写数据缓冲区的首地址 
    bufLen - dwHaveNumWritten,          //被写数据缓冲区大小
    &dwNumBytesWritten, //函数执行成功后,返回实际向串口写的个数
    NULL)) //此处必须设置NULL
    {
    dwHaveNumWritten = dwHaveNumWritten + dwNumBytesWritten;
    //写入完成
    if (dwHaveNumWritten == bufLen)
    {
    break;
    }
    iInc++;
    if (iInc >= 3)
    {
    return FALSE;
    }
    Sleep(10);
    }
    else
    {
    return FALSE;
    }
    }while (TRUE);

    return TRUE;
    }
      

  3.   

    串口没插东西的时候,OpenPort这个函数也可以运行成功的。
    然后不管接不接串口,都在写串口,WriteFile的时候,死掉,然后程序无响应。
      

  4.   

    #include "afxwin.h"
    HANDLE m_hDev;
    char m_errMsg[200];
    //连接串口
    void ConnectOperation(const char* commPort, DWORD bandRate, BYTE byteSize, BYTE parity, BYTE stopBits)
    {
    m_hDev = CreateFile(commPort,
    GENERIC_READ | GENERIC_WRITE,
    0,    // comm devices must be opened w/exclusive-access
    NULL, // no security attributes
    OPEN_EXISTING, // comm devices must use OPEN_EXISTING
    0,    // not overlapped I/O
    NULL  // hTemplate must be NULL for comm devices
    );
    if (m_hDev == INVALID_HANDLE_VALUE) {
    sprintf(m_errMsg,"打开串口设备错误 -> %d.\n\n", GetLastError());
    ::MessageBox(NULL,m_errMsg,"提示",0);
    return;
        }

    DCB dcb;
    BOOL fSuccess;
    //获取串口设备状态信息
    fSuccess = GetCommState(m_hDev, &dcb);
    if (!fSuccess) {
    sprintf(m_errMsg,"获取设备状态信息失败 -> %d.\n\n", GetLastError());
    ::MessageBox(NULL,m_errMsg,"提示",0);
    return;
        }
        
    //[Default] Fill in the DCB: baud=9,600 bps, 8 data bits, no parity, and 1 stop bit.
    dcb.BaudRate = bandRate; // set the baud rate
    dcb.ByteSize = byteSize; // data size, xmit, and rcv
    dcb.Parity = parity; // no parity bit 0
    dcb.StopBits = stopBits; // one stop bit 0
    //设置串口设备状态
    fSuccess = SetCommState(m_hDev, &dcb);
    if (!fSuccess) {
    sprintf(m_errMsg,"设置设备状态信息失败 -> %d.\n\n", GetLastError());
    ::MessageBox(NULL,m_errMsg,"提示",0);
    return;
    }

    COMMTIMEOUTS comTimeOut;
    comTimeOut.ReadIntervalTimeout = 1;//接收时,两字符间最大的时延
    comTimeOut.ReadTotalTimeoutMultiplier = 1;//读取每字节的超时
    comTimeOut.ReadTotalTimeoutConstant = 1;//读串口数据的固定超时
    comTimeOut.WriteTotalTimeoutMultiplier = 1;//写每字节的超时
    comTimeOut.WriteTotalTimeoutConstant = 1;//写串口数据的固定超时
    //设备串口设备超时时限
    fSuccess = SetCommTimeouts(m_hDev,&comTimeOut);
    if (!fSuccess) {
    sprintf(m_errMsg,"设置设备读写超时延迟失败 -> %d.\n\n", GetLastError());
    ::MessageBox(NULL,m_errMsg,"提示",0);
    return;
    }

    //设备串口设备读写缓冲区大小,单位字节
    fSuccess = SetupComm(m_hDev,640,640);
    if (!fSuccess) {
    sprintf(m_errMsg,"设置设备读写缓冲区失败 -> %d.\n\n", GetLastError());
    ::MessageBox(NULL,m_errMsg,"提示",0);
    return;
    }
    }
    //写入数据
    void WriteDataToPort(const char *data)//不要超过缓冲区大小
    {
    DWORD recvLen;
    if (!::WriteFile(m_hDev,data,strlen(data),&recvLen,NULL))
    {
    ::MessageBox(NULL,"写入数据到串口设备失败","提示",0);
    }
    }
    //读取数据
    void ReadDataFromPort()
    {
    char recvMsg[640];
    memset(recvMsg,0,sizeof(recvMsg));
    DWORD recvLen;
    if (!::ReadFile(m_hDev,recvMsg,640,&recvLen,NULL))
    {
    ::MessageBox(NULL,"从串口设备读取数据失败","提示",0);
    }
    }
      

  5.   


    这里面使用OpenPort时不知怎么设为偶校验