Files
newspark110/device/SerialPort/SerialPort.cpp
Chenwenxuan edac2715f0 init
2024-03-06 14:54:30 +08:00

190 lines
4.6 KiB
C++

#include "SerialPort.h"
#include <assert.h>
#define RETURN_ACK 0xac
Comm::Comm()
{
m_hComm = nullptr;
InitializeCriticalSection(&mCsRead);
}
Comm::~Comm()
{
if (m_hComm != nullptr)
{
CloseComm();
}
m_hComm = nullptr;
}
int Comm::getSerialSet(QString DevName)
{
QSettings *settings;//申明一个QSetting类函数
settings = new QSettings ("SerialDevSet.ini", QSettings::IniFormat);//构建函数
QString strKey;
strKey = "/"+DevName+"/com";
com = settings->value(strKey).toString();
if (com.length() > 4)
{
com = "\\\\.\\" + com ;
}
strKey = "/"+DevName+"/baud";
nBaudRate = settings->value(strKey).toInt();
strKey = "/"+DevName+"/nParity";
nParity = settings->value(strKey).toInt();
strKey = "/"+DevName+"/nByteSize";
nByteSize = settings->value(strKey).toInt();
strKey = "/"+DevName+"/nStopBits";
nStopBits = settings->value(strKey).toInt();
if (nStopBits == 1)
nStopBits = 0;
strKey = "/"+DevName+"/pidP";
pidP = settings->value(strKey).toFloat();
strKey = "/"+DevName+"/dstPower";
dstPower = settings->value(strKey).toFloat();
return 0;
}
/*
nParity: 0-4=None,Odd,Even,Mark,Space 校验位
nByteSize: Number of bits/byte, 4-8 数据位
nStopBits: 0,1,2 = 1, 1.5, 2 停止位
*/
bool Comm::OpenComm()
{
if (m_hComm != nullptr)
return true;
DCB dcb; // 串口控制块
COMMTIMEOUTS timeouts = { // 串口超时控制参数
100, // 读字符间隔超时时间: 100 ms
10, // 读操作时每字符的时间: 1 ms (n个字符总共为n ms)
500, // 基本的(额外的)读超时时间: 500 ms
10, // 写操作时每字符的时间: 1 ms (n个字符总共为n ms)
100 }; // 基本的(额外的)写超时时间: 100 ms
m_hComm = CreateFile(reinterpret_cast<const wchar_t *>(com.utf16()), // 串口名称或设备路径
GENERIC_READ | GENERIC_WRITE, // 读写方式
0, // 共享方式:独占
nullptr, // 默认的安全描述符
OPEN_EXISTING, // 创建方式
0, // 不需设置文件属性
nullptr); // 不需参照模板文件
if (m_hComm == INVALID_HANDLE_VALUE)
{
//printf("open error\n");
m_hComm = nullptr;
return FALSE; // 打开串口失败 这里要发送失败消息
}
if (!SetCommTimeouts(m_hComm, &timeouts)) // 设置超时
{
//printf("SetCommTimeouts error\n");
CloseComm();
return false;
}
if (!GetCommState(m_hComm, &dcb)) // 取DCB
{
//printf("GetCommState error\n");
CloseComm();
return false;
}
dcb.BaudRate = static_cast<unsigned long>(nBaudRate);
dcb.ByteSize = static_cast<unsigned char>(nByteSize);
dcb.Parity = static_cast<unsigned char>(nParity);
dcb.StopBits = static_cast<unsigned char>(nStopBits);
if (!SetCommState(m_hComm, &dcb)) // 设置DCB
{
//printf("SetCommState error\n");
CloseComm();
return false;
}
if (!SetupComm(m_hComm, 4096, 2048)) // 设置输入输出缓冲区大小
{
//printf("SetupComm error\n");
CloseComm();
return false;
}
PurgeComm(m_hComm, PURGE_TXABORT | PURGE_RXABORT |
PURGE_TXCLEAR | PURGE_RXCLEAR);
return TRUE;//这里发送成功消息
}
// 关闭串口
bool Comm::CloseComm()
{
bool ret = true;
if (m_hComm != nullptr)
ret = CloseHandle(m_hComm);
m_hComm = nullptr;
return ret;
}
int Comm::SendCmd(char *data, unsigned short data_len ,unsigned char * revData, int * revData_len)
{
DWORD dwNumWrite; // 串口发出的数据长度
DWORD dwNumRead; // 串口收到的数据长度
unsigned char rev_buf[4096];
DWORD RevDataLen = 0;
DWORD dwError = 0;
COMSTAT ComStat;
int count = 0;
if (data == nullptr)
{
return -1;
}
dwNumRead = 0;
memset(rev_buf, 0, sizeof(rev_buf));
PurgeComm(m_hComm, PURGE_TXABORT | PURGE_RXABORT |
PURGE_TXCLEAR | PURGE_RXCLEAR);
if (!WriteFile(m_hComm, data, static_cast<unsigned long>(data_len), &dwNumWrite, nullptr))
{
return -1;
}
// if (strcmp("mon\r", data) != 0)
// {
// return 0;
// }
while (TRUE)
{
Sleep(100);
ClearCommError(m_hComm, &dwError, &ComStat);
if ((ComStat.cbInQue >= 1))
{
if (!::ReadFile(m_hComm, rev_buf, ComStat.cbInQue, &RevDataLen, nullptr))
{
return -3;
}
else
{
*revData_len = static_cast<int>(RevDataLen);
memcpy_s(revData,RevDataLen,rev_buf,RevDataLen);
break;
}
}
count++;
if (count >= 20)
return -1;
}
return 0;
}