本帖最后由 VisualEleven 于 2012-12-19 13:19:22 编辑

解决方案 »

  1.   

    推荐用串口API
    别人的库用起来爽,出问题了。
    你就知道惨了。
      

  2.   

    好吧,串口API,还没搞到这种程度用第三方的库函数是不爽,这个函数sio_close(Port)内部到底做了什么导致程序崩溃,我郁闷但是MOXA公司做的类库我又不相信会水到这种程度,100Hz又不算高。
      

  3.   

    调试时候发现,不是sio_close(Port)函数的问题,而是在OnBtnPortopen()函数执行完后进行后续处理的时候才出现Unhandled exception ...... Access Violation. 这应该可以说明不是库函数的问题吧。
      

  4.   


    // .h
    typedef void (WINAPI *ZY_RECV_COMDATA)(void* pParam, BYTE *data, int dataLen);
    class CMyCom
    {
    public:
    CMyCom(void);
    ~CMyCom(void);
    public:
    BOOL Open(int nComID, void* pMainWnd, ZY_RECV_COMDATA pFun, DWORD nRate = 9600);
    void Close();
    void Send(BYTE *pBuf, int nLen);
    BOOL IsOpen();
    HANDLE m_hCom;
    ZY_RECV_COMDATA m_CallBackFun;
    void* m_pMainWnd;
    };//.cpp
    CMyCom::CMyCom()
    {
    m_hCom = NULL;
    m_pMainWnd = NULL;
    }CMyCom::~CMyCom()
    {
    }DWORD WINAPI ThreadReciveData(LPVOID lpParameter)
    {
    CMyCom* pMyCom = (CMyCom*)lpParameter;
    HANDLE hCom = pMyCom->m_hCom; BYTE data[512];
    DWORD wCount; 
    while(1)
    {
    if(!ReadFile(hCom, data, 512, &wCount, NULL))
    {
    pMyCom->m_hCom = NULL;
    break;
    } if(wCount > 0)
    {
    pMyCom->m_CallBackFun(pMyCom->m_pMainWnd, data, wCount);
    }
    Sleep(1);
    }
    return 1;
    }BOOL CMyCom::Open(int nComID, void* pMainWnd, ZY_RECV_COMDATA pFun, DWORD nRate)
    {
    if(m_hCom) return FALSE; WCHAR szCOMID[32];
    wsprintfW(szCOMID, L"COM%d", nComID); m_hCom = CreateFileW(
    szCOMID, // 串口号
    GENERIC_READ | GENERIC_WRITE, // 允许读写
    0, // 因为串行口不支持任何共享模式, 必须以独占方式打开
    NULL, // 定义安全属性,一般不用,可设为NULL
    OPEN_EXISTING, // 定义文件创建方式, 对串口必须设为OPEN_EXISTING,表示打开已经存在的文件;
    NULL/*FILE_FLAG_OVERLAPPED*/, // 为该文件指定定义文件属性和标志,这个程序中设为FILE_FLAG_OVERLAPPED,表示异步通信方式异步I/O
    NULL); // 指向一个模板文件的句柄,串口无模板可言,设为NULL if (m_hCom == INVALID_HANDLE_VALUE)
    {
    Close();
    return FALSE;
    } DCB dcb;
    if(!GetCommState(m_hCom, &dcb))
    {
    AfxMessageBox(L"获得串口信息失败!");
    return FALSE;
    } // 9600,N,8,1
    dcb.BaudRate = nRate; // 波特率9600
    dcb.fParity = 0; // 0=无校验 1=开启校验
    dcb.Parity = NOPARITY; // 校验方式,值0~4分别对应无校验、奇校验、偶校验、校验置位、校验清零
    dcb.ByteSize = 8; // 一个字节的数据位个数
    dcb.StopBits = ONESTOPBIT; // 0=1位 1=1.5位 2=2位
    dcb.fBinary = 1; // 以二进制方式来处理串口 if(!SetCommState(m_hCom, &dcb))
    {
    AfxMessageBox(L"设置串口信息失败!");
    return FALSE;
    } if(!SetupComm(m_hCom, 1024, 1024)) //输入输出缓冲区
    {
    AfxMessageBox(L"设置串口缓冲区长度失败");
    return FALSE;
    } COMMTIMEOUTS CommTimeouts; CommTimeouts.ReadIntervalTimeout = MAXDWORD;        /* Maximum time between read chars. */
    CommTimeouts.ReadTotalTimeoutMultiplier = 0; // 以毫秒为单位指定一个乘数,该乘数用来计算读操作的总限时时间。每个读操作的总限时时间等于读操作所需的字节数与该值的乘积。
    CommTimeouts.ReadTotalTimeoutConstant = 0; // 以毫秒为单位指定一个常数,用于计算读操作的总限时时间。每个操作的总限时时间等于
    CommTimeouts.WriteTotalTimeoutMultiplier = 50; // 同上
    CommTimeouts.WriteTotalTimeoutConstant = 2000; // 同上
    if(!SetCommTimeouts(m_hCom, &CommTimeouts))
    {
    AfxMessageBox(L"串口超时设置失败~");
    return FALSE;
    } PurgeComm(m_hCom, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR); m_pMainWnd = pMainWnd;
    m_CallBackFun = pFun; CloseHandle(CreateThread(NULL, 0, ThreadReciveData, LPVOID(this), 0, NULL));
    return TRUE;
    }void CMyCom::Close()
    {
    CloseHandle(m_hCom);
    m_hCom = NULL;
    }void CMyCom::Send(BYTE *pBuf, int nLen)
    {
    if(m_hCom)
    {
    DWORD wCount = 0;
    WriteFile(m_hCom, pBuf, nLen, &wCount, NULL);
    }
    }BOOL CMyCom::IsOpen()
    {
    return m_hCom != NULL;
    }// 使用
    // 窗体函数
    void CMianDlg::OnCommXX(BYTE *data, int dataLen)
    {
    }
    //回调函数
    void WINAPI OnComRecvData(void* pParam, BYTE *data, int dataLen)
    {
    CMianDlg *pDlg = (CMianDlg*)pParam;
    pDlg->OnCommMscommXX(data, dataLen);
    }
    m_Com.Open(1, this/*接收窗体指针*/, OnComRecvData, 9600);
    我以前写的,不一定规范,你可以试下
      

  5.   

    测试的时候用IsOpen()这个函数判断串口状态
    另外usb转串的时候可能会有意外发生,测试的时候最好不要用usb转串,程序完成后再使用usb转串,分别测一次,有利于定位错误
      

  6.   

    谢谢各位,在关串口之前,对可能产生的隐患进行了排除,已经解决了,谢谢各位!
    PS:MOXA公司开发的串口库PCOMM还是非常好用的,使用非常方便,推荐一下哦。