⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tserial_event.cpp

📁 串口通讯驱动
💻 CPP
📖 第 1 页 / 共 2 页
字号:



/* ------------------------------------------------------------------------ --
--                                                                          --
--                        PC serial port connection object                  --
--                           for  event-driven programs                     --
--                                                                          --
--                                                                          --
m                         --
--                                                                          --
--                                                                          --
--                                                                          --
-- ------------------------------------------------------------------------ --
--                                                                          --
--  Filename : Tserial_event.cpp                                            --
--  Author   : Wang Bin                                            --
--  Created  : 3rd Aug 2007                                           --
--  Modified :                                             --
--  Plateform: Windows 95, 98, NT, 2000 (Win32)                             --
-- ------------------------------------------------------------------------ --

-- ------------------------------------------------------------------------ --
--                                                                          --
--    Note to Visual C++ users:  Don't forget to compile with the           --
--     "Multithreaded" option in your project settings                      --
--                                                                          --
--         See   Project settings                                           --
--                   |                                                      --
--                   *--- C/C++                                             --
--                          |                                               --
--                          *--- Code generation                            --
--                                       |                                  --
--                                       *---- Use run-time library         --
--                                                     |                    --
--                                                     *---- Multithreaded  --
--                                                                          --
--                                                                          --
--                                                                          --
-- ------------------------------------------------------------------------ */




/* ---------------------------------------------------------------------- */

#define STRICT
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <process.h>
#include <conio.h>
#include <windows.h>


#include "Tserial_event.h"

#define SIG_POWER_DOWN     0
#define SIG_READER         1
#define SIG_READ_DONE      2    // data received has been read
#define SIG_WRITER         3
#define SIG_DATA_TO_TX     4    // data waiting to be sent
#define SIG_MODEM_EVENTS   5
#define SIG_MODEM_CHECKED  6

void Tserial_event_thread_start(void *arg);

typedef unsigned (WINAPI *PBEGINTHREADEX_THREADFUNC) (LPVOID lpThreadParameter);
typedef unsigned *PBEGINTHREADEX_THREADID;

/* ---------------------------------------------------------------------- */
/* ---------------------  Tserial_event_thread_start  ------------------- */
/* ---------------------------------------------------------------------- */
/**
    This function is not part of the Tserial_event object. It is simply used
    to start the thread from an external point of the object.
*/
void Tserial_event_thread_start(void *arg)
{
    class Tserial_event *serial_unit;

    serial_unit = (Tserial_event *) arg;
    
    if (serial_unit!=0)
        serial_unit->run();
}

/* -------------------------------------------------------------------- */
/* -------------------------    Tserial_event ------------------------- */
/* -------------------------------------------------------------------- */
Tserial_event::Tserial_event()
{
    int i;

    ready            = false;
    parityMode       = SERIAL_PARITY_NONE;
    port[0]          = 0;
    rate             = 0;
    threadid         = 0;
    serial_handle    = INVALID_HANDLE_VALUE;
    tx_in_progress   = 0;
    rx_in_progress   = 0;
    max_rx_size      = 1;
    tx_size          = 0;
    received_size    = 0;
    check_modem      = false;

    manager          = 0;

    /* -------------------------------------------------------------- */
    // creating Events for the different sources
    for (i=0; i<SERIAL_SIGNAL_NBR; i++)
    {
        if ((i==SIG_READER) || (i==SIG_WRITER) || (i==SIG_MODEM_EVENTS))
            serial_events[i] = CreateEvent(NULL, TRUE, FALSE, NULL);  // Manual Reset
        else
            serial_events[i] = CreateEvent(NULL, FALSE, FALSE, NULL); // Auto reset
    }
}

/* -------------------------------------------------------------------- */
/* --------------------------    ~Tserial_event ----------------------- */
/* -------------------------------------------------------------------- */
Tserial_event::~Tserial_event()
{
    int i;

    /* -------------------------------------------------------- */
    for (i=0; i<SERIAL_SIGNAL_NBR; i++)         // deleting the events
    {
        if (serial_events[i]!=INVALID_HANDLE_VALUE)
            CloseHandle(serial_events[i]);
        serial_events[i] = INVALID_HANDLE_VALUE;
    }

    if (serial_handle!=INVALID_HANDLE_VALUE)
        CloseHandle(serial_handle);
    serial_handle = INVALID_HANDLE_VALUE;
}
/* -------------------------------------------------------------------- */
/* --------------------------    disconnect   ------------------------- */
/* -------------------------------------------------------------------- */
void Tserial_event::disconnect(void)
{
    ready = false;
    SetEvent(serial_events[SIG_POWER_DOWN]);
}
/* -------------------------------------------------------------------- */
/* --------------------------    connect      ------------------------- */
/* -------------------------------------------------------------------- */
/**
     Serial port, file and overlapped structures initialization
*/
int  Tserial_event::connect (char *port_arg, int  rate_arg,  int parity_arg,
                             char ByteSize , bool modem_events)
{
    int  erreur;
    DCB  dcb;
    int  i;
    COMMTIMEOUTS cto = { 0, 0, 0, 0, 0 };

    /* --------------------------------------------- */
    if (serial_handle!=INVALID_HANDLE_VALUE)
        CloseHandle(serial_handle);
    serial_handle = INVALID_HANDLE_VALUE;

    if (port_arg!=0)
    {
        strncpy(port, port_arg, 10);
        rate        = rate_arg;
        parityMode  = parity_arg;
        check_modem = modem_events;

        erreur      = 0;
        ZeroMemory(&ovReader   ,sizeof(ovReader)   );  // clearing the overlapped
        ZeroMemory(&ovWriter   ,sizeof(ovWriter)   );
        ZeroMemory(&ovWaitEvent,sizeof(ovWaitEvent));
        memset(&dcb,0,sizeof(dcb));

        /* -------------------------------------------------------------------- */
        // set DCB to configure the serial port
        dcb.DCBlength       = sizeof(dcb);                   
        
        /* ---------- Serial Port Config ------- */
        dcb.BaudRate        = rate;

        switch(parityMode)
        {
            case SERIAL_PARITY_NONE:
                            dcb.Parity      = NOPARITY;
                            dcb.fParity     = 0;
                            break;
            case SERIAL_PARITY_EVEN:
                            dcb.Parity      = EVENPARITY;
                            dcb.fParity     = 1;
                            break;
            case SERIAL_PARITY_ODD:
                            dcb.Parity      = ODDPARITY;
                            dcb.fParity     = 1;
                            break;
        }


        dcb.StopBits        = ONESTOPBIT;
        dcb.ByteSize        = (BYTE) ByteSize;

        dcb.fOutxCtsFlow    = 0;
        dcb.fOutxDsrFlow    = 0;
        dcb.fDtrControl     = DTR_CONTROL_DISABLE;
        dcb.fDsrSensitivity = 0;
        dcb.fRtsControl     = RTS_CONTROL_DISABLE;
        dcb.fOutX           = 0;
        dcb.fInX            = 0;
        
        /* ----------------- misc parameters ----- */
        dcb.fErrorChar      = 0;
        dcb.fBinary         = 1;
        dcb.fNull           = 0;
        dcb.fAbortOnError   = 0;
        dcb.wReserved       = 0;
        dcb.XonLim          = 2;
        dcb.XoffLim         = 4;
        dcb.XonChar         = 0x13;
        dcb.XoffChar        = 0x19;
        dcb.EvtChar         = 0;
        
        /* -------------------------------------------------------------------- */
        serial_handle    = CreateFile(port, GENERIC_READ | GENERIC_WRITE,
                   0, NULL, OPEN_EXISTING,FILE_FLAG_OVERLAPPED,NULL);
                   // opening serial port

        ovReader.hEvent    = serial_events[SIG_READER];
        ovWriter.hEvent    = serial_events[SIG_WRITER];
        ovWaitEvent.hEvent = serial_events[SIG_MODEM_EVENTS];

        if (serial_handle    != INVALID_HANDLE_VALUE)
        {
            if (check_modem)
            {
                if(!SetCommMask(serial_handle, EV_RING | EV_RLSD))
                    erreur = 1;
            }
            else
            {
                if(!SetCommMask(serial_handle, 0))
                    erreur = 1;
            }

                
            // set timeouts
            if(!SetCommTimeouts(serial_handle,&cto))
                erreur = 2;

            // set DCB
            if(!SetCommState(serial_handle,&dcb))
                erreur = 4;
        }
        else
            erreur = 8;
    }
    else
        erreur = 16;


    /* --------------------------------------------- */
    for (i=0; i<SERIAL_SIGNAL_NBR; i++)
    {
        if (serial_events[i]==INVALID_HANDLE_VALUE)
            erreur = 32;
    }

    /* --------------------------------------------- */
    if (erreur!=0)
    {
        CloseHandle(serial_handle);
        serial_handle = INVALID_HANDLE_VALUE;
    }
    else
    {
        // start thread
        _beginthreadex(NULL,0,(PBEGINTHREADEX_THREADFUNC) Tserial_event_thread_start,
                  (void *) this, 0, &threadid);
    }

    /* --------------------------------------------- */
    return(erreur);
}
/* -------------------------------------------------------------------- */
/* ---------------------           setManager     --------------------- */
/* -------------------------------------------------------------------- */
void         Tserial_event::setManager(type_myCallBack manager_arg)
{
        manager = manager_arg;
}
/* -------------------------------------------------------------------- */
/* ---------------------           setRxSize      --------------------- */
/* -------------------------------------------------------------------- */
void         Tserial_event::setRxSize(int size)
{
        max_rx_size = size;
        if (max_rx_size>SERIAL_MAX_RX)
            max_rx_size = SERIAL_MAX_RX;
}
/* -------------------------------------------------------------------- */
/* ---------------------           setManager     --------------------- */
/* -------------------------------------------------------------------- */
char *      Tserial_event::getDataInBuffer(void)
{
    return(rxBuffer);
}
/* -------------------------------------------------------------------- */
/* ---------------------           setManager     --------------------- */
/* -------------------------------------------------------------------- */
int      Tserial_event::getDataInSize(void)
{
    return(received_size);
}
/* -------------------------------------------------------------------- */
/* ---------------------           setManager     --------------------- */
/* -------------------------------------------------------------------- */
void   Tserial_event::dataHasBeenRead(void)
{
    SetEvent(serial_events[SIG_READ_DONE]);
}
/* -------------------------------------------------------------------- */
/* -----------------------   getNbrOfBytes  --------------------------- */
/* -------------------------------------------------------------------- */
int Tserial_event::getNbrOfBytes    (void)
{
    struct _COMSTAT status;
    int             n;
    unsigned long   etat;

    n = 0;

    if (serial_handle!=INVALID_HANDLE_VALUE)
    {
        ClearCommError(serial_handle, &etat, &status);
        n = status.cbInQue;
    }
    return(n);
}
/* -------------------------------------------------------------------- */
/* --------------------------    sendData     ------------------------- */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -