串口通信问题,CE 5.0 + Evc 4.0 + Sp4 + API

mdlv   2007-11-15 16:59 楼主
我参照Msdn+网上资料写一个串口通信的类。
如下:
// CeSeriapPort.cpp: implementation of the CCeSerialPort class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "CeSeriapPort.h"
#include "comport.h"

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CCeSerialPort::CCeSerialPort()
{
        m_bAlive = false;
        m_hComm = NULL;
        ZeroMemory(m_bReadBuf,sizeof(m_bReadBuf));
}

CCeSerialPort::~CCeSerialPort()
{

}

BOOL CCeSerialPort::OpenPort(UINT uPort, UINT uBaud, BYTE bData, BYTE bStop, BYTE bVerify)
{
        WCHAR wszPort[16] = L"";
        ::wsprintf(wszPort,L"COM%d:",uPort);
        DCB dcb;
        HANDLE hThread = NULL;
       
        m_hComm = CreateFile(wszPort,GENERIC_READ | GENERIC_WRITE,0,NULL,OPEN_EXISTING,0,NULL);
        if(INVALID_HANDLE_VALUE == m_hComm)
        {
                MessageBox(NULL,L"打开串口失败!",L"错误信息",MB_ICONSTOP);
                return FALSE;
        }

        if(!SetCommMask(m_hComm,EV_RXCHAR | EV_CTS | EV_DSR | EV_RING | EV_RLSD)) //| EV_CTS | EV_DSR | EV_RING | EV_RLSD
        {
                MessageBox(NULL,L"设置串口事件失败!",L"错误信息",MB_ICONSTOP);
        }

        SetupComm(m_hComm,256,256);

        PurgeComm(m_hComm,PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR);
       
        dcb.DCBlength = sizeof(DCB);

        if(GetCommState(m_hComm,&dcb))
        {
                dcb.BaudRate = uBaud;
                dcb.ByteSize = bData;
                dcb.StopBits = bStop;
                dcb.Parity = bVerify;
                dcb.fBinary = TRUE;
                dcb.fParity = TRUE;
                dcb.fOutxCtsFlow = FALSE;
                dcb.fOutxDsrFlow = FALSE;
                dcb.fDtrControl = DTR_CONTROL_ENABLE;
                dcb.fDsrSensitivity = FALSE;      
                dcb.fTXContinueOnXoff = TRUE;   
                dcb.fOutX = FALSE;            
                dcb.fInX = FALSE;              
                dcb.fErrorChar = FALSE;           
                dcb.fNull = FALSE;               
                dcb.fRtsControl = RTS_CONTROL_ENABLE;
                dcb.fAbortOnError = FALSE;      


                if(!SetCommState(m_hComm,&dcb))
                {
                        MessageBox(NULL,L"设置串口属性失败!",L"错误信息",MB_ICONSTOP);
                }
        }

        COMMTIMEOUTS CommTimeouts;
        GetCommTimeouts (m_hComm, &CommTimeouts);

        // Change the COMMTIMEOUTS structure settings.
        CommTimeouts.ReadIntervalTimeout = MAXDWORD;  
        CommTimeouts.ReadTotalTimeoutMultiplier = 0;  
        CommTimeouts.ReadTotalTimeoutConstant = 0;   
        CommTimeouts.WriteTotalTimeoutMultiplier = 10;  
        CommTimeouts.WriteTotalTimeoutConstant = 1000;



        if(!SetCommTimeouts(m_hComm,&CommTimeouts))
        {
                MessageBox(NULL,L"设置超时参数失败!",L"错误信息",MB_ICONSTOP);
        }

        m_bAlive = true;

//        DWORD dw = 0;
//        ReadFile(m_hComm,m_bReadBuf,sizeof(m_bReadBuf),&dw,0);

        hThread = CreateThread(NULL,0,ComThreadProc,this,0,NULL);
        if(hThread == NULL)
        {
                m_bAlive = false;
                MessageBox(NULL,L"创建监视线程失败!",L"错误信息",MB_ICONSTOP);
                CloseHandle(m_hComm);
                return FALSE;
        }

        CloseHandle(hThread);

        return TRUE;
}

void CCeSerialPort::ClosePort()
{
        if(m_bAlive)
        {
                m_bAlive = false;
                SetCommMask(m_hComm,0);
                PurgeComm(m_hComm,PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR);
                CloseHandle(m_hComm);
                m_hComm = NULL;
        }
}

DWORD CCeSerialPort::ComThreadProc(LPVOID lParam)
{
        CCeSerialPort * pPort = (CCeSerialPort*)lParam;
        DWORD dwEvtMask,dwReaded = 0,dwError = 0;
        COMSTAT comstat;

        SetCommMask(pPort->m_hComm, EV_RXCHAR | EV_CTS | EV_DSR | EV_RLSD | EV_RING);

        while(pPort->m_bAlive)
        {       
                WaitCommEvent(pPort->m_hComm,&dwEvtMask,0);
               
                if(pPort->m_bAlive == false) break;

                SetCommMask (pPort->m_hComm, EV_RXCHAR | EV_CTS | EV_DSR | EV_RLSD | EV_RING);

                if((dwEvtMask & EV_RXCHAR) == EV_RXCHAR)
                {
                        ClearCommError(pPort->m_hComm,&dwError,&comstat);
                        if(comstat.cbInQue > 0)
                        {
                                if(ReadFile(pPort->m_hComm,pPort->m_bReadBuf,MAX_READ_BUFFER,&dwReaded,0) && dwReaded > 0)
                                {
                                        ShowData(pPort->m_bReadBuf,dwReaded);
                                        ZeroMemory(pPort->m_bReadBuf,dwReaded);
                                }
                        }
                }
                else
                {
                        dwReaded = 0;
                        if(GetCommModemStatus(pPort->m_hComm,&dwReaded))
                        {
                                ChangeState(dwReaded);
                        }
                }       
        }
        return 0;
}

DWORD CCeSerialPort::WriteData(BYTE *pszBuff,DWORD dwWriteBytes)
{
        DWORD dwWrited = 0;
        if(m_bAlive)
        {
                if(!WriteFile(m_hComm,(LPCVOID)pszBuff,dwWriteBytes,&dwWrited,0))
                {
                        dwWrited = 0;
                }
        }

        return dwWrited;
}

BOOL CCeSerialPort::SetLineState(DWORD dwState)
{
        if(m_bAlive)
        {
                return EscapeCommFunction(m_hComm,dwState);
        }
        return FALSE;
}

此类写串口好用,读串口不好用。

阻塞在WaitCommEvent函数,当我发送数据的时候他不响应。程序退出的时候它响应。

另一端为开发机: P D 3.0 + 1G内存 + xp + 串口调试工具 + evc 4.0 + Sp4

回复评论 (8)

各位老大上
点赞  2007-11-16 07:52
如果能用示波器,就先看一下信号。也许是电路的问题。

如果不能用示波器,或者硬件电路没有问题,

你先用别的串口工具测试一下,会不会出现同样的问题。
点赞  2007-11-16 08:01
我用其他的串口工具同样只能发不能读,我是软件开发人员不用过也不会用示波器。
点赞  2007-11-16 08:29
另外我还发现,文本框显示数字的速度很慢

实际情况:
ce发送数据到xp,xp这面已经收到数据了,ce这方面发出数据长度还没有更改。

我使用SetDlgItemInt(hwndDlg,IDC_EDIT_SEND_NUM,g_uSendBytes,FALSE);


g_uSendBytes为全局变量
点赞  2007-11-16 08:50
问题已经找到,谢谢各位.
点赞  2007-11-16 14:29
怎么回事啊
点赞  2007-11-16 17:21
Iobase,SysIntr设置不正确
点赞  2007-12-5 08:07
Iobase,SysIntr在哪里设置?
点赞  2008-4-25 15:19
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复