这里使用的是SerialPort 4.3版本的,其他的流程详见这位大佬
CSerialPort教程4.3.x (2) - CSerialPort源码简介 - 知乎 (zhihu.com)
如果想要以十六进制发送数据,转换代码如下:
std::vector<unsigned char> MyclassDlg::HexStringToBytes(const CString& hexString)
{
std::vector<unsigned char> bytes;
CString temp = hexString;
temp.Remove(' '); // 移除空格
// 检查字符串长度,必须是偶数
if (temp.GetLength() % 2 != 0)
{
AfxMessageBox(_T("十六进制字符串的长度必须为偶数"));
return bytes;
}
for (int i = 0; i < temp.GetLength(); i += 2)
{
unsigned int byte;
CString byteString = temp.Mid(i, 2);
if (_stscanf_s(byteString, _T("%02x"), &byte) == 1)
{
bytes.push_back(static_cast<unsigned char>(byte));
}
else
{
AfxMessageBox(_T("无效的十六进制字符"));
return std::vector<unsigned char>(); // 返回空数组表示出错
}
}
return bytes;
}
发送代码如下:
void MyClassDlg::OnBnClickedButtonSend()
{
// TODO: 在此添加控件通知处理程序代码
GetDlgItem(IDC_SendEdit)->SetFocus();
if (!m_SerialPort.isOpen()) ///没有打开串口
{
AfxMessageBox(_T("请首先打开串口"));
return;
}
CString temp;
m_Send.GetWindowText(temp);
if (BST_CHECKED == ((CButton*)GetDlgItem(IDC_CHECK_HEXSEND))->GetCheck())
{
// 转换十六进制字符串到字节数组
std::vector<unsigned char> data = HexStringToBytes(temp);
if (!data.empty())
{
m_SerialPort.writeData(data.data(), data.size());
tx += data.size();
CString str2;
str2.Format(_T("%d"), tx);
m_sendCountCtrl.SetWindowText(str2);
}
else
{
AfxMessageBox(_T("请输入有效的十六进制字符串"));
}
}
else {
int len = 0;
char* m_str = NULL;
#ifdef UNICODE
// 兼容中文
CStringA strA(temp);
len = strA.GetLength();
m_str = strA.GetBuffer();
#else
len = temp.GetLength();
m_str = temp.GetBuffer(0);
#endif
m_SerialPort.writeData(m_str, len);
tx += len;
CString str2;
str2.Format(_T("%d"), tx);
m_sendCountCtrl.SetWindowText(str2);
}
}
代码解释
-
HexStringToBytes 函数:这是一个辅助函数,将十六进制字符串转换为字节数组。它首先移除字符串中的空格,然后检查长度是否为偶数,最后将每两个字符转换为一个字节。
-
错误检查:如果输入不是有效的十六进制字符串,该函数会返回一个空的字节数组并弹出错误消息。
-
发送逻辑更新:在按钮点击事件中,调用
HexStringToBytes
函数将输入字符串转换为字节数组,再通过writeData
方法发送。
注意事项
- 输入格式:确保用户输入的是有效的十六进制字符串,每个字节由两个字符表示。例如,"A1 B2 C3" 或 "A1B2C3"。
- 错误处理:在转换过程中增加了错误处理,确保无效输入不会导致程序崩溃。
- 字节数组发送:修改后的代码将字节数组直接传递给
writeData
函数。