当时,我们正在尝试创建用于串行通信的接口,以便能够与微处理器进行通信。
实际上-一切正常。几乎!为了能够与我们的控制器进行通信,我们需要与其进行同步。为此,我们编写一个字符串:"?0{SY}13!"
,然后控制器应以"!0{SY}F5?"
答复以接受同步请求。为此,我们使用writeData
函数(有效-我们知道通过使用echo
),然后使用readData
来读取答案。问题在于,由于某种原因,它将无法读取任何内容。尽管它成功返回1
,但它读取的字符始终为" "
(无)。
现在出现了一个奇怪的部分-如果我们使用外部终端程序初始化端口(如腻子),然后关闭程序,则一切正常。它接受同步请求,回答(我们可以阅读),然后我们可以做所有想要的事情。但是除非我们使用外部程序初始化端口,否则它将无法正常工作。
用于初始化接口的构造函数如下:
SerialIF::SerialIF(int baud, int byteSize, int stopBits, char* parity, int debug)
{
string coutport = getPort();
wstring wideport;
debug_ = debug; //Debuglevel
sync = false; //sync starts with false
error = false; //Error false as beginnging
//this is just for converting to the right type
for (int i = 0; i < coutport.length(); i++)
{
wideport += wchar_t(coutport[i]);
}
const wchar_t* port = wideport.c_str();
SerialIF::hserial = CreateFile(port,
GENERIC_READ | GENERIC_WRITE,
0,
0,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
0);
if (hserial == INVALID_HANDLE_VALUE)
{
if (GetLastError() == ERROR_FILE_NOT_FOUND)
{
if (debug_ != LOW)
{
cout << "[-] Port " << coutport << "doesn't exist." << endl;
}
}
if (debug_ != LOW)
{
cout << "[-] Handle error - is there another terminal active?" << endl;
}
error = true;
}
DCB dcbParms = { 0 };
dcbParms.DCBlength = sizeof(dcbParms);
if (!GetCommState(hserial, &dcbParms))
{
if (debug_ != LOW)
{
cout << "[-] Couldn't get status from port " << coutport << endl;
}
error = true;
}
if (!error)
{
setBaud(dcbParms, baud);
setParity(dcbParms, parity);
setByteSize(dcbParms, byteSize);
setStopbits(dcbParms, stopBits);
if (debug_ == HIGH)
{
cout << "[+] Serial port " << coutport << " has been activated. \nBaud-rate: " << baud << "\nParity: "
<< parity << "\nStop bits: " << stopBits << endl;
}
}
else if (debug_ != LOW)
{
cout << "[-] Port not initialized" << endl;
}
}
这应该有效-我真的不知道为什么不应该。它没有返回错误,最近几天我尝试了很多错误搜索,尝试了超时,尝试了其他方式构建它,但是都归结为相同的问题。
为什么不初始化端口?
编辑:
[尝试同步时的输出:由于缺乏声誉而无法发布图片。尽管输出如下:
[+]串行端口COM1已激活。波特率:9600奇偶校验:无停止位:1
[+]->?0 {SY} 13!写入端口。((这就是它进入无限循环的地方,读取“”))
编辑:读取代码:
const int bytesToRead = 1; //I byte pr læsning
char buffer[bytesToRead + 1] = { 0 }; //Bufferen til data
DWORD dwBytesRead = 0; //Antal bytes læst
string store; //Store - den vi gemmer den samlede streng i
bool end = false; //Kontrolvariabel til whileloop.
while (end == false)
{
if (ReadFile(hserial, buffer, bytesToRead, &dwBytesRead, NULL))
/*Readfile læser fra interfacet vha. hserial som vi oprettede i constructoren*/
{
if (buffer[0] == '?') //Da protokollen slutter en modtaget streng med "?", sætter vi end til true
{ //Hvis denne læses.
end = true;
}
store += buffer[0];
}
else
{
if (debug_ != LOW)
{
cout << "[-] Read fail" << endl; //Hvis readfile returnerer false, så er der sket en fejl.
}
end = true;
}
}
if (debug_ == HIGH)
{
cout << "[+] Recieved: " << store << endl; //I forbindelse med debug, er det muligt at få udsrkevet det man fik ind.
}
recentIn = store; //RecentIN brugES i andre funktioner
if (verify()) //Som f.eks. her, hvor vi verificerer dataen
{
if (debug_ == HIGH)
{
cout << "[+] Verification success!" << endl;
}
return convertRecData(store);
}
else
{
if (debug_ != LOW)
{
cout << "[-] Verification failed." << endl;
}
vector <string> null; //Returnerer en string uden data i, hvis der er sket en fejl.
return null;
}
您从不叫SetCommState
。
我不确定您的函数setBaud
,setParity
等来自哪里,但是我看不到它们如何才能真正修改串行端口,因为它们无法访问通讯设备的句柄。
ReadFile()可以返回成功,即使读取零字节也是如此。使用dwBytesRead查找接收到的字符的实际数量。
while (ReadFile(hserial, buffer, 1, &dwBytesRead, NULL))
{
if (dwBytesRead != 0)
{
store += buffer[0];
if (buffer[0] == '?')
{
end = true;
break;
}
}
}
在PC和包含CH340的arduino纳米克隆之间存在类似的问题。这篇文章是唯一一个很好地描述了我的问题的帖子。我通过关闭DTR(数据终端就绪)和RTS(请求发送)流控制解决了该问题,通常在(重新)启动PC或插入arduino之后激活该流控制。我在DCB
的文档中找到了对此参数的描述我知道他的职位很老,但也许我可以用这个想法/解决方案来帮助其他人。