📄 tty.cpp
字号:
// TTY.cpp: implementation of the CTTY class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "cge.h"
#include "TTY.h"
//#include "eppdll.h"
#include <conio.h>
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//extern CTTY MyTTY;
//BYTE M_COM_Return;
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
//DWORD FAR PASCAL CloseDialerProc( LPVOID lpData );
DWORD FAR PASCAL CommWatchProc( LPVOID lpData );
int NEAR ReadCommBlock( NPTTYINFO npTTYInfo, LPSTR lpszBlock, int nMaxLength );
//BOOL NEAR WriteCommBlock( NPTTYINFO npTTYInfo, BYTE *lpByte , DWORD dwBytesToWrite, DWORD *dwBytesWritten);
BOOL NEAR WriteTTYBlock( NPTTYINFO npTTYInfo, LPSTR lpBlock, int nLength );
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CTTY::CTTY()
{
npTTYInfo = NULL;
/*
DWORD PParityTable[5] =
{
NOPARITY, EVENPARITY, ODDPARITY, MARKPARITY, SPACEPARITY
} ;
DWORD SStopBitsTable[3] =
{
ONESTOPBIT, ONE5STOPBITS, TWOSTOPBITS
} ;
DWORD BBaudTable[13] =
{ CBR_110, CBR_300, CBR_600, CBR_1200, CBR_2400,
CBR_4800, CBR_9600, CBR_14400, CBR_19200, CBR_38400,
CBR_56000, CBR_128000, CBR_256000
} ;
for(int i=0; i<5; i++) ParityTable[i] = PParityTable[i] ;
for( i=0; i<3; i++) StopBitsTable[i] = SStopBitsTable[i] ;
for( i=0; i<13; i++) BaudTable[i] = BBaudTable[i];
*/
}
CTTY::~CTTY()
{
CloseConnection();
DestroyTTYInfo();
}
//---------------------------------------------------------------------------
// LRESULT NEAR CreateTTYInfo( HWND hWnd )
//
// Description:
// Creates the tty information structure and sets
// menu option availability. Returns -1 if unsuccessful.
//
// Parameters:
// HWND hWnd
// Handle to main window.
//
// Win-32 Porting Issues:
// - Needed to initialize TERMWND( npTTYInfo ) for secondary thread.
// - Needed to create/initialize overlapped structures used in reads &
// writes to COMM device.
//
//---------------------------------------------------------------------------
LRESULT NEAR CTTY::CreateTTYInfo( void )
{
if (NULL == (npTTYInfo = (NPTTYINFO) LocalAlloc( LPTR, sizeof( TTYINFO ) )))
return ( (LRESULT) -1 ) ;
/*char strBaudRate[6];
GetProfileString("Config","BaudRate", "4800",strBaudRate,6);//((CMcomApp *)AfxGetApp())->
SelectedBaudRate = atol(strBaudRate);
int ComPort=DEFAULTCOMPORT;
GetProfileInt("Config","ComPort", ComPort);
*/
SelectedBaudRate = 1200; //baudrate=4800
// ComPort = 2; //COM2 = 2; //COM1 = 1; //IBM
// initialize TTY info structure
npTTYInfo->HeadPtr = 0;
npTTYInfo->TailPtr = 0;
COMDEV( npTTYInfo ) = 0 ;
CONNECTEDTO( npTTYInfo ) = FALSE ;
CONNECTED( npTTYInfo ) = FALSE ;
//CURSORSTATE( npTTYInfo ) = CS_HIDE ;
LOCALECHO( npTTYInfo ) = FALSE ;
AUTOWRAP( npTTYInfo ) = TRUE ;
PORT( npTTYInfo ) = ComPort;
BAUDRATE( npTTYInfo ) = SelectedBaudRate;
//CBR_19200 ;
BYTESIZE( npTTYInfo ) = 8 ;
FLOWCTRL( npTTYInfo ) = FC_RTSCTS ;
FLOWCTRL( npTTYInfo ) = FC_XONXOFF ;
PARITY( npTTYInfo ) = NOPARITY ;
STOPBITS( npTTYInfo ) = ONESTOPBIT ;
XONXOFF( npTTYInfo ) = FALSE ;
WRITE_OS( npTTYInfo ).Offset = 0 ;
WRITE_OS( npTTYInfo ).OffsetHigh = 0 ;
READ_OS( npTTYInfo ).Offset = 0 ;
READ_OS( npTTYInfo ).OffsetHigh = 0 ;
// create I/O event used for overlapped reads / writes
READ_OS( npTTYInfo ).hEvent = CreateEvent( NULL, // no security
TRUE, // explicit reset req
FALSE, // initial event reset
NULL ) ; // no name
if (READ_OS( npTTYInfo ).hEvent == NULL)
{
LocalFree( npTTYInfo ) ;
return ( -1 ) ;
}
WRITE_OS( npTTYInfo ).hEvent = CreateEvent( NULL, // no security
TRUE, // explicit reset req
FALSE, // initial event reset
NULL ) ; // no name
if (NULL == WRITE_OS( npTTYInfo ).hEvent)
{
CloseHandle( READ_OS( npTTYInfo ).hEvent ) ;
LocalFree( npTTYInfo ) ;
return ( -1 ) ;
}
return ( (LRESULT) TRUE ) ;
} // end of CreateTTYInfo()
//---------------------------------------------------------------------------
// BOOL NEAR OpenConnection( HWND hWnd )
//
// Description:
// Opens communication port specified in the TTYINFO struct.
// It also sets the CommState and notifies the window via
// the fConnected flag in the TTYINFO struct.
//
// Parameters:
// HWND hWnd
// handle to TTY window
//
// Win-32 Porting Issues:
// - OpenComm() is not supported under Win-32. Use CreateFile()
// and setup for OVERLAPPED_IO.
// - Win-32 has specific communication timeout parameters.
// - Created the secondary thread for event notification.
//
//---------------------------------------------------------------------------
BOOL NEAR CTTY::OpenConnection( void )
{
char szPort[ 15 ], szTemp[ 40 ] ;
BOOL fRetVal ;
// HANDLE hCommWatchThread ;
// DWORD dwThreadID ;
COMMTIMEOUTS CommTimeOuts ;
if (NULL == npTTYInfo )
return ( FALSE ) ;
// load the COM prefix string and append port number
lstrcpy(szTemp, "COM");
wsprintf( szPort, "%s%d", (LPSTR) szTemp, PORT( npTTYInfo ) ) ;
// open COMM device
if ((COMDEV( npTTYInfo ) =
CreateFile( szPort, GENERIC_READ | GENERIC_WRITE,
0, // exclusive access
NULL, // no security attrs
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL |
FILE_FLAG_OVERLAPPED, // overlapped I/O
NULL )) == (HANDLE) -1 )
{
sprintf(szTemp, "打开%s失败!", szPort);
AfxMessageBox(szTemp);
return ( FALSE ) ;
}
else
{
// get any early notifications
LPCOMMPROP lpCommProp = (LPCOMMPROP)malloc(sizeof(COMMPROP));
lpCommProp->wPacketLength = sizeof(COMMPROP);
GetCommProperties(COMDEV( npTTYInfo ), lpCommProp);
WORD dwSize = lpCommProp->wPacketLength; // get the size of the struct
free(lpCommProp);
lpCommProp = (LPCOMMPROP)malloc(dwSize);
lpCommProp->wPacketLength = dwSize;
if(GetCommProperties(COMDEV( npTTYInfo ), lpCommProp) == FALSE)
{
DWORD dError = GetLastError();
}
//m611
/*
if (lpCommProp->dwProvSubType == PST_RS232)
{
AfxMessageBox("Open COM!");
} */
free(lpCommProp);
SetCommMask( COMDEV( npTTYInfo ), EV_RXCHAR ) ;
// setup device buffers in 4196 out 4196
SetupComm( COMDEV( npTTYInfo ), 4196, 4196 ) ;
// purge any information in the buffer
PurgeComm( COMDEV( npTTYInfo ), PURGE_TXABORT | PURGE_RXABORT |
PURGE_TXCLEAR | PURGE_RXCLEAR ) ;
// set up for overlapped I/O
CommTimeOuts.ReadIntervalTimeout = MAXDWORD ;
CommTimeOuts.ReadTotalTimeoutMultiplier = 0 ;
CommTimeOuts.ReadTotalTimeoutConstant = 1000 ;
// CBR_9600 is approximately 1byte/ms. For our purposes, allow
// double the expected time per character for a fudge factor.
CommTimeOuts.WriteTotalTimeoutMultiplier = 0 ;
CommTimeOuts.WriteTotalTimeoutConstant = 1000 ;
SetCommTimeouts( COMDEV( npTTYInfo ), &CommTimeOuts ) ;
}
fRetVal = SetupConnection( ) ;//串口初始化
if (fRetVal)
{
CONNECTED( npTTYInfo ) = TRUE ;
/* 建立 Read Thread
// Create a secondary thread
// to watch for an event.
if (NULL == (hCommWatchThread =
CreateThread( (LPSECURITY_ATTRIBUTES) NULL,
0,
(LPTHREAD_START_ROUTINE) CommWatchProc,
(LPVOID) npTTYInfo,
0, &dwThreadID )))
{
CONNECTED( npTTYInfo ) = FALSE ;
CloseHandle( COMDEV( npTTYInfo ) ) ;
fRetVal = FALSE ;
}
else
{
THREADID( npTTYInfo ) = dwThreadID ;
HTHREAD( npTTYInfo ) = hCommWatchThread ;
// assert DTR
EscapeCommFunction( COMDEV( npTTYInfo ), SETDTR ) ;
}*/
}
else
{
CONNECTED( npTTYInfo ) = FALSE ;
CloseHandle( COMDEV( npTTYInfo ) ) ;
}
return ( fRetVal ) ;
} // end of OpenConnection()
//---------------------------------------------------------------------------
// BOOL NEAR SetupConnection( HWND hWnd )
//
// Description:
// This routines sets up the DCB based on settings in the
// TTY info structure and performs a SetCommState().
//
// Parameters:
// HWND hWnd
// handle to TTY window
//
// Win-32 Porting Issues:
// - Win-32 requires a slightly different processing of the DCB.
// Changes were made for configuration of the hardware handshaking
// lines.
//
//---------------------------------------------------------------------------
BOOL NEAR CTTY::SetupConnection( void )
{
BOOL fRetVal ;
BYTE bSet ;
DCB dcb ;
if (NULL == npTTYInfo)
return ( FALSE ) ;
dcb.DCBlength = sizeof( DCB ) ;
GetCommState( COMDEV( npTTYInfo ), &dcb ) ;
dcb.BaudRate = BAUDRATE( npTTYInfo ) ;
dcb.ByteSize = BYTESIZE( npTTYInfo ) ;
dcb.Parity = PARITY( npTTYInfo ) ;
dcb.StopBits = STOPBITS( npTTYInfo ) ;
// setup hardware flow control
bSet = (BYTE) ((FLOWCTRL( npTTYInfo ) & FC_DTRDSR) != 0) ;
dcb.fOutxDsrFlow = bSet ;
if (bSet)
dcb.fDtrControl = DTR_CONTROL_HANDSHAKE ;
else
dcb.fDtrControl = DTR_CONTROL_ENABLE ;
bSet = (BYTE) ((FLOWCTRL( npTTYInfo ) & FC_RTSCTS) != 0) ;
dcb.fOutxCtsFlow = bSet ;
if (bSet)
dcb.fRtsControl = RTS_CONTROL_HANDSHAKE ;
else
dcb.fRtsControl = RTS_CONTROL_ENABLE ;
// setup software flow control
bSet = (BYTE) ((FLOWCTRL( npTTYInfo ) & FC_XONXOFF) != 0) ;
dcb.fInX = dcb.fOutX = bSet ;
dcb.XonChar = ASCII_XON ;
dcb.XoffChar = ASCII_XOFF ;
dcb.XonLim = 100 ;
dcb.XoffLim = 100 ;
// other various settings
dcb.fBinary = TRUE ;
dcb.fParity = TRUE;
fRetVal = SetCommState( COMDEV( npTTYInfo ), &dcb ) ;
return ( fRetVal ) ;
} // end of SetupConnection()
//************************************************************************
// DWORD FAR PASCAL CommWatchProc( LPSTR lpData )
//
// Description:
// A secondary thread that will watch for COMM events.
//
// Parameters:
// LPSTR lpData
// 32-bit pointer argument
//
// Win-32 Porting Issues:
// - Added this thread to watch the communications device and
// post notifications to the associated window.
//
//************************************************************************
DWORD FAR PASCAL CommWatchProc( LPVOID lpData )
{
int x=5;
/*
DWORD dwEvtMask ;
NPTTYINFO npTTYInfo = (NPTTYINFO) lpData ;
OVERLAPPED os ;
int nLength ;
BYTE abIn[ MAXBLOCK + 1] ;
memset( &os, 0, sizeof( OVERLAPPED ) ) ;
// create I/O event used for overlapped read
os.hEvent = CreateEvent( NULL, // no security
TRUE, // explicit reset req
FALSE, // initial event reset
NULL ) ; // no name
if (os.hEvent == NULL)
{
MessageBox( NULL, "Failed to create event for thread!", "TTY Error!",
MB_ICONEXCLAMATION | MB_OK ) ;
return ( FALSE ) ;
}
if (!SetCommMask( COMDEV( npTTYInfo ), EV_RXCHAR ))
return ( FALSE ) ;
DWORD dwError;
COMSTAT cs;
//再读到的串abIn,如果不是0D则弹出对话框(重新校验)否则读并口EPP的数据
//保存串口数据
//WriteTTYBlock( npTTYInfo, (LPSTR) abIn, nLength ) ;
//调读并口EPP的数据函数
while ( CONNECTED( npTTYInfo ) )
{
dwEvtMask = 0 ;
WaitCommEvent( COMDEV( npTTYInfo ), &dwEvtMask, NULL );
ClearCommError(COMDEV( npTTYInfo ),&dwError,&cs);
if ((dwEvtMask & EV_RXCHAR) && cs.cbInQue)
//if ((dwEvtMask & EV_TXEMPTY) )
{
do
{
if (nLength = ReadCommBlock( npTTYInfo, (LPSTR) abIn, MAXBLOCK ))
{
//处理读到的串abIn
//如果是0E则弹出对话框(仪器在自校验)否则向串口写0F do{}while
//M_COM_Return = abIn[0];
MyTTY.CloseConnection(); //关闭串口
return 0; //利用全局变量,方便编程
if(abIn[0]==0x0e)
{
AfxMessageBox("仪器在自校验...");
}
else if(abIn[0]==0x0d)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -