工控串口通讯设计的源码
/*************************************************************
EasySoft easycomm v2.0
(c) 2001-2004 EasySoft Corporation. All Rights Reserved.
@doc easycomm.rtf
@module easycomm.h | easycomm interface file
@devnote jdzwq 2003.01 - 2004.10
*************************************************************/
#ifndef _EASYCOMM_H
#define _EASYCOMM_H
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <windows.h>
#include <commctrl.h>
#include <tchar.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef enum{
NC_COMMBREAK = 110,
NC_COMMERROR = 111,
NC_COMMMONITOR = 112,
NC_COMMACK = 113,
NC_COMMRECIVE = 114,
NC_COMMSENT = 115
}NotifyCode;
typedef struct tagNMHDR_COMM{
HWND hwndFrom;
UINT idFrom;
UINT code;
LPARAM lParam;
WPARAM wParam;
}NMHDR_COMM;
#define WM_COMMMSG WM_USER + 10
#define COMMCTRLCLASS _T("CommCtrl")
ATOM RegisterCommCtrlClass(HINSTANCE hInstance);
#define COM_SETPORT WM_COMMMSG + 150
#define COM_GETPORT WM_COMMMSG + 151
#define COM_SETBAUDRATE WM_COMMMSG + 152
#define COM_GETBAUDRATE WM_COMMMSG + 153
#define COM_SETBYTESIZE WM_COMMMSG + 154
#define COM_GETBYTESIZE WM_COMMMSG + 155
#define COM_SETSTOPBITS WM_COMMMSG + 156
#define COM_GETSTOPBITS WM_COMMMSG + 157
#define COM_SETPARITY WM_COMMMSG + 158
#define COM_GETPARITY WM_COMMMSG + 159
#define COM_SETFCTRL WM_COMMMSG + 160
#define COM_GETFCTRL WM_COMMMSG + 161
#define COM_SETTIMEOUTS WM_COMMMSG + 162
#define COM_GETTIMEOUTS WM_COMMMSG + 163
#define COM_SETACKCHAR WM_COMMMSG + 164
#define COM_GETACKCHAR WM_COMMMSG + 165
#define COM_SETLISTIMER WM_COMMMSG + 166
#define COM_GETLISTIMER WM_COMMMSG + 167
#define COM_SETACTIVE WM_COMMMSG + 168
#define COM_GETACTIVE WM_COMMMSG + 169
#define COM_SETDATA WM_COMMMSG + 170
#define COM_GETDATA WM_COMMMSG + 171
#define COM_SETQUEUE WM_COMMMSG + 172
#define COM_POSTERROR WM_COMMMSG + 175
#define COM_POSTRECIVE WM_COMMMSG + 176
#define COM_POSTSENT WM_COMMMSG + 177
#define COM_POSTBREAK WM_COMMMSG + 178
#define COM_POSTACK WM_COMMMSG + 179
#define COM_POSTMONITOR WM_COMMMSG + 180
#define COM_QUERYSEND WM_COMMMSG + 181
#define PY_NONE 0 /*无奇偶校验*/
#define PY_EVEN 1 /*偶校验*/
#define PY_ODD 2 /*奇校验*/
#define PY_MARK 3
#define PY_SPACE 4
#define STOPBITS_ONE 1 /*1位停止位*/
#define STOPBITS_TWO 2 /*2位停止位*/
#define STOPBITS_ONEHALF 3 /*1.5停止位*/
#define FLOWCTRL_NONE 0 /*无流控制*/
#define FLOWCTRL_HARD 1 /*硬件控制*/
#define FLOWCTRL_SOFT 2 /*软件控制*/
#define CE_PARAM -1
#define READ_SUCCESS 0
#define READ_TIMEOUTS 1
#define WRITE_SUCCESS 0
#define WRITE_TIMEOUTS 1
/*端口状态*/
typedef struct _CommMonitor{
BOOL bRLSDHold;
BOOL bCTSHold;
BOOL bDSRHold;
BOOL bXOFFHold;
BOOL bXOFFSent;
int nInQueue;
int nOutQueue;
}CommMonitor;
#ifdef _CHS
#define ERROR_PARAM _T("参数错误")
#define ERROR_BREAK _T("硬件中断")
#define ERROR_FRAME _T("硬件幀错误")
#define ERROR_IOE _T("通讯I/O错误")
#define ERROR_OVERRUM _T("数据丢失")
#define ERROR_RXOVER _T("输入缓冲区溢出")
#define ERROR_RXPARITY _T("硬件校验错误")
#define ERROR_TXFULL _T("输出缓冲区溢出")
#define ERROR_UNKNOWN _T("其他错误")
#else
#define ERROR_PARAM _T("The parameter setup error")
#define ERROR_BREAK _T("The hardware detected a break condition.")
#define ERROR_FRAME _T("The hardware detected a framing error.")
#define ERROR_IOE _T("An I/O error occurred during communications with the device.")
#define ERROR_OVERRUN _T("A character-buffer overrun has occurred. The next character is lost.")
#define ERROR_RXOVER _T("An input buffer overflow has occurred. There is either no room in the input buffer, or a character was received after the end-of-file (EOF) character.")
#define ERROR_RXPARITY _T("The hardware detected a parity error.")
#define ERROR_TXFULL _T("The application tried to transmit a character, but the output buffer was full.")
#define ERROR_UNKNOWN _T("Other error occurred")
#endif
extern void InitCommControl(HINSTANCE hInstance);
extern void UnInitCommControl(HINSTANCE hInstance);
#ifdef __cplusplus
}
#endif
#endif
/*************************************************************
EasySoft easycomm v2.0
(c) 2001-2004 EasySoft Corporation. All Rights Reserved.
@doc easycomm.rtf
@module easycomm.c | easycomm impliment file
@devnote jdzwq 2003.01 - 2004.10
*************************************************************/
#include "easycomm.h"
typedef struct tagCommDelta{
HWND hWnd;
BOOL bActive; /*侦听标志*/
BOOL bReady; /*串口可写标志*/
HANDLE hListen; /*侦听线程句柄*/
DWORD dwListen; /*侦听线程ID*/
OVERLAPPED ovListen; /*用于侦听的重叠操作结构*/
HANDLE hCom; /*端口句柄*/
CRITICAL_SECTION cs; /* 同步临界区*/
short nFlowCtrl; /*流控制模式*/
short nAckChar; /*回应字符*/
short nParity; /*校验方式*/
short nStopBits; /*停止位*/
short nByteSize; /*位长*/
short nReadTimeoutPerByte; /*读每字节超时参数*/
short nWriteTimeoutPerByte; /*写每字节超时参数*/
long nListenTimeout; /*侦听超时*/
long nBaudRate; /*波特率*/
long nInQueue; /*输入缓冲区大小*/
long nOutQueue; /*输出缓冲区大小*/
TCHAR szPort[10]; /*端口*/
}CommDelta;
/*定义线程操作结构*/
typedef struct _OperaParam
{
HANDLE hCom; /*串口句柄*/
LPCRITICAL_SECTION pcs; /*临界区引用*/
DWORD dwDataBytes; /*请求操作字节数*/
DWORD dwOperaBytes; /*实际操作字节数*/
BYTE* data; /*读写数据指针*/
short nRetCode;
}OperaParam;
#define GETCOMMDELTA(hWnd) ((CommDelta*)GetWindowLong(hWnd,GWL_USERDATA))
#define SETCOMMDELTA(hWnd,ptd) SetWindowLong(hWnd,GWL_USERDATA,(LONG)ptd)
LRESULT CALLBACK CommCtrlProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
void COM_Paint(HWND hWnd,HDC hDC);
int COM_SendSign(HWND hWnd,UINT sign, WPARAM wParam,LPARAM lParam);
BOOL COM_Active(HWND hWnd,BOOL bActive);
long COM_SendData(HWND hWnd,long size,BYTE* data);
long COM_ReciveData(HWND hWnd,long size,BYTE* data);
DWORD WINAPI ListenProc(LPVOID lpParam);
DWORD WINAPI WriteProc(LPVOID lpParam);
void* _CommAlloc(long size);
void _CommFree(void* data);
ATOM RegisterCommCtrlClass(HINSTANCE hInstance)
{
WNDCLASS wcex;
#ifdef _WINDOWS
wcex.style = CS_OWNDC | CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;
#else
wcex.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;
#endif
wcex.lpfnWndProc = (WNDPROC)CommCtrlProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = NULL;
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)GetStockObject(GRAY_BRUSH);
wcex.lpszMenuName = NULL;
wcex.lpszClassName = COMMCTRLCLASS;
return RegisterClass(&wcex);
}
LRESULT CALLBACK CommCtrlProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
CommDelta* ptd = GETCOMMDELTA(hWnd);
PAINTSTRUCT ps;
int n;
switch(message)
{
case WM_CREATE:
ptd = (CommDelta*)calloc(1,sizeof(CommDelta));
ptd->hWnd = hWnd;
/*默认参数配置*/
lstrcpy(ptd->szPort,_T("COM1"));
ptd->nReadTimeoutPerByte = ptd->nWriteTimeoutPerByte = 10;
ptd->nListenTimeout = 5000;
ptd->nFlowCtrl = 0;
ptd->nAckChar = 0;
ptd->nParity = 0;
ptd->nStopBits = 1;
ptd->nByteSize = 8;
ptd->nBaudRate = 1200;
ptd->bReady = FALSE;
ptd->bActive = FALSE;
ptd->hCom = INVALID_HANDLE_VALUE;
ptd->hListen = NULL;
InitializeCriticalSection(&ptd->cs);
SETCOMMDELTA(hWnd,ptd);
break;
case WM_DESTROY:
if(ptd->bActive)
SendMessage(hWnd,COM_SETACTIVE,(WPARAM)FALSE,0);
DeleteCriticalSection(&ptd->cs);
free(ptd);
break;
case WM_PAINT:
if(GetUpdateRect(hWnd,NULL,TRUE))
{
BeginPaint(hWnd,&ps);
COM_Paint(hWnd,ps.hdc);
EndPaint(hWnd,&ps);
}
case COM_SETPORT:
if(lParam)
{
n = _tcslen((TCHAR*)lParam);
n