繁体   English   中英

串口通讯初始化

[英]Serial port communication initialization

当时我们正在尝试为串行通信创建一个接口,以便能够与微处理器进行通信。

实际上 - 一切正常。 几乎! 为了能够与我们的控制器通信,我们需要与它同步。 为此,我们编写了一个字符串: "?0{SY}13!" ,然后控制器应该回复"!0{SY}F5?" 接受同步请求。 为此,我们使用了一个writeData函数(它可以工作 - 我们知道通过使用echo ),然后我们使用一个readData来读取答案。 问题是,由于某种原因,它不会读取任何内容。 虽然它返回1表示成功,但它读取的字符始终是" " (什么都没有)。

现在是奇怪的部分 - 如果我们使用外部终端程序来初始化端口(如 putty),然后关闭程序,那么一切正常。 它接受同步请求、回答(我们可以阅读它),然后我们可以做我们想做的一切。 但是除非我们使用外部程序来初始化端口,否则它不起作用。

初始化接口的构造函数如下所示:

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 奇偶校验:NONE 停止位: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

我不确定您的函数setBaudsetParity等来自哪里,但我看不到它们如何实际修改串行端口,因为它们无权访问通信设备的句柄。

即使读取零字节,ReadFile() 也可以返回成功。 使用 dwBytesRead 查找实际接收到的字符数。

while (ReadFile(hserial, buffer, 1, &dwBytesRead, NULL)) 
{
    if (dwBytesRead != 0)
    {
       store += buffer[0];

       if (buffer[0] == '?')  
       {                               
           end = true;     
           break;
       }
    }
}

在 PC 和包含 CH340 的 arduino nano 克隆之间有类似的问题。 这篇文章是唯一一篇很好地描述了我的问题的文章。 我通过关闭 DTR(数据终端就绪)和 RTS(请求发送)流控制来解决它,这通常在(重新)启动 PC 或插入 arduino 后激活。 我在DCB的文档中找到了对这个参数的描述

我知道 shis 的帖子很旧,但也许我可以用这个想法/解决方案帮助其他人。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM