Inisialisasi komunikasi port serial

Pada saat ini kami mencoba membuat antarmuka untuk komunikasi serial, agar dapat berkomunikasi dengan mikroprosesor.

Sebenarnya - semuanya berfungsi dengan baik. Hampir! Untuk dapat berkomunikasi dengan pengontrol kami, kami perlu melakukan sinkronisasi dengannya. Untuk melakukan ini, kita menulis string: "?0{SY}13!", dan pengontrol kemudian harus membalas dengan "!0{SY}F5?" untuk menerima permintaan sinkronisasi. Untuk melakukan ini, kita menggunakan fungsi writeData (yang berfungsi - kita mengetahuinya dengan menggunakan echo), dan setelah itu kita menggunakan readData untuk membaca jawabannya. Masalahnya adalah, karena alasan tertentu, ia tidak dapat membaca apa pun. Meskipun ia mengembalikan 1 untuk sukses, karakter yang dibacanya selalu " " (tidak ada).

Sekarang sampai pada bagian yang aneh - jika kita menggunakan program terminal eksternal untuk menginisialisasi port (seperti dempul), dan kemudian menutup program, maka semuanya berfungsi dengan baik. Ia menerima permintaan sinkronisasi, jawaban (dan kita dapat membacanya), dan kemudian kita dapat melakukan semua yang kita inginkan. Namun kecuali kita menggunakan program eksternal untuk menginisialisasi port, itu tidak akan berhasil.

Konstruktor untuk menginisialisasi antarmuka terlihat seperti ini:

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;
    }
}

Ini seharusnya berhasil - saya benar-benar tidak tahu mengapa tidak. Tidak ada kesalahan yang dikembalikan, saya sudah mencoba BANYAK pencarian kesalahan beberapa hari terakhir, saya mencoba batas waktu, saya mencoba cara lain untuk membangunnya, tetapi semuanya bermuara pada masalah yang sama.

Mengapa ini tidak menginisialisasi port?

Sunting:

Output ketika mencoba melakukan sinkronisasi: Tidak dapat memposting gambar karena kurangnya reputasi. meskipun hasilnya sebagai berikut:

[+] Port serial COM1 telah diaktifkan. Tingkat baud: 9600 Paritas: TIDAK ADA Bit berhenti: 1

[+] -> ?0{SY}13! ditulis ke port. ((Dan di sinilah ia masuk ke pembacaan loop tak terbatas " "))

EDIT: kode untuk dibaca:

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;
}

person Benjamin Larsen    schedule 11.12.2014    source sumber
comment
Apa yang dihasilkan ketika port diinisialisasi? Seperti pada baris [+] Serial Port....   -  person Greycon    schedule 11.12.2014
comment
dapatkah Anda memberikan kode readData()?   -  person alexm    schedule 11.12.2014
comment
@Greycon - Saya telah mengedit postingan asli untuk memasukkan hasilnya.   -  person Benjamin Larsen    schedule 11.12.2014
comment
@alexm Saya telah mengedit postingan.   -  person Benjamin Larsen    schedule 11.12.2014
comment
Anda mengandalkan kebaikan orang asing untuk menginisialisasi DCB untuk Anda. Pengaturan jabat tangan bukanlah hal yang sepele. Mudah untuk di-debug hanya dengan melihat DCB yang dikembalikan oleh GetCommState() btw.   -  person Hans Passant    schedule 11.12.2014
comment
@HansPassant Saya mengerti maksud Anda. Terima kasih telah memperhatikan.   -  person Benjamin Larsen    schedule 11.12.2014
comment
Ya, metode setHandshake() sama sekali tidak ada. Itu sesuai dengan keluhannya.   -  person Hans Passant    schedule 11.12.2014
comment
@HansPassant Saya mencoba mengedit kode `dcbParms.BaudRate = 9600; dcbParms.Parity = NOPARITAS; dcbParms.StopBits = 1; SetCommState(hserial, &dcbParms);` meskipun itu tidak berpengaruh pada program. Nilai standar untuk sisanya seharusnya baik-baik saja. '   -  person Benjamin Larsen    schedule 11.12.2014
comment
Baca postingan ini untuk mengetahui latar belakang tentang arti jabat tangan.   -  person Hans Passant    schedule 11.12.2014
comment
Saya memiliki masalah yang sama, meskipun saya menelepon SetCommState. Tautan yang diposting oleh Hans Passant membantu saya melihat masalahnya. Dalam kasus saya itu adalah DtrControl. Terima kasih banyak !!!   -  person BaldDude    schedule 14.11.2018


Jawaban (3)


Anda tidak pernah menelepon SetCommState.

Saya tidak yakin dari mana fungsi setBaud,setParity dll. Anda berasal, tetapi saya tidak dapat melihat bagaimana fungsi tersebut sebenarnya dapat mengubah port serial, karena mereka tidak memiliki akses ke pegangan perangkat komunikasi.

person Roddy    schedule 11.12.2014
comment
Saya mengerti maksud Anda. Fungsi GetCommState adalah satu-satunya yang menerima ini. SetBaud dan seterusnya menggunakan: dcbParms.BaudRate = CBR_110. Saya akan mencoba menggunakan SetCommState. - person Benjamin Larsen; 11.12.2014
comment
..Meskipun memiliki efek yang sama menggunakan SetCommState setelah meneruskan data ke struktur dcb :-( - person Benjamin Larsen; 11.12.2014
comment
@BenjaminLarsen Anda seharusnya dapat memeriksa apakah port telah dikonfigurasi dengan benar dengan mengetikkan MODE COMn: ke dalam prompt perintah. Atau, panggil saja GetCommState untuk kedua kalinya (ke DCB berbeda) dan bandingkan keduanya. Selain itu, jika kode Anda berfungsi setelah PUTTY dijalankan, bandingkan DCB yang Anda terima setelah itu dengan DCB setelah pengaturan Anda dijalankan. - person Roddy; 12.12.2014
comment
Oh, dan satu hal lagi: Bidang StopBits di DCB sangat non-intuitif (0= 1 stop bit, 1=1.5 stop bits, 2=2). Anda harus menggunakan dcbParms.StopBits = ONESTOPBIT; - person Roddy; 12.12.2014

ReadFile() dapat mengembalikan kesuksesan bahkan ketika nol byte dibaca. Gunakan dwBytesRead untuk menemukan jumlah sebenarnya karakter yang diterima.

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

       if (buffer[0] == '?')  
       {                               
           end = true;     
           break;
       }
    }
}
person alexm    schedule 11.12.2014
comment
Ya, saya sadar akan hal itu. Saya mencoba mengeluarkan semua yang ada di buffer. Semua kosong. Masalahnya mungkin terletak pada konstruktor - sepertinya tidak bisa berfungsi. - person Benjamin Larsen; 11.12.2014
comment
@BenjaminLarsen Jadi dwBytesRead bukan nol kan? - person alexm; 11.12.2014

Punya masalah serupa antara PC dan klon Arduino nano termasuk CH340. Posting ini adalah satu-satunya yang menggambarkan masalah saya dengan sangat baik. Saya menyelesaikannya dengan mematikan kontrol aliran DTR (data-terminal-ready) dan RTS (request-to-send), yang biasanya diaktifkan setelah (kembali) menghidupkan PC atau mencolokkan Arduino. Saya menemukan deskripsi parameter ini di dokumentasi DCB

Saya tahu postingannya sudah sangat lama tetapi mungkin saya dapat membantu orang lain dengan ide/solusi ini.

person DGO    schedule 07.06.2020
comment
Ah!! Ini mungkin masalah saya juga! Terima kasih! stackoverflow.com/questions/64929987/ - person Jimmy Westberg; 27.11.2020