免费注册 查看新帖 |

ChinaUnix.net

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2857 | 回复: 8

Windows与ARM2440串口通信的问题 [复制链接]

论坛徽章:
0
发表于 2008-11-19 11:38 |显示全部楼层
写了一个Windows下模拟超级终端与串口通信的程序。现在已经能相互通信,但有一个问题:每次我往串口写入数据后,这个数据马上会被负责读串口的线程读到。怎么能象超级终端里那样读和写完全分开?请问怎么解决?

[ 本帖最后由 Wind-Son 于 2008-11-19 11:47 编辑 ]

论坛徽章:
0
发表于 2008-11-19 11:40 |显示全部楼层
代码:
BOOL CComS::Connect(ComParam* p)
{
    CString name;

    ASSERT(p);

    if (m_hCom) {
        ErrMsg(IDS_ERR_COM_AREADY_OPEN);
        return FALSE;
    }

    name.Format(_T("COM%d"), p->u.Coms.ID);

    m_hCom = ::CreateFile(name,
        GENERIC_READ|GENERIC_WRITE,
        0,
        NULL,
        OPEN_EXISTING,
        /*FILE_ATTRIBUTE_NORMAL|*/FILE_FLAG_OVERLAPPED,
        NULL);
    if (m_hCom == INVALID_HANDLE_VALUE) {
        ReportLastErr();
        return FALSE;
    }

    DCB LocalDCB;

    LocalDCB.DCBlength = sizeof(LocalDCB);

    if (!::GetCommState(m_hCom, &LocalDCB)) {
        ReportLastErr();
        ::CloseHandle(m_hCom);
        return FALSE;
    }

    LocalDCB.BaudRate = p->u.Coms.Baudrate;
    LocalDCB.fBinary = TRUE;
    LocalDCB.fParity = FALSE;
    LocalDCB.fOutxCtsFlow = FALSE;
    LocalDCB.fOutxDsrFlow = FALSE;
    LocalDCB.fDtrControl = DTR_CONTROL_DISABLE;//DTR_CONTROL_HANDSHAKE;

    LocalDCB.fRtsControl = RTS_CONTROL_DISABLE;//DTR_CONTROL_HANDSHAKE;

    LocalDCB.fOutX = FALSE;
    LocalDCB.fInX = FALSE;
    LocalDCB.fNull = FALSE;
    LocalDCB.fNull=FALSE;
    LocalDCB.ByteSize = 8;
    LocalDCB.Parity = NOPARITY;
    LocalDCB.StopBits = ONESTOPBIT;
    if (!::SetCommState(m_hCom, &LocalDCB)) {
        ReportLastErr();
        ::CloseHandle(m_hCom);
        return FALSE;
    }

    DWORD err;
    if (!::ClearCommError(m_hCom, &err, NULL)) {
        ReportLastErr();
        return FALSE;
    }

    memset(&m_ComOverlap, 0, sizeof(OVERLAPPED));
    m_ComOverlap.hEvent = ::CreateEvent(NULL, TRUE, FALSE, NULL);
    m_Event = ::CreateEvent(NULL, TRUE, FALSE, NULL);

    int byteUsedTime = 14400 / 115200 +1 + 1000;
    COMMTIMEOUTS timeouts = {20 + byteUsedTime, byteUsedTime, 1000, byteUsedTime , 20};
    SetCommTimeouts(m_hCom, &timeouts) ;
    SetCommMask(m_hCom, EV_RXCHAR|EV_TXEMPTY );//设置事件驱动的类型

    SetupComm(m_hCom, 10204, 5210);
    PurgeComm(m_hCom, PURGE_RXCLEAR|PURGE_TXCLEAR|PURGE_RXABORT|PURGE_TXABORT);

    InitializeCriticalSection(&m_Critical);

    return TRUE;
}

BOOL CComS::Disconnect()
{
    DWORD err;

    if (!::ClearCommError(m_hCom, &err, NULL))
        ReportLastErr();
    if (!::CloseHandle(m_hCom))
        ReportLastErr();
    SetEvent(m_ComOverlap.hEvent);
    Sleep(100);
    if (!::CloseHandle(m_ComOverlap.hEvent))
        ReportLastErr();
    if (!::CloseHandle(m_Event))
        ReportLastErr();
    m_hCom = NULL;
    return TRUE;
}


论坛徽章:
0
发表于 2008-11-19 11:41 |显示全部楼层
没明白问题在哪里

论坛徽章:
0
发表于 2008-11-19 11:42 |显示全部楼层
代码2:
BOOL CComS::Send(LPBYTE pBuf, int len, DWORD MaxTime)
{
    BOOL ret = FALSE;
    OVERLAPPED overlap;

    ASSERT(m_hCom != NULL);
    ASSERT(len < 2000);

    DWORD written = 0;

    SetEvent(m_ComOverlap.hEvent);

    memset(&overlap, 0, sizeof(OVERLAPPED));
    overlap.hEvent = ::CreateEvent(NULL, TRUE, FALSE, NULL);

    EnterCriticalSection(&m_Critical);

    BYTE Buf[100] = "rbbttqqyybb";
    //if (!::WriteFile(m_hCom, Buf, 10, &written, &overlap)) {

    if (!::WriteFile(m_hCom, pBuf, len, &written, &overlap)) {
        if (::GetLastError() == ERROR_IO_PENDING) {
            if (::WaitForSingleObject(overlap.hEvent, MaxTime) == WAIT_OBJECT_0) {
                if (!GetOverlappedResult(m_hCom, &overlap, &written, FALSE))
                    ReportLastErr();
                ret = TRUE;
            }
        }
    } else {
        ret = TRUE;
    }

    if (!::CloseHandle(overlap.hEvent))
        ReportLastErr();

    LeaveCriticalSection(&m_Critical);

    return ret;
}

DWORD CComS::Receive(LPBYTE pDestBuf, int length, DWORD MaxTime)
{
#define RX_BUF_LEN    10000
    static BYTE buffer[RX_BUF_LEN];
    static int curOut = -1, curLen = 0;
    int tmp, len;

    ASSERT(m_hCom != NULL);
    ASSERT(length < 2000);

    tmp = length;
   
    if (curLen) {
        len = min(length, curLen);
        memcpy(pDestBuf, &buffer[curOut], len);
        length -= len;
        pDestBuf += len;
        curOut += len;
        curLen -= len;
        if (length == 0)
            return len;
    }
    ASSERT(curLen == 0);

    EnterCriticalSection(&m_Critical);

    DWORD dwEvtMask = 0;
    OVERLAPPED os;
    memset(&os, 0, sizeof(OVERLAPPED));
    os.hEvent = m_Event;
    ResetEvent(m_Event);
    SetCommMask(m_hCom, EV_RXCHAR|EV_TXEMPTY);

    COMSTAT ComStat;
    DWORD dwLength, dwErrorFlags, dwBytesRead;
    if (!WaitCommEvent(m_hCom, &dwEvtMask, &os)) {
        if (::WaitForSingleObject(m_ComOverlap.hEvent, 0) == WAIT_OBJECT_0) {
            ResetEvent(m_ComOverlap.hEvent);
            goto out;
        }
        if (GetLastError() != ERROR_IO_PENDING)
            goto out;
        if (::WaitForSingleObject(m_Event, 300) == WAIT_OBJECT_0) {
            if (!GetOverlappedResult(m_hCom, &os, &dwBytesRead, FALSE)) {
                ReportLastErr();
                goto out;
            }
            //break;

        }
        //dwEvtMask = 0;

    }

    if (dwEvtMask & EV_TXEMPTY) {
        //PurgeComm(m_hCom, PURGE_TXCLEAR|PURGE_TXABORT);

        goto out;
    }

    if (!(dwEvtMask & EV_RXCHAR))
        goto out;
   
    ClearCommError(m_hCom, &dwErrorFlags, &ComStat) ;
    dwLength = ComStat.cbInQue;
    if (dwLength > 0) {               
        ResetEvent(os.hEvent);
        ASSERT(dwLength <= RX_BUF_LEN);
        if (!ReadFile(m_hCom, buffer, dwLength,
            &dwBytesRead, &os)) {
            ReportLastErr();
        }
        //GetOverlappedResult(m_hCom, &os, &dwBytesRead, TRUE);

        len = min((int)dwBytesRead, length);
        memcpy(pDestBuf, buffer, len);
        curLen = dwBytesRead - len;
        curOut = len;
        length -= len;            
    }

out:
    LeaveCriticalSection(&m_Critical);
    return tmp - length;
}

论坛徽章:
0
发表于 2008-11-19 11:45 |显示全部楼层
原帖由 eveson 于 2008-11-19 11:41 发表
没明白问题在哪里

本来应该是接收线程只可以读到从开发板发上来的数据(上行数据),可实际上发送到板子上的数据(下行数据)也被它读到了
上行和下行的数据混到一起了

[ 本帖最后由 Wind-Son 于 2008-11-19 11:46 编辑 ]

论坛徽章:
0
发表于 2008-11-19 14:31 |显示全部楼层
读写保护啊!或者双通道,

论坛徽章:
0
发表于 2008-11-19 16:49 |显示全部楼层
怎么会啊,串口应该会有接受buffer和发送buffer的啊。

论坛徽章:
0
发表于 2008-11-19 17:04 |显示全部楼层
原帖由 eveson 于 2008-11-19 16:49 发表
怎么会啊,串口应该会有接受buffer和发送buffer的啊。

我也觉得很奇怪,搞了两天都没解决。按理流文件发出去的数据都读不回来才对啊

论坛徽章:
0
发表于 2008-11-19 17:22 |显示全部楼层
好好检查下代码吧,肯定哪个地方不小心让你写错了。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

基于案例的 SQL 优化实战训练营

讲师:中电福富特级专家梁敬彬,参与本次课程培训,你将收获:
1. 能编写出较为高效的 SQL;
2. 能解决70%以上的数据库常见优化问题;
3. 能得到老师提供的高效的相关工具和解决方案;
4. 能举一反三,收获不仅仅是 SQL 优化。
现在购票享受8.8折优惠!
----------------------------------------
优惠时间:2019年3月20日前

大会官网>>
  

北京盛拓优讯信息技术有限公司. 版权所有 16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122
中国互联网协会会员  联系我们:huangweiwei@it168.com
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP