📄 tserial_event.cpp
字号:
/* ------------------------------------------------------------------------ --
-- --
-- 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 + -