为什么我的串口读线程会导致程序直接退出? 在线等,

dzkuchun   2007-12-30 08:07 楼主
/************************************************************************/
/* 串口接收回调函数                                                     */
/************************************************************************/
//CString m_strRecv ;

void CMFCWinCEDlg::OnSeriesRead(CWnd* pWnd,BYTE* buf,int bufLen)
{
        //SerialPort com = new SerialPort("COM1");

        CMFCWinCEDlg *pDlg = (CMFCWinCEDlg *)pWnd;
        pDlg->UpdateData(TRUE);

        for(int i=0;i             pDlg->m_strRecv.Format(L"%s %c",pDlg->m_strRecv,buf);

        pDlg->UpdateData(FALSE);
        delete[] buf;
}


//串口读线程函数
DWORD CCESeries::ReadThreadFunc(LPVOID lparam)
{
        CCESeries *ceSeries = (CCESeries*)lparam;
        //AfxMessageBox(L"Start read thread...");
        DWORD        evtMask;
        BYTE * readBuf = NULL;//读取的字节
        //char * readBuf = NULL;
        DWORD actualReadLen=0;//实际读取的字节数
        DWORD willReadLen;
       
        DWORD dwReadErrors;
        COMSTAT        cmState;
        TCHAR szBuf[200];
       
        //AfxMessageBox(L"Read Thread Func.");
        // 清空缓冲,并检查串口是否打开。
        //ASSERT(ceSeries->m_hComm !=INVALID_HANDLE_VALUE);
       
       
        //清空串口
        PurgeComm(ceSeries->m_hComm, PURGE_RXCLEAR | PURGE_TXCLEAR );
       
        SetCommMask(ceSeries->m_hComm, EV_RXCHAR | EV_CTS | EV_DSR );
        while (ceSeries->m_hComm !=INVALID_HANDLE_VALUE)//(TRUE)
        {          
                if (WaitCommEvent(ceSeries->m_hComm,&evtMask,0))
                {                       
                        SetCommMask (ceSeries->m_hComm, EV_RXCHAR | EV_CTS | EV_DSR );
                        //表示串口收到字符               
                        if (evtMask & EV_RXCHAR)
                        {
                               
                                ClearCommError(ceSeries->m_hComm,&dwReadErrors,&cmState);
                                willReadLen = cmState.cbInQue;
                                if (willReadLen <= 0)
                                {
                                        continue;
                                }
                               
                                readBuf = new BYTE[willReadLen+1];                               
                                ReadFile(ceSeries->m_hComm, readBuf, willReadLen, &actualReadLen,0);
                               
                                //如果读取的数据大于0,
                                if (actualReadLen>0)
                                {
                                //        wsprintf(szBuf, TEXT("Length: %ld\r\n"), willReadLen);
                                //        OutputDebugString(szBuf);
                                        //触发读取回调函数
//                                        AfxMessageBox(L"Onseriesread!");
                                        ceSeries->m_OnSeriesRead(ceSeries->m_pPortOwner,readBuf,actualReadLen);
                                }
                        }
                }
                //如果收到读线程退出信号,则退出线程
                if (WaitForSingleObject(ceSeries->m_hReadCloseEvent,500) == WAIT_OBJECT_0)
                {
                        break;
                }
        }
        return 0;
}


希望有高手可以帮忙,多谢,在线等,

回复评论 (14)

如果需要,我可以发整个程序代码给您,
QQ:236309574,
yyq_leaf@126.com
点赞  2007-12-30 11:58
没有这么干的,在读线程里不要直接readfile
发个消息让界面线程处理
点赞  2007-12-30 13:33
哦,??

多谢提醒,

那样的话,怎么做?

请大哥具体点可以吗????
点赞  2007-12-30 14:20
我使用弹出信息的方式看了,

是这句执行的有问题,

ReadFile(ceSeries-> m_hComm,   readBuf,   willReadLen,   &actualReadLen,0);

麻烦大家给看看吧,多谢了,
我很急啊,

不知道为什么会在这个地方出错,俺想不通,难道真的如MBWQ 大哥所说,不能在读线程里直接ReadFile,

我很想试试MBWQ 所说的方法,发个消息让界面线程处理,
但是,由于是初学VC++,所以根本不知道该如何做,
请大家指教!!!
点赞  2007-12-30 20:26
请各位不要吝惜您的知识好吗???


您的一点指点可能会帮了别人很大的忙。。。。。。
点赞  2007-12-30 21:24
各位大哥,我自己把读串口的操作放出来了,
通过消息响应,
但是,下面代码(1)地方出错了,
可以麻烦大家帮忙分析一下吗????
求你们了,给点反应好不好??!!!

/************************************************************************/
/* 串口接收回调函数                                                     */
/************************************************************************/
void CMFCWinCEDlg::OnSeriesRead(LPVOID lparam,DWORD willReadLen,CWnd* pOwner,HANDLE cehComm)
{       
        AfxMessageBox(L"99999999999999999");
        CCESeries *ceSeries = (CCESeries*)lparam;
        AfxMessageBox(L"11111");
        CMFCWinCEDlg *pDlg = (CMFCWinCEDlg *)pOwner;
        AfxMessageBox(L"22222");
        HANDLE hComm=cehComm;
        AfxMessageBox(L"33333");
        BYTE * readBuf = NULL;//读取的字节
        DWORD actualReadLen;
        AfxMessageBox(L"44444");
        readBuf = new BYTE[willReadLen];  //(1) 这里出错了,苍天啊,大地啊,哪位天使姐姐帮忙看看为什么?!
        AfxMessageBox(L"88888888888888");
        ReadFile(hComm, readBuf, willReadLen, &actualReadLen,0);
        AfxMessageBox(L"7777777777777");
        pDlg->UpdateData(TRUE);
        for(int i=0;i             pDlg->m_strRecv.Format(L"%s %c",pDlg->m_strRecv,readBuf);
        AfxMessageBox(L"6666666666666666");
        pDlg->m_strRecv.Format(L"%s %c",pDlg->m_strRecv,13);
        pDlg->m_strRecv.Format(L"%s %c",pDlg->m_strRecv,10);
        ::SendMessage(::GetDlgItem(pDlg->m_hWnd, IDC_EDIT_RECV), EM_LINESCROLL, 0,(LPARAM)(WORD)-1);
        pDlg->UpdateData(FALSE);
        delete[] readBuf;
}
点赞  2007-12-30 21:39
难道我这么定义也有问题:
BYTE * readBuf = new BYTE[200];

这样做,也冒犯了内存大哥了吗???!!

我郁闷了,真的,
很郁闷,

请哪位天使哥哥给我个解释好吗?
先谢谢了,

大冷天的,我昨天从8:00加班到21:00,
今天从8:00一直到现在,
不容易啊,

大家就帮帮我吧,
点赞  2007-12-30 21:46
全我一个人自言自语了,

郁闷,
难道是天气太冷,大家都不愿意伸出援手??!!
点赞  2007-12-30 21:47
BOOL CCESeries::OpenPort(CWnd* pPortOwner,                        /*使用串口类,窗体句柄*/
                                                 UINT portNo        ,                        /*串口号*/
                                                 UINT baud                ,                        /*波特率*/
                                                 UINT parity        ,                        /*奇偶校验*/
                                                 UINT databits        ,                        /*数据位*/
                                                 UINT stopbits                           /*停止位*/
                                                 )
{
//创建读串口线程
m_hReadThread = CreateThread(NULL,0,ReadThreadFunc,this,0,&m_dwReadThreadID);
//创建写串口线程
m_hWriteThread = CreateThread(NULL,0,WriteThreadFunc,this,0,&m_dwWriteThreadID);
}

请问大家,创建线程时,第四个参数可以用this吗?
为什么运行到“ pDlg-> UpdateData(TRUE);” 就出“Debug Assertion Failed!”错误,
谁知道怎么回事吗?

点赞  2007-12-31 09:34
错误如下:
C:\Documents and Settings\yyq\桌面\2770.jpg
点赞  2007-12-31 09:53
错误信息如下:

/*****************************************
Debug Assertion Failed!

Program:\Storage Card\MFCWinCE.exe
File:
f:\rtm\vctools\vc7libsce\ship\atlmfc\src\mfc\wincore.cpp
Line:1144
(Press Retry to debug the application)

Abort  Retry Ignore
*****************************************/

点赞  2007-12-31 14:30
// should also be in the permanent or temporary handle map
CHandleMap* pMap = afxMapHWND();
ASSERT(pMap != NULL);//?

句柄出错了。

//Create Comm Write Event
                m_hWriteEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
                ASSERT(m_hWriteEvent != NULL);
                ::ResetEvent(m_hWriteEvent);

                //Start read thread if not already started.
                if (!GetExitCodeThread(m_hReadThread, &dwState) || (dwState != STILL_ACTIVE))
                {
                        //开线程
                        m_hReadThread = CreateThread(NULL, 0, ReadThread, this, 0, &dwState);
                }
点赞  2008-1-2 14:24
谢谢您的回答,

我现在可以接收数据了,接收数据的代码如下:
//串口读线程函数
DWORD CCESeries::ReadThreadFunc(LPVOID lparam)
{
        CCESeries *ceSeries = (CCESeries*)lparam;       
        DWORD        evtMask;
        BYTE readBuf[1000]={0};//读取的字节
        DWORD actualReadLen=0;//实际读取的字节数
        DWORD willReadLen;
        DWORD dwReadErrors;
        COMSTAT        cmState;
        //TCHAR szBuf[200];
        // 清空缓冲,并检查串口是否打开。
        ASSERT(ceSeries->m_hComm !=INVALID_HANDLE_VALUE);        
        //清空串口
        PurgeComm(ceSeries->m_hComm, PURGE_RXCLEAR | PURGE_TXCLEAR );
        SetCommMask (ceSeries->m_hComm, EV_RXCHAR);// | EV_CTS | EV_DSR
        while (TRUE)
        {          
                        WaitCommEvent(ceSeries->m_hComm,&evtMask,0);
                        //表示串口收到字符               
                        if (evtMask & EV_RXCHAR)
                        {
                                ClearCommError(ceSeries->m_hComm,&dwReadErrors,&cmState);
                                willReadLen = cmState.cbInQue;
                                if (willReadLen == 0)
                                {
                                        continue;
                                }
                                ReadFile(ceSeries->m_hComm, readBuf, willReadLen, &actualReadLen,0);
                                if (actualReadLen>0)
                                {
                                        //触发读取数据回调函数
                                        ceSeries->m_OnSeriesRead(ceSeries->m_pPortOwner,readBuf,actualReadLen);
                                }
                        }
                if (WaitForSingleObject(ceSeries->m_hReadCloseEvent,500) == WAIT_OBJECT_0)
                {
                        break;
                }
        }
        return 0;


但是还有两个问题:
1. 经常会出现死机状态;
2. 读取到的数据经常分开两次返回,比如说硬件返回一条"Microsoft",这里经常会先收到"Mi",然后收到"crosoft";
3. 经常发完一条命令后,程序会自动退出;(发命令是通过发送命令,触发消息,通过消息处理函数做WriteFile()来写串口的)
4. 麻烦大家帮忙看看这段代码有没有什么问题,如果有,请提出来;

如果大家知道,
麻烦回答一下,
多谢了,

点赞  2008-1-2 21:19
无满意揭帖了,
实在没意思,
点赞  2008-1-3 21:21
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复