Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

[WINAPI][C++] Program komunikujący się po RS232

Ostatnio zmodyfikowano 2014-08-31 12:09
Autor Wiadomość
1aam2am1
» 2014-08-30 22:09:31
To chyba jest WINAPI struktura COM ma wszystko co potrzebujesz jest tak chyba zabezpieczenie abyś nie próbował wczytać danych gdy ich niema, zapobiegnie to blokadzie programu.
P-116420
krzysztof.kolski
Temat założony przez niniejszego użytkownika
» 2014-08-30 22:34:56
Acha , dzięki - zabieram się do analizowania.
Zmyliło mnie takie ładne opakowanie WINAPI w tą całą obiektowość.
P-116424
krzysztof.kolski
Temat założony przez niniejszego użytkownika
» 2014-08-30 22:39:10
Niestety nie kompiluje mi się, zawaliła mnie masa błędów:

>------ Build started: Project: sfera, Configuration: Release Win32 ------
1>  sphere.cpp
1>sphere.cpp(2): error C2864: 'rgbf::number' : only static const integral data members can be initialized within a class
1>sphere.cpp(3): error C2864: 'rgbf::rgbnumber' : only static const integral data members can be initialized within a class
1>sphere.cpp(4): error C2059: syntax error : '{'
1>sphere.cpp(4): error C2334: unexpected token(s) preceding '{'; skipping apparent function body
1>sphere.cpp(5): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>sphere.cpp(5): error C2146: syntax error : missing ';' before identifier 'value'
1>sphere.cpp(5): error C2059: syntax error : '{'
1>sphere.cpp(5): error C2334: unexpected token(s) preceding '{'; skipping apparent function body
1>sphere.cpp(7): error C2864: 'rgbf::bluetooth' : only static const integral data members can be initialized within a class
1>sphere.cpp(38): error C2039: 'string' : is not a member of 'std'
1>sphere.cpp(38): error C2061: syntax error : identifier 'string'
1>sphere.cpp(11): error C2065: 'value' : undeclared identifier
1>sphere.cpp(16): error C2039: 'value' : is not a member of 'rgbf'
1>          sphere.cpp(1) : see declaration of 'rgbf'
1>sphere.cpp(16): error C2039: 'value' : is not a member of 'rgbf'
1>          sphere.cpp(1) : see declaration of 'rgbf'
1>sphere.cpp(17): error C2039: 'value' : is not a member of 'rgbf'
1>          sphere.cpp(1) : see declaration of 'rgbf'
1>sphere.cpp(17): error C2039: 'value' : is not a member of 'rgbf'
1>          sphere.cpp(1) : see declaration of 'rgbf'
1>sphere.cpp(18): error C2039: 'value' : is not a member of 'rgbf'
1>          sphere.cpp(1) : see declaration of 'rgbf'
1>sphere.cpp(18): error C2039: 'value' : is not a member of 'rgbf'
1>          sphere.cpp(1) : see declaration of 'rgbf'
1>sphere.cpp(19): error C2039: 'value' : is not a member of 'rgbf'
1>          sphere.cpp(1) : see declaration of 'rgbf'
1>sphere.cpp(19): error C2039: 'value' : is not a member of 'rgbf'
1>          sphere.cpp(1) : see declaration of 'rgbf'
1>sphere.cpp(26): error C2039: 'value' : is not a member of 'rgbf'
1>          sphere.cpp(1) : see declaration of 'rgbf'
1>sphere.cpp(26): error C2039: 'value' : is not a member of 'rgbf'
1>          sphere.cpp(1) : see declaration of 'rgbf'
1>sphere.cpp(33): error C2039: 'value' : is not a member of 'rgbf'
1>          sphere.cpp(1) : see declaration of 'rgbf'
1>sphere.cpp(33): error C2039: 'value' : is not a member of 'rgbf'
1>          sphere.cpp(1) : see declaration of 'rgbf'
1>sphere.cpp(39): error C2065: 'hex' : undeclared identifier
1>sphere.cpp(39): error C2228: left of '.size' must have class/struct/union
1>          type is ''unknown-type''
1>sphere.cpp(40): error C2065: 'hex' : undeclared identifier
1>sphere.cpp(42): error C2065: 'hex' : undeclared identifier
1>sphere.cpp(42): error C2065: 'hex' : undeclared identifier
1>sphere.cpp(42): error C2065: 'hex' : undeclared identifier
1>sphere.cpp(42): error C2065: 'hex' : undeclared identifier
1>sphere.cpp(42): error C2065: 'hex' : undeclared identifier
1>sphere.cpp(42): error C2065: 'hex' : undeclared identifier
1>sphere.cpp(55): error C2512: 'rgbf' : no appropriate default constructor available
1>sphere.cpp(57): error C3861: 'strtol': identifier not found
1>sphere.cpp(58): error C2039: 'value' : is not a member of 'rgbf'
1>          sphere.cpp(1) : see declaration of 'rgbf'
1>sphere.cpp(59): error C2039: 'value' : is not a member of 'rgbf'
1>          sphere.cpp(1) : see declaration of 'rgbf'
1>sphere.cpp(60): error C2039: 'value' : is not a member of 'rgbf'
1>          sphere.cpp(1) : see declaration of 'rgbf'
1>sphere.cpp(65): error C2660: 'rgbf::IsHex' : function does not take 1 arguments
1>sphere.cpp(83): error C2146: syntax error : missing ';' before identifier 'hCom'
1>sphere.cpp(83): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>sphere.cpp(83): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>sphere.cpp(84): error C2146: syntax error : missing ';' before identifier 'fSuccess_COM'
1>sphere.cpp(84): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>sphere.cpp(84): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>sphere.cpp(85): error C2146: syntax error : missing ';' before identifier 'statsread'
1>sphere.cpp(85): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>sphere.cpp(85): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>sphere.cpp(86): error C2146: syntax error : missing ';' before identifier 'RS_read'
1>sphere.cpp(86): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>sphere.cpp(86): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>sphere.cpp(87): error C2146: syntax error : missing ';' before identifier 'RS_send'
1>sphere.cpp(87): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>sphere.cpp(87): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>sphere.cpp(94): error C2039: 'map' : is not a member of 'std'
1>sphere.cpp(94): error C2143: syntax error : missing ';' before '<'
1>sphere.cpp(94): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>sphere.cpp(94): error C2039: 'string' : is not a member of 'std'
1>sphere.cpp(94): error C2238: unexpected token(s) preceding ';'
1>sphere.cpp(95): error C2039: 'map' : is not a member of 'std'
1>sphere.cpp(95): error C2143: syntax error : missing ';' before '<'
1>sphere.cpp(95): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>sphere.cpp(95): error C2238: unexpected token(s) preceding ';'
1>sphere.cpp(97): error C2061: syntax error : identifier 'HKEY'
1>sphere.cpp(149): error C2039: 'string' : is not a member of 'std'
1>sphere.cpp(149): error C2061: syntax error : identifier 'string'
1>sphere.cpp(98): error C2065: 'LONG' : undeclared identifier
1>sphere.cpp(98): error C2146: syntax error : missing ';' before identifier 'result'
1>sphere.cpp(98): error C2065: 'result' : undeclared identifier
1>sphere.cpp(99): error C2065: 'com' : undeclared identifier
1>sphere.cpp(99): error C2228: left of '.clear' must have class/struct/union
1>          type is ''unknown-type''
1>sphere.cpp(100): error C2065: 'jest' : undeclared identifier
1>sphere.cpp(100): error C2228: left of '.clear' must have class/struct/union
1>          type is ''unknown-type''
1>sphere.cpp(102): error C2039: 'list' : is not a member of 'std'
1>sphere.cpp(102): error C2065: 'list' : undeclared identifier
1>sphere.cpp(102): error C2065: 'HKEY' : undeclared identifier
1>sphere.cpp(102): error C2065: 'klucze' : undeclared identifier
1>sphere.cpp(106): error C2065: 'lpSubKey' : undeclared identifier
1>sphere.cpp(106): fatal error C1903: unable to recover from previous error(s); stopping compilation
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
P-116426
1aam2am1
» 2014-08-30 22:43:37
Tak jest to jeden plik z mojego bardzo starego projektu do komunikacji z oświetleniem led (byłem wtedy głupi i niemądry, nie umiałem dobrze dzielić na pliki) więc to się nie skompiluje musisz wyciągnąć fragmenty które potrzebujesz. Jak jakiejś funkcji nie znasz to masz google.

Edit:
C/C++
#include <iostream>
#include <windows.h>
using namespace std;


class COM {
private:
    HANDLE hCom; //uchwyt portu
    BOOL fSuccess_COM; //flaga pomocnicza bdw
    COMSTAT statsread; //status
    DWORD RS_read; //ilosc bitow wyslanych
    DWORD RS_send;
   
public:
    std::string poloncz;
    std::string polonczony;
   
    bool start_COM( std::string port ) {
        DCB dcb; //konfiguracja portu
       
        if( !polonczony.empty() ) {
            TerminateThread( hCom, 0 );
            CloseHandle( hCom );
        }
        polonczony = "";
       
        hCom = CreateFile(( "\\\\.\\" + port ).c_str(), GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL ); //otwieranie portu
       
        if( hCom == INVALID_HANDLE_VALUE )
        {
            return 0;
        }
       
        //pobranie aktualnych ustawien portu
        fSuccess_COM = GetCommState( hCom, & dcb );
        if( !fSuccess_COM )
        {
            return 0;
        }
       
        //ustawienie naszej konfiguracji
        dcb.BaudRate = CBR_9600; // predkosc transmisji //zmienic na 38400
        dcb.ByteSize = 8; // ilosc bitow danych
        dcb.Parity = NOPARITY; // brak bitu parzystosci
        dcb.StopBits = ONESTOPBIT; // jeden bity stopu
        dcb.fDtrControl = DTR_CONTROL_DISABLE; //Kontrola linii DTR: DTR_CONTROL_DISABLE (nieaktywny), DTR_CONTROL_ENABLE (aktywny)
        dcb.fRtsControl = RTS_CONTROL_DISABLE; //Kontrola linii RTS: RTS_CONTROL_DISABLE (nieaktywny), RTS_CONTROL_ENABLE (aktywny)
       
        fSuccess_COM = SetCommState( hCom, & dcb );
        if( !fSuccess_COM )
        {
            return 0;
        }
       
        this->polonczony = port;
        return 1; //koniec ustawienia portu
    }
   
    void close_COM() {
        TerminateThread( hCom, 0 ); //zamyka port com
        CloseHandle( hCom );
        polonczony = "";
    }
   
    void Write( PCVOID informacja, DWORD ile ) {
        fSuccess_COM = WriteFile( hCom, informacja, ile, & RS_send, 0 );
        if( !fSuccess_COM ) {
            this->close_COM();
            std::cout << "nie";
        }
        std::cout << "tak";
    }
   
    void send_color_map_COM( std::string informacja ) {
        if( !polonczony.empty() ) {
            COMSTAT statssend; //status
            Write( informacja.c_str(), informacja.size() );
            ClearCommError( hCom, NULL, & statssend );
            while( statssend.cbOutQue != 0 ) {
                ClearCommError( hCom, NULL, & statssend ); //sprawdza status
            }
            informacja = "";
        }
    }
   
    bool read_color_map_COM( std::string & informacja ) {
        if( !polonczony.empty() ) {
            static std::string informacja;
            char read_char_COM;
            COMSTAT statsread; //status
            ClearCommError( hCom, NULL, & statsread ); //sprawdza status
            if( statsread.cbInQue != 0 ) {
                ReadFile( hCom, & read_char_COM, 1, & RS_read, 0 );
                if( read_char_COM != '\n' ) {
                    informacja += read_char_COM;
                } else {
                    if( strcmp( informacja.c_str(), "read" ) == 0 ) {
                       
                        informacja = "";
                        return false;
                    }
                    return true;
                }
            }
        }
        return false;
    }
};
Wybrane funkcje kompiluje się.
P-116429
krzysztof.kolski
Temat założony przez niniejszego użytkownika
» 2014-08-30 23:06:09
dalej mi się nie kompiluje, niestety
P-116434
1aam2am1
» 2014-08-30 23:19:03
Jakie błędy i czy masz int main()
P-116435
krzysztof.kolski
Temat założony przez niniejszego użytkownika
» 2014-08-30 23:51:27
ok, jednak mój program działa, problem nie leżał w RS232 tylko gdzieś indziej.

Program już ładnie wysyła dane, tylko teraz chciałbym użyć OVERLAPPED do odbioru, jak to zrobić?
P-116437
krzysztof.kolski
Temat założony przez niniejszego użytkownika
» 2014-08-31 00:54:46
Program teraz wygląda tak:
 
C/C++
#include "stdafx.h"
#include <windows.h>

#define IDC_MAIN_BUTTON 101 // Button identifier
#define IDC_MAIN_EDIT 102 // Edit box identifier
#define IDC_MAIN_EDIT2 103 // Edit box identifier
#define IDC_MAIN_EDIT3 104 // Edit box identifier
#define IDC_MAIN_EDIT4 105 // Edit box identifier
HWND hEdit, hEdit2, hEdit3, hEdit4;
DCB dcb;
HANDLE hNumPort;
char lpBuffor_read[ 33 ], lpBuffor_write[ 33 ];
DWORD RS_ile;
char tabw[ 4 ], tabr;
LPSTR buf;
LRESULT CALLBACK WinProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam );
int dlugos;

int WINAPI WinMain( HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpCmdLine, int nShowCmd )
{
    WNDCLASSEX wClass;
    ZeroMemory( & wClass, sizeof( WNDCLASSEX ) );
    wClass.cbClsExtra = NULL;
    wClass.cbSize = sizeof( WNDCLASSEX );
    wClass.cbWndExtra = NULL;
    wClass.hbrBackground =( HBRUSH ) COLOR_WINDOW;
    wClass.hCursor = LoadCursor( NULL, IDC_ARROW );
    wClass.hIcon = NULL;
    wClass.hIconSm = NULL;
    wClass.hInstance = hInst;
    wClass.lpfnWndProc =( WNDPROC ) WinProc;
    wClass.lpszClassName = "Window Class";
    wClass.lpszMenuName = NULL;
    wClass.style = CS_HREDRAW | CS_VREDRAW;
   
    if( !RegisterClassEx( & wClass ) )
    {
        int nResult = GetLastError();
        MessageBox( NULL,
        "Window class creation failed\r\n",
        "Window Class Failed",
        MB_ICONERROR );
    }
   
    HWND hWnd = CreateWindowEx( NULL,
    "Window Class",
    "NOWE RS232 TEST (bajt 1,bajt 2,bajt 3,bajt 4)",
    WS_OVERLAPPEDWINDOW,
    200,
    200,
    640,
    480,
    NULL,
    NULL,
    hInst,
    NULL );
   
    if( !hWnd )
    {
        int nResult = GetLastError();
       
        MessageBox( NULL,
        "Window creation failed\r\n",
        "Window Creation Failed",
        MB_ICONERROR );
    }
   
    ShowWindow( hWnd, nShowCmd );
   
    MSG msg;
    ZeroMemory( & msg, sizeof( MSG ) );
   
    while( GetMessage( & msg, NULL, 0, 0 ) )
    {
       
        TranslateMessage( & msg );
        DispatchMessage( & msg );
    }
   
    return 0;
}

LRESULT CALLBACK WinProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam )
{
    switch( msg )
    {
    case WM_CREATE:
        {
            // Create an edit box
            hEdit = CreateWindowEx( WS_EX_CLIENTEDGE, "EDIT", "", WS_CHILD | WS_VISIBLE | ES_NUMBER, 50, 50, 25, 20, hWnd,( HMENU ) IDC_MAIN_EDIT, GetModuleHandle( NULL ), NULL );
            hEdit2 = CreateWindowEx( WS_EX_CLIENTEDGE, "EDIT", "", WS_CHILD | WS_VISIBLE | ES_NUMBER, 150, 50, 25, 20, hWnd,( HMENU ) IDC_MAIN_EDIT2, GetModuleHandle( NULL ), NULL );
            hEdit3 = CreateWindowEx( WS_EX_CLIENTEDGE, "EDIT", "", WS_CHILD | WS_VISIBLE | ES_NUMBER, 250, 50, 25, 20, hWnd,( HMENU ) IDC_MAIN_EDIT3, GetModuleHandle( NULL ), NULL );
            hEdit4 = CreateWindowEx( WS_EX_CLIENTEDGE, "EDIT", "", WS_CHILD | WS_VISIBLE | ES_NUMBER, 350, 50, 25, 20, hWnd,( HMENU ) IDC_MAIN_EDIT4, GetModuleHandle( NULL ), NULL );
           
            HGDIOBJ hfDefault = GetStockObject( DEFAULT_GUI_FONT );
            SendMessage( hEdit, WM_SETFONT,( WPARAM ) hfDefault, MAKELPARAM( FALSE, 0 ) );
            SendMessage( hEdit2, WM_SETFONT,( WPARAM ) hfDefault, MAKELPARAM( FALSE, 0 ) );
            SendMessage( hEdit3, WM_SETFONT,( WPARAM ) hfDefault, MAKELPARAM( FALSE, 0 ) );
            SendMessage( hEdit4, WM_SETFONT,( WPARAM ) hfDefault, MAKELPARAM( FALSE, 0 ) );
           
            // Create a push button
            HWND hWndButton = CreateWindowEx( NULL,
            "BUTTON",
            "Wyślij",
            WS_TABSTOP | WS_VISIBLE |
            WS_CHILD | BS_DEFPUSHBUTTON,
            50,
            220,
            100,
            24,
            hWnd,
            ( HMENU ) IDC_MAIN_BUTTON,
            GetModuleHandle( NULL ),
            NULL );
            SendMessage( hWndButton,
            WM_SETFONT,
            ( WPARAM ) hfDefault,
            MAKELPARAM( FALSE, 0 ) );
           
           
            hNumPort = CreateFile( "COM1", GENERIC_WRITE | GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL );
            dcb.DCBlength = sizeof( dcb );
           
            dcb.BaudRate = CBR_9600;
            dcb.fParity = FALSE;
            dcb.Parity = NOPARITY;
            dcb.StopBits = ONESTOPBIT;
            dcb.ByteSize = 8;
           
            dcb.fDtrControl = DTR_CONTROL_ENABLE;
            dcb.fRtsControl = DTR_CONTROL_ENABLE;
           
            dcb.fOutxCtsFlow = FALSE;
            dcb.fOutxDsrFlow = FALSE;
            dcb.fDsrSensitivity = FALSE;
            dcb.fAbortOnError = FALSE;
            dcb.fOutX = FALSE;
            dcb.fInX = FALSE;
            dcb.fErrorChar = FALSE;
            dcb.fNull = FALSE;
           
            if( SetCommState( hNumPort, & dcb ) ) MessageBox( NULL, "Udało się połączyć z portem COM1", "Inf", MB_ICONINFORMATION );
            else MessageBox( NULL, "Nie udało się połączyć z portem COM1", "Błąd", MB_ICONERROR );
           
        }
        break;
       
    case WM_COMMAND:
        switch( LOWORD( wParam ) )
        {
        case IDC_MAIN_BUTTON:
            {
                dlugos = GetWindowTextLength( hEdit ); buf =( LPSTR ) GlobalAlloc( GPTR, dlugos + 1 ); GetWindowText( hEdit, buf, dlugos + 1 ); tabw[ 0 ] = atoi( buf ) % 256;
                dlugos = GetWindowTextLength( hEdit2 ); buf =( LPSTR ) GlobalAlloc( GPTR, dlugos + 1 ); GetWindowText( hEdit2, buf, dlugos + 1 ); tabw[ 1 ] = atoi( buf ) % 256;
                dlugos = GetWindowTextLength( hEdit3 ); buf =( LPSTR ) GlobalAlloc( GPTR, dlugos + 1 ); GetWindowText( hEdit3, buf, dlugos + 1 ); tabw[ 2 ] = atoi( buf ) % 256;
                dlugos = GetWindowTextLength( hEdit4 ); buf =( LPSTR ) GlobalAlloc( GPTR, dlugos + 1 ); GetWindowText( hEdit4, buf, dlugos + 1 ); tabw[ 3 ] = atoi( buf ) % 256;
                WriteFile( hNumPort, tabw, 4, & RS_ile, 0 );
               
               
                MessageBox( NULL,
                "Danej zostały wysłane",
                "Information",
                MB_ICONINFORMATION );
            }
            break;
        }
        break;
       
    case WM_DESTROY:
        { CloseHandle( hNumPort );
            PostQuitMessage( 0 );
            return 0;
        }
        break;
    }
   
    return DefWindowProc( hWnd, msg, wParam, lParam );
}

I już nie mam problemu z wysyłaniem danych - program działa.
Teraz chciałbym dodać do tego odbierania danej.

Program który napisałem dla mikrokontrolera wysyła bajt o wartości 'A' kiedy wymuszę stan niski na określnym jego wejściu.
W terminalu znak A faktycznie się pokazuje.

Teraz potrzebuje prostą rzecz:
Mój program PC ma wyświetlić messagebox'a z informacją gdy przyjdzie do niego kod znaku A.
PYTANIA: 1)Jak dokłądnie działa ReadFile - chodzi mi o to czy jeśli nic nie odbiera to zatrzymuje wątek aż się dana pojawi?
         2)Jak najoptymalniej dodać powyższą funkcjonalność do mojego programu? Byłbym wdzięczny gdyby ktoś dodał :)
P-116439
1 « 2 » 3
Poprzednia strona Strona 2 z 3 Następna strona