分享
 
 
 

VC在windows下编写用于串行通讯的程序

王朝vc·作者佚名  2006-01-08
窄屏简体版  字體: |||超大  

既然有这么多人问这个文体,贝贝就给个Visual C++ 4.2写的

Window 95串口通讯函数集合(只适用于32位)

需要说明的是:这是我程序的一部分,因此有一些与具体应用无关的部分。

但我觉得关键是原理,而不是程序本身.后面有些使用介绍,帮助理解这长的程序。

头文件(.H)

#include "StdAfx.h"

#define GWL_PGPSINFO 0

#define GPSEXTRABYTES sizeof( LONG )

#define MAXPORTS 4

#define CN_SEND WM_USER+100

#define RXQUEUE 4096

#define TXQUEUE 4096

// cursor states

#define CS_HIDE 0x00

#define CS_SHOW 0x01

// Flow control flags

#define FC_DTRDSR 0x01

#define FC_RTSCTS 0x02

#define FC_XONXOFF 0x04

// ascii definitions

#define ASCII_BEL 0x07

#define ASCII_BS 0x08

#define ASCII_LF 0x0A

#define ASCII_CR 0x0D

#define ASCII_XON 0x11

#define ASCII_XOFF 0x13

// data structures

typedef struct tagGPSINFO

{

HANDLE idComDev;

BYTE bPort;

BOOL fConnected;

BYTE bByteSize,bParity,bStopBits;

DWORD dwBaudRate;

HANDLE hPostEvent,hWatchThread,hWatchEvent;

HWND hTermWnd;

DWORD dwThreadID;

OVERLAPPED osWrite,osRead;

} GPSINFO, *PGPSINFO ;

#define COMDEV( x ) (x -> idComDev)

#define PORT( x ) (x -> bPort)

#define CONNECTED( x ) (x -> fConnected)

#define BYTESIZE( x ) (x -> bByteSize)

#define PARITY( x ) (x -> bParity)

#define STOPBITS( x ) (x -> bStopBits)

#define BAUDRATE( x ) (x -> dwBaudRate)

#define POSTEVENT( x ) (x -> hPostEvent)

#define HTHREAD( x ) (x -> hWatchThread)

#define THREADID( x ) (x -> dwThreadID)

#define WRITE_OS( x ) (x -> osWrite)

#define READ_OS( x ) (x -> osRead)

// function prototypes (private)

LRESULT NEAR CreateGPSInfo(HWND,BYTE nPort=1);

BOOL NEAR DestroyGPSInfo();

int NEAR ReadCommBlock(LPSTR,int);

BOOL NEAR WriteCommBlock(LPSTR,DWORD);

BOOL NEAR OpenConnection();

BOOL NEAR SetupConnection();

BOOL NEAR CloseConnection();

// function prototypes (public)

DWORD FAR PASCAL CommWatchProc(LPSTR);

具体实现请看下文(为了这文章,我都段线2次了)

CPP实现部分:

#include "StdAfx.h"

#include "Com.h"

HWND hGPSWnd=NULL;

PGPSINFO npGPSInfo=NULL;

LRESULT NEAR CreateGPSInfo(HWND hWnd,BYTE nPort)

{

if (NULL==(npGPSInfo=(PGPSINFO)LocalAlloc(LPTR,sizeof(GPSINFO))))

return ((LRESULT)-1) ;

hGPSWnd=hWnd;

COMDEV(npGPSInfo)=0;

CONNECTED(npGPSInfo)=FALSE;

PORT(npGPSInfo)=nPort;

BAUDRATE(npGPSInfo)=CBR_9600;

BYTESIZE(npGPSInfo)=8;

PARITY(npGPSInfo)=NOPARITY;

STOPBITS(npGPSInfo)=ONESTOPBIT;

WRITE_OS(npGPSInfo).Offset=0;

WRITE_OS(npGPSInfo).OffsetHigh=0;

READ_OS(npGPSInfo).Offset=0;

READ_OS(npGPSInfo).OffsetHigh=0;

// create I/O event used for overlapped reads / writes

READ_OS(npGPSInfo).hEvent=CreateEvent(NULL,TRUE,FALSE,NULL);

if (READ_OS(npGPSInfo).hEvent==NULL)

{ LocalFree( npGPSInfo ) ;

return ( -1 ) ;

}

WRITE_OS(npGPSInfo).hEvent=CreateEvent(NULL,TRUE,FALSE,NULL);

if (NULL==WRITE_OS(npGPSInfo).hEvent)

{ CloseHandle(READ_OS(npGPSInfo).hEvent);

LocalFree(npGPSInfo) ;

return (-1) ;

}

return ( (LRESULT) TRUE ) ;

}

BOOL NEAR DestroyGPSInfo()

{

if (!npGPSInfo) return (FALSE);

if (CONNECTED(npGPSInfo)) CloseConnection();

CloseHandle(READ_OS(npGPSInfo).hEvent);

CloseHandle(WRITE_OS(npGPSInfo).hEvent);

CloseHandle(POSTEVENT(npGPSInfo));

LocalFree(npGPSInfo);

return (TRUE);

}

BOOL NEAR OpenConnection()

{

char szPort[15];

BOOL fRetVal;

HCURSOR hOldCursor,hWaitCursor;

HANDLE hCommWatchThread;

DWORD dwThreadID;

COMMTIMEOUTS CommTimeOuts;

if (!npGPSInfo) return (FALSE);

hWaitCursor=LoadCursor(NULL,IDC_WAIT) ;

hOldCursor=SetCursor(hWaitCursor) ;

wsprintf(szPort,"COM%d",PORT(npGPSInfo));

if

((COMDEV(npGPSInfo)=CreateFile(szPort,GENERIC_READ|GENERIC_WRITE,

0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL|FILE_FLAG_OVERLAPPED,

NULL))==(HANDLE)-1)

return ( FALSE ) ;

else

{ SetCommMask(COMDEV(npGPSInfo),EV_RXCHAR);

SetupComm(COMDEV(npGPSInfo),4096,4096);

PurgeComm(COMDEV(npGPSInfo),PURGE_TXABORT|PURGE_RXABORT|PURGE_TXCLEAR|PURGE_R

XCLEAR);

CommTimeOuts.ReadIntervalTimeout=0xFFFFFFFF;

CommTimeOuts.ReadTotalTimeoutMultiplier=0;

CommTimeOuts.ReadTotalTimeoutConstant=1000;

CommTimeOuts.WriteTotalTimeoutMultiplier=0;

CommTimeOuts.WriteTotalTimeoutConstant=1000;

SetCommTimeouts(COMDEV(npGPSInfo),&CommTimeOuts);

}

fRetVal=SetupConnection();

if (fRetVal)

{ CONNECTED(npGPSInfo)=TRUE;

if

(NULL==(hCommWatchThread=CreateThread((LPSECURITY_ATTRIBUTES)NULL,

0,(LPTHREAD_START_ROUTINE)CommWatchProc,

(LPVOID)NULL,0,&dwThreadID)))

{ CONNECTED(npGPSInfo)=FALSE;

CloseHandle(COMDEV(npGPSInfo));

fRetVal=FALSE;

}

else

{ THREADID(npGPSInfo)=dwThreadID;

HTHREAD(npGPSInfo)=hCommWatchThread;

EscapeCommFunction(COMDEV(npGPSInfo),SETDTR);

}

}

else

{ CONNECTED(npGPSInfo)=FALSE;

CloseHandle(COMDEV(npGPSInfo));

}

SetCursor(hOldCursor);

return (fRetVal);

}

BOOL NEAR SetupConnection()

{ BOOL fRetVal;

DCB dcb;

if (!npGPSInfo) return(FALSE);

dcb.DCBlength=sizeof(DCB);

GetCommState(COMDEV(npGPSInfo),&dcb);

dcb.BaudRate=BAUDRATE(npGPSInfo);

dcb.ByteSize=BYTESIZE(npGPSInfo);

dcb.Parity=PARITY(npGPSInfo);

dcb.StopBits=STOPBITS(npGPSInfo);

dcb.fOutxDsrFlow=FALSE;

dcb.fDtrControl=DTR_CONTROL_ENABLE;

dcb.fOutxCtsFlow=FALSE;

dcb.fRtsControl=RTS_CONTROL_ENABLE;

dcb.fInX=dcb.fOutX=FALSE;

dcb.fBinary=TRUE;

dcb.fParity=TRUE;

fRetVal=SetCommState(COMDEV(npGPSInfo),&dcb);

return (fRetVal);

}

BOOL NEAR CloseConnection()

{

if (!npGPSInfo) return(FALSE);

CONNECTED(npGPSInfo)=FALSE;

SetCommMask(COMDEV(npGPSInfo),0);

while(THREADID(npGPSInfo)!=0);

EscapeCommFunction(COMDEV(npGPSInfo),CLRDTR);

PurgeComm(COMDEV(npGPSInfo),PURGE_TXABORT|PURGE_RXABORT|

PURGE_TXCLEAR|PURGE_RXCLEAR);

CloseHandle(COMDEV(npGPSInfo));

return (TRUE);

}

int NEAR ReadCommBlock(LPSTR lpszBlock,int nMaxLength)

{

BOOL fReadStat ;

COMSTAT ComStat ;

DWORD dwErrorFlags;

DWORD dwLength;

DWORD dwError;

if (!npGPSInfo) return(FALSE);

ClearCommError(COMDEV(npGPSInfo),&dwErrorFlags,&ComStat);

dwLength=min((DWORD)nMaxLength,ComStat.cbInQue);

if (dwLength>0)

{ fReadStat=ReadFile(COMDEV(npGPSInfo),lpszBlock,

dwLength,&dwLength,&READ_OS(npGPSInfo));

if (!fReadStat)

{ if (GetLastError()==ERROR_IO_PENDING)

{ OutputDebugString(" IO Pending");

while(!GetOverlappedResult(COMDEV(npGPSInfo),&READ_OS(npGPSInfo),&dwLength,TR

UE))

{ dwError=GetLastError();

if(dwError == ERROR_IO_INCOMPLETE)

continue;

}

}

else

{ dwLength=0;

ClearCommError(COMDEV(npGPSInfo),&dwErrorFlags,&ComStat);

}

}

}

return ( dwLength ) ;

}

BOOL NEAR WriteCommBlock(LPSTR lpByte,DWORD dwBytesToWrite)

{ BOOL fWriteStat;

DWORD dwBytesWritten;

DWORD dwErrorFlags;

DWORD dwError;

COMSTAT ComStat;

if (!npGPSInfo) return(FALSE);

fWriteStat=WriteFile(COMDEV(npGPSInfo),lpByte,dwBytesToWrite,

&dwBytesWritten,&WRITE_OS(npGPSInfo));

if (!fWriteStat)

{ if(GetLastError()==ERROR_IO_PENDING)

{ while(!GetOverlappedResult(COMDEV(npGPSInfo),

&WRITE_OS(npGPSInfo),&dwBytesWritten,TRUE))

{ dwError=GetLastError();

if(dwError == ERROR_IO_INCOMPLETE)

continue;

else

{

ClearCommError(COMDEV(npGPSInfo),&dwErrorFlags,&ComStat);

break;

}

}

}

else

{

ClearCommError(COMDEV(npGPSInfo),&dwErrorFlags,&ComStat);

return ( FALSE );

}

}

return ( TRUE ) ;

}

DWORD FAR PASCAL CommWatchProc(LPSTR)

{ DWORD dwEvtMask;

OVERLAPPED os;

int nLength;

BYTE abIn[1024];

memset(&os,0,sizeof(OVERLAPPED));

// create I/O event used for overlapped read

os.hEvent=CreateEvent(NULL,TRUE,FALSE,NULL);

if (os.hEvent==NULL)

{ MessageBox(NULL,"Failed to create event for thread!","GPS

Error!",MB_ICONEXCLAMATION|MB_OK);

return ( FALSE ) ;

}

if (!SetCommMask(COMDEV(npGPSInfo),EV_RXCHAR)) return (FALSE);

while (CONNECTED( npGPSInfo))

{ dwEvtMask=0 ;

WaitCommEvent(COMDEV(npGPSInfo),&dwEvtMask,NULL);

if ((dwEvtMask&EV_RXCHAR)==EV_RXCHAR)

{ do

{ if

(nLength=ReadCommBlock((LPSTR)abIn,1024))

{

//WriteCommBlock((LPSTR)abIn,nLength );

*(abIn+nLength)=0;

::SendMessage(hGPSWnd,CN_SEND,nLength,(LONG)(LPSTR)abIn);

}

}

while ((nLength>0)&&(CONNECTED( npGPSInfo)));

}

}

CloseHandle(os.hEvent);

THREADID(npGPSInfo)=0;

HTHREAD(npGPSInfo)=NULL;

return(TRUE);

}

就这些了,希望能对问这些问题的朋友有所帮助!

一般使用的顺序是:

CreateGPSInfo(被通知的窗口句柄,串口端口号1或2);

OpenConnection();//建立联结它会调用SetupConnection

DestroyGPSInfo();//解除联结它会调用CloseConnection

可以用ReadCommBlock/WriteCommBlock来读/写串口

CommWatchProc是监视串口的线程,由OpenConnection建立

当串口有数据来的时侯,它会通知'被通知的窗口句柄'的窗口数据传到的消息(自定义的)

SendMessage(hGPSWnd,CN_SEND,nLength,(LONG)(LPSTR)abIn);

好了,文章结束了!希望能帮助你!

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有