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

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 请教一下各位,为什么我这个没有实现模拟点击
  • ¥15 执行 virtuoso 命令后,界面没有,cadence 启动不起来
  • ¥50 comfyui下连接animatediff节点生成视频质量非常差的原因
  • ¥20 有关区间dp的问题求解
  • ¥15 多电路系统共用电源的串扰问题
  • ¥15 slam rangenet++配置
  • ¥15 有没有研究水声通信方面的帮我改俩matlab代码
  • ¥15 ubuntu子系统密码忘记
  • ¥15 保护模式-系统加载-段寄存器
  • ¥15 电脑桌面设定一个区域禁止鼠标操作