📄 pcsyn_serial.c
字号:
#include <windows.h>
#include <stdio.h>
#include "pcsyn_protocol.h"
#include "pcsyn_serial.h"
#include "pcsyn_protocoldll.h"
static HANDLE hCom = 0;
static HANDLE hCommWatchThread = 0;
static OVERLAPPED read_overlapped;
static OVERLAPPED write_overlapped;
static OVERLAPPED wait_overlapped;
static void CommWatchProc(void* lpvoid);
typedef enum
{
RX_WAIT_STX,
RX_WAIT_DATA,
RX_WAIT_DATA_DLE,
RX_WAIT_ETX
}RX_STATUS;
RX_STATUS rx_status = RX_WAIT_STX;
static BYTE stx = 0x02;
static BYTE dle = 0x10;
static BYTE etx = 0x02;
#ifdef FILE_DEBUG
BOOL fileFirst = TRUE;
char szPathName[MAX_PATH];
char szFileTrace[MAX_PATH];
char szFileMonitor[MAX_PATH];
char szFileError[MAX_PATH];
void emptyMonitorFile()
{
if(!fileFirst)
{
remove(szFileTrace);
remove(szFileMonitor);
remove(szFileError);
}
}
void write_monitor(BYTE* data,int size,int type)
{
FILE *fp;
int i = 0;
static char buffer[1024];
char *p = buffer;
memset(buffer,0,sizeof(buffer) );
if(type ==0)//pc->target
{
p += sprintf(p,">>");
}
else
{
p += sprintf(p,"<<");
}
while(i<size)
{
p += sprintf(p," %02x", data[i++]);
}
p += sprintf(p,"\n");
fp = fopen(szFileMonitor,"a");
if(fp)
{
fprintf(fp,buffer);
fclose(fp);
}
}
#endif
DllExport int Serial_Open(unsigned char* name,unsigned baudtrate)
{
DCB dcb;
BOOL fSuccess;
COMMTIMEOUTS timeouts;
unsigned int dwThreadID;
#ifdef FILE_DEBUG
if(fileFirst)
{
char *pdest;
memset(szPathName, 0 ,sizeof(szPathName) );
GetModuleFileName(NULL,szPathName,sizeof(szPathName));
pdest = strrchr( szPathName, '\\' );
if(pdest)
*pdest = 0;
sprintf(szFileTrace,"%s\\pcsyn_trace.txt",szPathName);
sprintf(szFileMonitor,"%s\\pcsyn_monitor.txt",szPathName);
sprintf(szFileError,"%s\\pcsyn_error.txt",szPathName);
fileFirst = FALSE;
}
#endif
if (hCom )
return 1;
hCom =CreateFile( name, GENERIC_READ | GENERIC_WRITE, // 允许读写
0, // 此项必须为0
NULL, // no security attrs
OPEN_EXISTING, //设置产生方式
FILE_FLAG_OVERLAPPED, // 我们准备使用异步通信
NULL );
if(hCom == INVALID_HANDLE_VALUE)
return 2;
dcb.DCBlength = sizeof(dcb);
GetCommState (hCom, &dcb);
dcb.BaudRate = baudtrate; // set the baud rate
//dcb.fBinary = TRUE; // Binary mode; no EOF check
//dcb.fParity = FALSE; // Disable parity checking
//dcb.fOutxCtsFlow = FALSE; // No CTS output flow control
// dcb.fOutxDsrFlow = FALSE; // No DSR output flow control
dcb.fDtrControl = DTR_CONTROL_ENABLE;
// DTR flow control type
// dcb.fDsrSensitivity = FALSE; // DSR sensitivity
// dcb.fTXContinueOnXoff = TRUE; // XOFF continues Tx
// dcb.fOutX = FALSE; // No XON/XOFF out flow control
// dcb.fInX = FALSE; // No XON/XOFF in flow control
// dcb.fErrorChar = FALSE; // Disable error replacement
// dcb.fNull = FALSE; // Disable null stripping
dcb.fRtsControl = RTS_CONTROL_DISABLE;
// RTS flow control
dcb.fAbortOnError = FALSE; // Do not abort reads/writes on
// error
dcb.ByteSize = 8; // Number of bits/byte, 4-8
dcb.Parity = NOPARITY; // 0-4=no,odd,even,mark,space
dcb.StopBits = ONESTOPBIT;
fSuccess = SetCommState(hCom, &dcb);
timeouts.ReadIntervalTimeout = 0;
timeouts.ReadTotalTimeoutMultiplier = 0;
timeouts.ReadTotalTimeoutConstant = 0;
timeouts.WriteTotalTimeoutMultiplier = 0;
timeouts.WriteTotalTimeoutConstant = 0;
SetCommTimeouts (hCom, &timeouts);
SetCommMask (hCom, EV_RXCHAR);
PurgeComm(hCom, PURGE_TXABORT|PURGE_RXABORT|PURGE_TXCLEAR|PURGE_RXCLEAR);
read_overlapped.hEvent = CreateEvent (NULL, FALSE, FALSE, "read");
write_overlapped.hEvent = CreateEvent (NULL, FALSE, FALSE, "write");
wait_overlapped.hEvent = CreateEvent (NULL, FALSE, FALSE, "wait");
if(!hCommWatchThread)
hCommWatchThread = CreateThread( (LPSECURITY_ATTRIBUTES) NULL, //安全属性
0,//初始化线程栈的大小,缺省为与主线程大小相同
(LPTHREAD_START_ROUTINE)CommWatchProc, //线程的全局函数
NULL,
0,
&dwThreadID);
return 0;
}
DllExport int Serial_Close()
{
if(hCom)
{
CloseHandle(hCom);
hCom = 0;
WaitForSingleObject(hCommWatchThread,INFINITE);
CloseHandle(hCommWatchThread);
hCommWatchThread = NULL;
CloseHandle (read_overlapped.hEvent);
CloseHandle (write_overlapped.hEvent);
CloseHandle(wait_overlapped.hEvent);
}
return 0;
}
static void CommWatchProc(void* lpvoid)
{
BOOL fSuccess;
DWORD event_mask;
BYTE *p, inbuf[64];
DWORD size;
DWORD dwError;
int i;
static BYTE rxbuff[256];
static int size_rxbuff = 0;
while(1)
{
read_overlapped.Offset = 0;
read_overlapped.OffsetHigh = 0;
WaitCommEvent (hCom, &event_mask, &wait_overlapped);
if(hCom == NULL)
break;
SetCommMask (hCom, EV_RXCHAR);
do
{
fSuccess = ReadFile(hCom, &inbuf[0], 1, &size, &read_overlapped);
if (fSuccess == FALSE)
{
switch(dwError =GetLastError() )
{
case ERROR_HANDLE_EOF:
break;
case ERROR_IO_PENDING:
fSuccess = GetOverlappedResult(hCom, &read_overlapped,
&size, TRUE);
break;
//if (fSuccess == FALSE) assert(0);
default:
break;//?
}
}
p = inbuf;
i = size;
//rx_status = RX_WAIT_STX;
//size_rxbuff = 0;
while (i--)
{
switch(rx_status)
{
case RX_WAIT_STX://begin data recv
if(*p == stx)
{
rx_status = RX_WAIT_DATA;
size_rxbuff = 0;
}
break;
case RX_WAIT_DATA:
if(*p == dle)
{
rx_status = RX_WAIT_DATA_DLE;
}
else if(*p == etx)
{
rx_status = RX_WAIT_STX;
if(rxbuff[0] == HEADER_DL && size_rxbuff >=6 )
{
serial2protocol(rxbuff+1,size_rxbuff-1);
#ifdef FILE_DEBUG
write_monitor(rxbuff, size_rxbuff,1);
#endif
}
#ifdef FILE_DEBUG
else if(rxbuff[0] == 0x11 && size_rxbuff >=6)
{
FILE *fp;
fp = fopen(szFileTrace,"a");
if(fp)
{
fwrite(rxbuff+1+5,1,size_rxbuff-1-5,fp);
fprintf(fp,"\n");
fclose(fp);
}
}
else
{
FILE *fp;
fp = fopen(szFileError,"a");
if(fp)
{
fwrite(rxbuff,1,size_rxbuff,fp);
fclose(fp);
}
}
#endif
if(size_rxbuff == 0)//recv package error,reset status
{
rx_status = RX_WAIT_DATA;
}
size_rxbuff = 0;
}
else
{
rxbuff [size_rxbuff ++ ] = *p;
}
break;
case RX_WAIT_DATA_DLE:
rxbuff [size_rxbuff ++ ] = *p;
rx_status = RX_WAIT_DATA;
break;
default:
break;
}
p++;
}
} while (size);
}
}//
int protocol2serial(BYTE *buf, int size)
{
BOOL fSuccess;
DWORD written;
static BYTE txbuf[256];
BYTE *ptxbuf = txbuf;
int i, txsize;
COMSTAT comstat;
DWORD dwError;
#ifdef FILE_DEBUG
write_monitor(buf, size,0);
#endif
if (stx)
*ptxbuf++ = stx;
// Optionally perform byte stuffing
if (dle)
{
for (i = 0; i < size; i++) {
if ((dle != 0 && *buf == dle) ||
(stx != 0 && *buf == stx) ||
(etx != 0 && *buf == etx))
*ptxbuf++ = dle;
*ptxbuf++ = *buf++;
}
}
else {
memcpy(ptxbuf, buf, size);
ptxbuf += size;
}
if (etx)
*ptxbuf++ = etx;
txsize = ptxbuf - txbuf;
ResetEvent(write_overlapped.hEvent); // why?
// ClearCommError(hCom,&dwError,&comstat);
fSuccess = WriteFile(hCom, txbuf, txsize, &written, &write_overlapped);
if (fSuccess == FALSE)
{
if (GetLastError () == ERROR_IO_PENDING)
{
if (GetOverlappedResult(hCom, &write_overlapped,
&written, TRUE) == FALSE)
{
//written = E_PKTDRV_SEND;
}
}
}
return written;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -