【发布时间】:2022-01-03 13:42:30
【问题描述】:
这是所有轮询com口的代码,根据modbus-RTU协议,设备没有响应。我不知道如何让设备响应我。设备地址和功能码足以回答。这些是前两个字符(0x15、0x03 ...) 我不知道我做错了什么!
有一个代码:
#include <windows.h>
#include <stdio.h>
#include <iostream>
#include <TCHAR.h>
using namespace std;
#pragma warning(disable:4996)
//обработчик COM порта
HANDLE hSerial;
//название порта
LPCTSTR sPortName = L"COM3";
int ReadCOM()
{
int a = 0;
DWORD iSize;
char sReceivedChar = { 0 };
char recBuf[100] = { 0 };
recBuf[0] = '\0';
while (!a)
{
//получение ответа
ReadFile(hSerial, &sReceivedChar, 1, &iSize, 0); // получаем 1 байт
if (iSize > 0) // если что-то принято, выводим
{
cout << "Answer: " << sReceivedChar;
strcat(recBuf, &sReceivedChar);
}
else
{
cin >> a;
}
}
CloseHandle(hSerial);
return 0;
}
int _tmain(int argc, _TCHAR* argv[])
{
//настройка параметров соединения (В данном случае COM порта)
DCB *dcbSerialParams = (DCB*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(DCB));;
dcbSerialParams->DCBlength = sizeof(dcbSerialParams);
if (BuildCommDCB(L"baud=9600 parity=E data=8 stop=2", dcbSerialParams))
{
std::cout << "success 1" << std::endl;
}
else
{
std::cout << "failure 1" << std::endl;
}
dcbSerialParams->fNull = TRUE;
//установка таймаута приема и передачи порта
COMMTIMEOUTS CommTimeOuts;
CommTimeOuts.ReadIntervalTimeout = 1000;
CommTimeOuts.ReadTotalTimeoutConstant = CommTimeOuts.ReadTotalTimeoutMultiplier = 100;
CommTimeOuts.WriteTotalTimeoutConstant = CommTimeOuts.WriteTotalTimeoutMultiplier = 100;
//открытие порта для чтения/записи
hSerial = CreateFile(sPortName, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
//проверка роботоспособности (не работает)
if (hSerial == INVALID_HANDLE_VALUE)
{
if (GetLastError() == ERROR_FILE_NOT_FOUND)
{
cout << "wrn::Serial port does NOT exist.\n";
}
else
{
cout << "wrn::Some other error occurred.\n";
}
}
//(работает) пишем соответствующее сообщение
else
{
cout << "suc::Serial port DOES exist.\n";
}
//запись свойств порта
if (!SetCommState(hSerial, dcbSerialParams))
{
cout << "faulure 2" << endl;
}
if (!SetCommTimeouts(hSerial, &CommTimeOuts))
{
cout << "failure 3" << endl;
}
//Освобождение DCB
HeapFree(GetProcessHeap(), 0, dcbSerialParams);
//char data[] = { 0x15, 0x03, 0x6B, 0x03, 0x37, 0x7E };
char data[] = { 0x15, 0x03, 0x00, 0x00, 0x00, 0x01, 0x84, 0x0A};
DWORD dwSize = sizeof(data); // размер этой строки
DWORD dwBytesWritten; // тут будет количество собственно переданных байт
BOOL iRet = WriteFile(hSerial, data, dwSize, &dwBytesWritten, NULL);
//нормальная работа
if (iRet)
{
cout << "nor :: " << dwSize << " Bytes in string. " << dwBytesWritten << " Bytes sended. " << endl;
}
//ошибка передачи
else
{
cout << "wrn :: " << "db = " << dwBytesWritten << "\nds = " << dwSize << endl;
}
ReadCOM();
return 0;
}
【问题讨论】:
-
对二进制数据使用字符串操作函数(例如
strcat)肯定会在您第一次读取值为零的字节时失败。更合适的方法是使用std::vector。如果您的其余代码准备好处理嵌入了 NUL 字符的字符串,即使std::string也可以工作。