xiaohui96 2019-03-14 20:44 采纳率: 0%
浏览 1931

C++串口通信writefile()后为什么要Sleep,readfile()才能读取到数据?

各位朋友大家好,有一个项目需要用C++实现串口通信(采用同步方式因为需要轮询下位机)并将串口的数据通过socket发送给服务器,现在基本功能已经实现,还存在一个小bug。当上位机用writefile函数向下位机写数据时,需要在writefile后Sleep(75),接收readfile时才能读取到数据,不加延时数据则为空。我的readfile函数是单独开了一个级别高的线程来完成的。writefile和线程的代码如下,各位帮忙提提意见

// 向串口写数据, 将缓冲区中的数据写入到串口
bool CSerialPort::WriteData(unsigned char *pData,  int length)
{

    int *pData1=new int;
    BOOL   bResult = TRUE;
    DWORD  BytesToSend = 0;
    if (m_hComm == INVALID_HANDLE_VALUE)
    {
        return false;
    }

    /** 临界区保护 */
    EnterCriticalSection(&m_csCommunicationSync);

    /** 向缓冲区写入指定量的数据 */
    bResult = WriteFile(m_hComm,/*文件句柄*/pData,/*用于保存读入数据的一个缓冲区*/ 9,/*要读入的字符数*/ &BytesToSend,/*指向实际读取字节数的指针*/ NULL);
    if (!bResult)
    {
        DWORD dwError = GetLastError();
        /** 清空串口缓冲区 */
        PurgeComm(m_hComm, PURGE_RXCLEAR | PURGE_RXABORT);
        LeaveCriticalSection(&m_csCommunicationSync);

        return false;
    }


    /** 离开临界区 */
    LeaveCriticalSection(&m_csCommunicationSync);
    Sleep(75);
    return true;
    }

//串口监听线程
UINT WINAPI CSerialPort::ListenThread(void* pParam)
{
/** 得到本类的指针 /
CSerialPort *pSerialPort = reinterpret_cast<CSerialPort
>(pParam);
// 线程循环,轮询方式读取串口数据

while (!pSerialPort->s_bExit)
{
UINT BytesInQue = pSerialPort->GetBytesInCOM();
/** 如果串口输入缓冲区中无数据,则休息一会再查询 /
for(int time=1;time<=3;time++){
if ((BytesInQue == 0))
{
Sleep(SLEEP_TIME_INTERVAL);
continue;
}
}
/
* 读取输入缓冲区中的数据并输出显示 */
//unsigned char cRecved = 0x00;
unsigned char cRecved ;
do
{
cRecved =0x00;
if (pSerialPort->ReadChar(cRecved) == true)
{

            // 定义字符串流,将后面的字符串按照对象存入到ss中并以空格键结束
            std::stringstream  ss; 

            int tm = cRecved;
            // std::hex表示16进制输出流,即后面输出的为16进制的形式,setw(2)以两个字符的形式输出,setfill(0)不够两个字符的用0填充。
            ss << std::hex << std::setw(2) << std::setfill('0') << tm;
            //减少传输数据大小,字符间不需空格
            //ss << " ";
            // 转换成大写
            string a = ss.str();
            //string b;

            //transform(a.begin(), a.end(), back_inserter(b), ::toupper);
            // 显示占用时间,引起错误
            //cout <<  b ;

            // 拼接传递给server
            recdata +=  a;
            continue;
            }
    } 
    while (--BytesInQue);   

    // 循环结束产生信号
    setClientUploadEvents();

}
return 0;
}

//读取串口接收缓冲区中一个字节的数据
bool CSerialPort::ReadChar(unsigned char &cRecved)
{
    BOOL  bResult = TRUE;
    DWORD BytesRead = 0;
    DWORD Bytesnum = GetBytesInCOM();
    if (m_hComm == INVALID_HANDLE_VALUE)
    {
        return false;
    }

    /** 临界区保护 */
    EnterCriticalSection(&m_csCommunicationSync);
    /** 从缓冲区读取一个字节的数据 */
        bResult = ReadFile(m_hComm, &cRecved, 1, &BytesRead, NULL);

    if ((!bResult))
    {
        /** 获取错误码,可以根据该错误码查出错误原因 */
        DWORD dwError = GetLastError();

        /** 清空串口缓冲区 */
        PurgeComm(m_hComm, PURGE_RXCLEAR | PURGE_RXABORT);
        LeaveCriticalSection(&m_csCommunicationSync);

        return false;
    }

    /** 离开临界区 */
    LeaveCriticalSection(&m_csCommunicationSync);

    return (BytesRead == 1);

}

主函数代码:
cout << mySerialPort.WriteData(temp, 9) << endl;
WaitForSingleObject(hEvent, INFINITE);
// 有信号执行下面语句
cout << 12345 << endl;
mySerialPort.socketsend(recdata,1,sclient);
recdata = "";

  • 写回答

1条回答 默认 最新

  • threenewbee 2019-03-14 23:52
    关注

    估计是有一个延迟,加上sleep等数据传过来,否则还没有来得及。

    评论

报告相同问题?

悬赏问题

  • ¥15 写一个方法checkPerson,入参实体类Person,出参布尔值
  • ¥15 我想咨询一下路面纹理三维点云数据处理的一些问题,上传的坐标文件里是怎么对无序点进行编号的,以及xy坐标在处理的时候是进行整体模型分片处理的吗
  • ¥15 CSAPPattacklab
  • ¥15 一直显示正在等待HID—ISP
  • ¥15 Python turtle 画图
  • ¥15 关于大棚监测的pcb板设计
  • ¥15 stm32开发clion时遇到的编译问题
  • ¥15 lna设计 源简并电感型共源放大器
  • ¥15 如何用Labview在myRIO上做LCD显示?(语言-开发语言)
  • ¥15 Vue3地图和异步函数使用