C++ 串口通信偶尔WriteFile卡死

wodenide007 CSDN会员 wodenide007 墨衍会员 · AI 创作全网分发 墨衍智能分发 通过墨衍一键同步至各平台 可同步平台 CSDN微信公众号微博知乎掘金百家号博客园抖音小红书 你的文章也可以这样分发 墨衍会员 ¥399起/年,写一次发全网 我也要 + 加入社区
最近做一个程序通过串口控制仪器,发现在正常收发数据一会儿之后,偶尔会在WriteFile发数据时程序卡死,部分代码如下,vs2013+win7.
bool CSerialPort::openComm()
{

m_hComm = CreateFileA(m_portNum.c_str(),
GENERIC_READ | GENERIC_WRITE, //允许读和写
0, //独占方式
NULL, OPEN_EXISTING, //打开而不是创建
0, //同步方式
NULL
);


if (m_hComm == INVALID_HANDLE_VALUE)
{

return false;

}
else
{
DCB dcb;
SetupComm(m_hComm, MAX_BUFFER_SIZE, MAX_BUFFER_SIZE); // 设置读写缓冲区大小
GetCommState(m_hComm, &dcb);
dcb.BaudRate = m_dwBaudRate;
dcb.ByteSize = m_byteSize;
dcb.Parity = m_parityBit;
dcb.StopBits = m_stopBit;

if (!SetCommState(m_hComm, &dcb))
{
return false;
}
}
//在读写串口前,用 PurgeComm 函数清空缓冲区
PurgeComm(m_hComm, PURGE_RXCLEAR | PURGE_TXCLEAR | PURGE_TXABORT | PURGE_TXABORT);

m_bOpen = true;

return true;

}

// 向串口发送数据
bool CSerialPort::writeToComm(const char* pData, unsigned int length)
{
DWORD dwError = 0;
if (ClearCommError(m_hComm, &dwError, NULL) && dwError > 0)
{
PurgeComm(m_hComm, PURGE_TXABORT | PURGE_TXCLEAR);
}

DWORD dwTx = 0;
BOOL ret = FALSE;

printf(pData);
printf("send\n");

ret = WriteFile(m_hComm, pData, length, &dwTx, NULL);

if (ret == FALSE)
{

return false;
}

return true;


}

UINT CSerialPort::GetBytesInCOM()
{
DWORD dwError = 0; /** 错误码 */
COMSTAT comstat; /** COMSTAT结构体,记录通信设备的状态信息 */
memset(&comstat, 0, sizeof(COMSTAT));

UINT BytesInQue = 0;
/** 在调用ReadFile和WriteFile之前,通过本函数清除以前遗留的错误标志 */
if (ClearCommError(m_hComm, &dwError, &comstat))
{
BytesInQue = comstat.cbInQue; /** 获取在输入缓冲区中的字节数 */
}

return BytesInQue;
}


bool CSerialPort::recv()
{
UINT BytesInQue = GetBytesInCOM();
if (BytesInQue == 0)
return false;

while (BytesInQue > 0)
{
BOOL bResult = TRUE;
DWORD BytesRead = 0;
char buf[bufsize];
/** 从缓冲区读取n个字节的数据 */
bResult = ReadFile(m_hComm, &buf, BytesInQue, &BytesRead, NULL);
if ((!bResult))
{
/** 获取错误码,可以根据该错误码查出错误原因 */
DWORD dwError = GetLastError();

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

return false;
}

if (BytesInQue + (int)strRecv.size() < bufsize)
strRecv += std::string(buf, BytesInQue);
else
strRecv = std::string(buf, BytesInQue);

Sleep(100);

BytesInQue = GetBytesInCOM();
}



return true;

}
...全文

相关推荐

VS2013 C++ MFC串口调试助手源码解析:从建工程到调通全流程

串口通信是嵌入式开发与上位机调试中最基础也最常用的技术之一,其核心原理是将串口设备视为文件,通过Win32 API的CreateFile、ReadFile和WriteFile实现数据的收发。在实际工程中,如何保证高速数据不丢帧、界面不卡顿,是衡量一个串口调试助手是否好用的关键。本文从串口通信的底层原理出发,介绍了基于C++与MFC框架构建串口调试助手的完整思路,涵盖串口参数配置、接收线程设计、自定义消息刷新界面、数据分包与常见排错技巧。该方案不仅适用于自定义协议调试、设备联调等场景,也能为二次开发提供清晰、

moumoon沐月

VS2013+C++实战:开发一款串口助手全流程解析

串口通信是嵌入式与工业控制领域的基础数据交互方式,通过标准API可实现设备间的可靠数据传输。在Windows平台上,基于C++与MFC框架构建串口调试助手,需要掌握串口参数配置、多线程接收机制、数据实时显示与发送等核心环节。实际工程实践中,利用Win32 API解决串口读写中的阻塞与乱码问题,并总结常见故障排查方法。该类工具适用于嵌入式开发、硬件调试及自动化测试等场景,帮助开发者快速定位问题、提升调试效率。从基础原理出发,逐步深入到工程实现,为串口上位机开发提供可复用的参考方案。

CodeCaptain

高校技术转移办公室如何实现技术成果的智能推荐与精准路演?.docx

科易网基于AI模型+行业大数据,在技术转移、成果转化、技术经纪、知识产权、产业创新、科技招商等垂直领域的多样化应用场景,推出科技创新领域的AI+工具与数智化解决方案,推动科技创新与产业创新智能化发展。

BIZKEEN

麻烦了熠哥,麻烦了熠哥麻烦了哈

麻烦了熠哥,麻烦了熠哥麻烦了哈。麻烦了熠哥,麻烦了熠哥麻烦了哈。麻烦了熠哥,麻烦了熠哥麻烦了哈

Return_xxx

STM32 LCD 16×2 屏幕使用

STM32 LCD 16×2 屏幕使用

给我留片猪头肉
评论 9
收藏 已收藏
分享
返回顶部
wodenide007 CSDN会员
C++ 语言 65,214 成员 250,514 内容