精华区 [关闭][返回]

当前位置:网易精华区>>讨论区精华>>编程开发>>C/C++>>硬件、外设相关>>串口专题>>Window 95串口通讯

主题:Window 95串口通讯
发信人: tony_tang()
整理人: wenbobo(2002-05-23 11:48:31), 站内信件
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("\n\rIO Pending"); 

while(!GetOverlappedResult(COMDEV(npGPSInfo),&READ_OS(npGPSInfo),&dwLe

ngth,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);

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

---------------------------------------
------摘自VC PARK

--
人家说我苕,我说我不苕.
外面下大雨,我往屋里跑!

※ 修改:.tony_tang 于 Sep 10 19:08:43 修改本文.[FROM: 202.96.137.62]
※ 来源:.月光软件站 http://www.moon-soft.com.[FROM: 202.96.155.204]

[关闭][返回]