各位朋友大家好,有一个项目需要用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 = "";