RS232 / Serielle Schnittstelle ansprechen



  • Hi an alle,

    Also, ich habe mir vor kurzem eine Relaiskarte gekauft und möchte diese jetzt über C++ und die Serielle Schnittstelle ansprechen. Ich hab Windows Vista.

    Nur wie kann ich 4 einzelne Bytes mit C++ über RS232 senden? Also das ich dafür WinApi brauche ist mir klar, aber alle Beispiel Codes ergaben bei mir nur irgendwelche Fehlermeldungen...

    Also es wär echt super toll wenn mir vllt jemand ein Code schicken könnte oder so 😃

    Danke im Vorraus 😉



  • Nochmal ein kurzes Ergänzungsbeispiel:

    CopyHANDLE hComm;
    hComm = CreateFile( gszPort,  
                        GENERIC_READ | GENERIC_WRITE, 
                        0, 
                        0, 
                        OPEN_EXISTING,
                        FILE_FLAG_OVERLAPPED,
                        0);
    if (hComm == INVALID_HANDLE_VALUE)
       // error opening port; abort
    

    Diesen Code zum Öffnen des ComPorts habe ich von der Microsoft seite. Es funktioniert bis auf den Ausdruck "gszPort". Da kommt immer eine Fehlermeldung das "gszPort" nicht festgelegt wurde oder so... Und so ähnlich läufts bei fast allen Codes die ich bis jetzt gefunden habe.. 😞

    mfg



  • lol



  • Daten senden ist einfach... empfangen schon etwas schwieriger... deshalb nimm lieber eine fertige Klasse:
    http://www.codeproject.com/KB/system/serial.aspx



  • Da bringt nix verstehen tu ich auch nix 😮



  • Ich habe mal hobbymässig ein EPROM-Programmiergerät zusammengelötet und die Software dazu geschrieben und habe dazu die serielle Schnittstelle angesprochen. Hier der wichtigste Ausschnitt ( ⚠ Achtung, der Quellcode ist von mir 🙂 ):

    static void UartCallback(HWND hwnd, BYTE *pData, DWORD length)
    {
        static const DWORD maxRetry = 3u;
        DWORD i = 0u;
        BOOL result = FALSE;
    
        for (i = 0u; i < maxRetry; ++i)
        {
            if (FALSE == result)
            {
                result = PostMessage(hwnd, WM_UART_RX_CALLBACK, (WPARAM)length, (LPARAM)pData);
    
                /* if posting failed, wait a bit before proceeding */
                if (FALSE == result)
                {
                    Sleep(100);
                }
            }
        }
    
        if ((FALSE == result) && (NULL != pData))
        {
            HeapFree(GetProcessHeap(), 0, pData);
        }
    
        return;
    }
    
    static VOID InitUartDCB(DCB *dcb)
    {
        dcb[0].DCBlength = sizeof(DCB);
        dcb[0].BaudRate = CBR_19200;
        dcb[0].fBinary = TRUE;
        dcb[0].fParity = FALSE;
        dcb[0].fOutxCtsFlow = FALSE;
        dcb[0].fOutxDsrFlow = FALSE;
        dcb[0].fDtrControl = DTR_CONTROL_DISABLE;
        dcb[0].fDsrSensitivity = FALSE;
        dcb[0].fTXContinueOnXoff = FALSE;
        dcb[0].fOutX = FALSE;
        dcb[0].fInX = FALSE;
        dcb[0].fErrorChar = FALSE;
        dcb[0].fNull = FALSE;
        dcb[0].fRtsControl = RTS_CONTROL_DISABLE;
        dcb[0].fAbortOnError = FALSE;
        dcb[0].fDummy2 = 0;
        dcb[0].wReserved = 0;
        dcb[0].XonLim = 0;
        dcb[0].XoffLim = 0;
        dcb[0].ByteSize = 8u;
        dcb[0].Parity = NOPARITY;
        dcb[0].StopBits = ONESTOPBIT;
        dcb[0].XonChar = 0;
        dcb[0].XoffChar = 0;
        dcb[0].ErrorChar = 0;
        dcb[0].EofChar = 0;
        dcb[0].EvtChar = 0;
        dcb[0].wReserved1 = 0;
    
        return;
    }
    
    static DWORD WINAPI UartThread(LPVOID pvoid)
    {
        TCHAR szPortName[256u] = { 0 };
        DCB dcb = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
        struct tThreadParams params = { 0, 0 };
        BYTE Command[2u];
        HANDLE hFileCom = INVALID_HANDLE_VALUE;
        MSG msg;
        enum tIdmItem PromCmd = IDM_BASE;
        BOOL done = FALSE;
        TCHAR* pMsg = NULL;
        BYTE* pDataToRead = NULL;
        DWORD cbDataToRead = 0;
        const DWORD comCnt = 7u;
        DWORD cbWritten = 0u;
        DWORD cbRead = 0;
    
        memcpy(&params, pvoid, sizeof(struct tThreadParams));
    
        PeekMessage(&msg, NULL, WM_USER, WM_USER, PM_NOREMOVE);
    
        SetEvent(params.event);
    
        /* generate COM device name */
        memset(&szPortName[0], 0, sizeof(szPortName));
        wsprintf(&szPortName[0], TEXT("\\\\.\\COM%u"), comCnt);
    
        /* try open it */
        hFileCom = CreateFile(
                &szPortName[0],
                (GENERIC_WRITE | GENERIC_READ),
                0,
                NULL,
                OPEN_EXISTING,
                0,
                NULL);
    
        if (INVALID_HANDLE_VALUE == hFileCom)
        {
            pMsg = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 256u);
            if (NULL != pMsg)
            {
                wsprintf(pMsg, TEXT("Could not open COM port %d."), comCnt);
                UartReport(params.hwnd, WM_USER_THREAD_MSG, TRUE, (LPARAM)pMsg);
            }
        }
        else
        {
            ZeroMemory(&dcb, sizeof(dcb));
            InitUartDCB(&dcb);
    
            if (0 == SetCommState(hFileCom, &dcb))
            {
                CloseHandle(hFileCom);
                hFileCom = INVALID_HANDLE_VALUE;
    
                pMsg = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 256u);
                if (NULL != pMsg)
                {
                    wsprintf(pMsg, TEXT("Could not initialize COM port %s."), &szPortName[0]);
                    UartReport(params.hwnd, WM_USER_THREAD_MSG, TRUE, (LPARAM)pMsg);
                }
            }
            else
            {
                /* SetCommState's return value is ok */
                pMsg = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 256u);
                if (NULL != pMsg)
                {
                    wsprintf(pMsg, TEXT("Initialization successfull for %s."), &szPortName[0]);
                    UartReport(params.hwnd, WM_USER_THREAD_MSG, FALSE, (LPARAM)pMsg);
                }
            }
        }
    
        while (FALSE == done)
        {
            if (FALSE == PeekMessage(&msg, (HWND)-1, 0, 0, PM_REMOVE))
            {
                /* no message available, do nothing */
                Sleep(10);
            }
            else
            {
                PromCmd = (enum tIdmItem)(msg.message);
    
                switch (PromCmd)
                {
                    case IDM_BASE:
                        {
                            break;
                        }
    
                    case IDM_PROM_READ_OUT:
                        {
                            Command[0u] = 0xAAu;
                            Command[1u] = 0xAAu;
    
                            if (FALSE == WriteFile(hFileCom, &Command[0], 2u, &cbWritten, NULL))
                            {
                                /* Failed writing command over UART */
                                /* Report error message */
                                pMsg = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 256u);
                                if (NULL != pMsg)
                                {
                                    wsprintf(pMsg, TEXT("Could not send READ OUT command."));
                                    UartReport(params.hwnd, WM_USER_THREAD_MSG, TRUE, (LPARAM)pMsg);
                                }
                                UartCallback(params.hwnd, NULL, 0u);
                            }
                            else
                            {
                                /* No errors */
                                cbDataToRead = (2u * 65536u);
                                pDataToRead = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, cbDataToRead);
    
                                if (NULL == pDataToRead)
                                {
                                    /* Failed allocating memory, try to report error message */
                                    pMsg = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 256u);
                                    if (NULL != pMsg)
                                    {
                                        wsprintf(pMsg, TEXT("Could not allocate memory."));
                                        UartReport(params.hwnd, WM_USER_THREAD_MSG, TRUE, (LPARAM)pMsg);
                                    }
                                    UartCallback(params.hwnd, NULL, 0u);
                                }
                                else
                                {
                                    /* Memory allocated, read data from UART */
                                    if (FALSE == ReadFile(hFileCom, pDataToRead, cbDataToRead, &cbRead, NULL))
                                    {
                                        /* Failed reading data from UART */
                                        pMsg = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 256u);
                                        if (NULL != pMsg)
                                        {
                                            wsprintf(pMsg, TEXT("Failed reading data from UART."));
                                            UartReport(params.hwnd, WM_USER_THREAD_MSG, TRUE, (LPARAM)pMsg);
                                        }
                                        UartCallback(params.hwnd, NULL, 0u);
                                        HeapFree(GetProcessHeap(), 0, pDataToRead);
                                    }
                                    else if (cbDataToRead != cbRead)
                                    {
                                        /* Not enough data received */
                                        pMsg = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 256u);
                                        if (NULL != pMsg)
                                        {
                                            wsprintf(pMsg, TEXT("Not enough data received: only %d bytes."), cbRead);
                                            UartReport(params.hwnd, WM_USER_THREAD_MSG, TRUE, (LPARAM)pMsg);
                                        }
                                        UartCallback(params.hwnd, NULL, 0u);
                                        HeapFree(GetProcessHeap(), 0, pDataToRead);
                                    }
                                    else
                                    {
                                        pMsg = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 256u);
                                        if (NULL != pMsg)
                                        {
                                            wsprintf(pMsg, TEXT("No errors. %d bytes received."), cbDataToRead);
                                            UartReport(params.hwnd, WM_USER_THREAD_MSG, FALSE, (LPARAM)pMsg);
                                        }
                                        /* No errors receiving data from UART */
                                        UartCallback(params.hwnd, pDataToRead, cbDataToRead);
                                    }
                                }
                            }
    
                            break;
                        }
    
                    case IDM_PROM_WRITE:
                        {
                            DWORD i = 0u;
                            const DWORD cbDataToWrite = (DWORD)msg.wParam;
                            const BYTE* const pDataToWrite = (BYTE*)msg.lParam;
    
                            Command[0u] = 0xBBu;
                            Command[1u] = 0xBBu;
    
                            if (FALSE == WriteFile(hFileCom, &Command[0], 2u, &cbWritten, NULL))
                            {
                                /* Failed writing command over UART */
                                /* Report error message */
                                pMsg = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 256u);
                                if (NULL != pMsg)
                                {
                                    wsprintf(pMsg, TEXT("Could not send WRITE command."));
                                    UartReport(params.hwnd, WM_USER_THREAD_MSG, TRUE, (LPARAM)pMsg);
                                }
                                UartCallback(params.hwnd, NULL, 0u);
                            }
                            else
                            {
                                /* No errors, send further data here */
    
                                /* This loop sends data (cbDataToWrite must be even) */
                                for (i = 0u; i < cbDataToWrite; i += 2u)
                                {
                                    if (FALSE == WriteFile(hFileCom, &pDataToWrite[i], 2u, &cbWritten, NULL))
                                    {
                                        /* Failed sending the bytes */
                                        pMsg = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 256u);
                                        if (NULL != pMsg)
                                        {
                                            wsprintf(pMsg, TEXT("Could not send data."));
                                            UartReport(params.hwnd, WM_USER_THREAD_MSG, TRUE, (LPARAM)pMsg);
                                        }
                                        UartCallback(params.hwnd, NULL, 0u);
                                        /* Break the loop */
                                        i = cbDataToWrite;
                                    }
                                    else
                                    {
    #if 1
                                        if (FALSE == FlushFileBuffers(hFileCom))
                                        {
                                            /* Failed flushing the bytes */
                                            pMsg = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 256u);
                                            if (NULL != pMsg)
                                            {
                                                wsprintf(pMsg, TEXT("Could not flush data."));
                                                UartReport(params.hwnd, WM_USER_THREAD_MSG, TRUE, (LPARAM)pMsg);
                                            }
                                            UartCallback(params.hwnd, NULL, 0u);
                                            /* Break the loop */
                                            i = cbDataToWrite;
                                        }
                                        else
                                        {
                                            Sleep(1u);
                                        }
    #endif
                                    }
    
                                    /* Report current state */
                                    if ((0u != i) && (0u == (i % 1024u)))
                                    {
                                        pMsg = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 256u);
                                        if (NULL != pMsg)
                                        {
                                            wsprintf(pMsg, TEXT("%d of %d Bytes sent..."), i, cbDataToWrite);
                                            UartReport(params.hwnd, WM_USER_THREAD_MSG, FALSE, (LPARAM)pMsg);
                                        }
                                    }
                                }
                            }
    
                            /* Report, sending data is ok */
                            pMsg = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 256u);
                            if (NULL != pMsg)
                            {
                                wsprintf(pMsg, TEXT("Ready. No errors."));
                                UartReport(params.hwnd, WM_USER_THREAD_MSG, FALSE, (LPARAM)pMsg);
                            }
                            UartCallback(params.hwnd, NULL, 0);
    
                            /* This thread is responsible for freeing the data buffer */
                            HeapFree(GetProcessHeap(), 0, (LPVOID)pDataToWrite);
    
                            break;
                        }
    
                    default:
                        {
                            /* Report error message */
                            pMsg = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 256u);
                            if (NULL != pMsg)
                            {
                                wsprintf(pMsg, TEXT("Unknown command received."));
                                UartReport(params.hwnd, WM_USER_THREAD_MSG, TRUE, (LPARAM)pMsg);
                            }
                            UartCallback(params.hwnd, NULL, 0u);
                            break;
                        }
                }
            }
        }
    
        CloseHandle(hFileCom);
    
        ExitThread(0);
    
        return 0;
    }
    

    Ich habe es als Thread laufen lassen und von der WndProc aus Kommandos an den Thread geschickt (mit PostThreadMessage) und der Thread hat mit UartCallback Ereignisse an den GUI Thread zurückgeschickt... vielleicht unnötig kompliziert - aber so hat es prima funktioniert 🙂


Log in to reply