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ść
krzysztof.kolski
Temat założony przez niniejszego użytkownika
[WINAPI][C++] Program komunikujący się po RS232
» 2014-08-30 20:16:40
Witam
Potrzebuje rozszerzyć swoją apliakcje o możliwość komunikowania się przez RS232. Docelowo program ma być uruchomiony na windows xp z fizycznym portem COM.

PARAMETRY:
prędkość 9600
brak bitu parzystości
1 bit stopu
wielkość ramki: 8 bitów
tryb transmisi: asynchroniczny
port COM1

Jeżeli chodzi o fizyczne urządzenie z którym się komunikuje to wszystko jest ok. Prototyp z mikrokontrolerem i przejściówką max232 wykonałem (odpowiednio) na płytce prototypowej i uniwersalnej.
Program w mikrokontrolerze jest napisany w C i kolejne bajty odczytuje jako:
- wartość PWM dla pierwszej diody
- wartość PWM dla drugiej diody
- wartość PWM dla trzeciej diody
- cztery najstarsze bity tego bajtu determinują stan 4 dodatkowych kontrolek
Dodatkowo mikrokontroler zwraca bajt 'A' przy pewnych zdarzeniach.

Użyłem programu putty do nawiązania transmisji, wszystko jest ok dlatego pozostał mi tylko problem w programie PC.

Próbowałem napisać taki program dla testu w którym mam 4 editboxy i przyciskiem wysyłam te 4 bajty po kolei, natomiast odebranie 'A' z mikrokontrolera powoduje pojawienie się messageboxa z informacją o tym.

To jest to co napisałem na podstawie porad z pewnego forum:
https://www.dropbox.com/s/abk2hap2ps5kei2/f.txt?dl=0
Niestety ten program nie uruchamia się prawidłowo (pod win xp nawet nie pojawiają się kontrolki, jakby się zawiesił).



PROŚBA: Proszę o jakikolwiek (prosty lub rozbudowany ale DZIAŁAJĄCY I KOMPILUJĄCY SIĘ) listing programu w C++ i winapi żebym mógł sobie spokojnie porównać gdzie robie błąd.
Pozdrawiam.
P-116405
pekfos
» 2014-08-30 20:35:43
Wstaw poprawnie kod.
P-116406
Monika90
» 2014-08-30 20:47:55
ReadFile wewnątrz pętli komunikatów będzie blokować wątek, ale tylko wtedy kiedy port uda się otworzyć, co nie powinno mieć miejsca bo to "\\\.\COM1", to nie jest prawidłowy literał napisowy w C++.
P-116407
krzysztof.kolski
Temat założony przez niniejszego użytkownika
» 2014-08-30 20:51:33
1. Gdzie dać ReadFile? Można stworzyć nowy wątek i bedzie ok?
2. Jak dodać kod tu u was na forum, między jakie klamry?
3. Co do "\\\.\COM1" to komentarz Sobiesława mnie skłonił do takiego zapisu, pod tym artykułem:
http://www.hotfix.pl/c-c++-winapi-komunikacja-poprzez-port-com-rs-232-a334.htm

Ale port chyba i tak się otwiera bo, tak jak napisałem, wygląda to tak jakby program się zawiesił.
P-116408
Monika90
» 2014-08-30 21:26:32
1. Wątek, a może overlapped IO?
2. [cpp]int main() { }[/cpp]
3. backslash w C++ musi być podwójny, czyli powinno być tak: "\\\\.\\COM1", czy kompilator nie wyswietlił Ci ostrzeżenia?

U mnie jest message box "Nie uda3o sie po31czya z portem COM1", potem wyświetla się okno główne.
A jak zmienię nazwę pliku na "\\\\.\\COM1", to jest "Uda3o sie po31czya z portem COM1" i program się zawiesza na ReadFile.
P-116411
krzysztof.kolski
Temat założony przez niniejszego użytkownika
» 2014-08-30 21:52:19
Oto kod którego używam:
 
C/C++
#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 ) )
    { //if(ReadFile(hNumPort, &tabr, 1, &RS_ile, 0)){char buf[256];wsprintf( buf,"Odebrano znak o kodzie %d",tabr);MessageBox(NULL,buf,"Inf",MB_ICONINFORMATION);}
       
        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 );
}


Porogram na laptopie z win7 zachowuje się tak jak tego się spodziewałem:
1. Informuje mnie przez messagebox że nie udało się połaczyć z portem COM
2. Wyświetla się okno programu z kontrolkami:
https://www.dropbox.com/s/h6y9bqceyust9xe/1.png?dl=0

Natomaist dziwnie zachowuje się na docelowym PC z win xp i portem COM:
1. Nie pojawia się messagebox z informacją (czy udało się połączyć czy też nie)
2. Pojawia się okno programu bez kontrolek (całe białe):
https://www.dropbox.com/s/jzjvrf0x3x7vzap/2.JPG?dl=0

Czym to może być spowodowane?
P-116414
1aam2am1
» 2014-08-30 21:56:34
Kiedyś się bawiłem portem COM (2 lata temu) daje link do dropboxa może coś z tego wyciągniesz
https://www.dropbox.com/s/tmwfxjta309t3lm/struct.cpp?dl=0
P-116415
krzysztof.kolski
Temat założony przez niniejszego użytkownika
» 2014-08-30 22:01:35
Dzięki :) ale to nie jest winapi.
Ja to potrzebuje koniecznie w WINAPI ponieważ komuniakcja po RS232 jest ostatnią rzeczą którą dodaje do programu.
P-116417
« 1 » 2 3
  Strona 1 z 3 Następna strona