RS-232-C端口实时监控软件的设计实现(2)
当选择好适当的参数后就可以根据设置好的端口配置情况打开通讯端口了。与以往DOS下串行通信程序不同的是,Windows操作平台下不提倡应用程序直接控制硬件(包括端口),也不让使用中断(除非打入到Ring0系统级),而是通过Windows操作系统提供的设备驱动程序来进行数据传递。在Windows操作系统下串行口和其他通讯端口一样是作为文件来进行处理的,而不是直接对端口进行操作,对于串行通信,Win 32 提供了相应的文件I/O函数与通信函数,通过了解这些函数的使用,可以编制出符合不同需要的通信程序。与通信设备相关的结构有COMMCONFIG ,COMMPROP,COMMTIMEOUTS,COMSTAT,DCB,MODEMDEVCAPS,MODEMSETTINGS共7个,与通信有关的Windows API函数共有26个,具体说明可参考MSDN帮助文件。下面是打开串口的部分关键代码:
//以创建文件的形式打开文件,并将返回的端口句柄保存于句柄idComDev之中。
idComDev =CreateFile( g_szCom_Port[g_com_config.nPort],
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL );
……
file://cfg为COMMCONFIG结构的实例对象,获取当前通讯口的状态。
cfg.dcb.DCBlength = sizeof( DCB ) ;
GetCommState( idComDev, &(cfg.dcb) ) ;
file://设置发送、接收缓存大小
SetupComm( idComDev, 4096, 4096 ) ;
// PurgeComm()是一个清除函数,它可以用来中止任何未决的后台读或写,并且可以冲掉I/O
file://缓冲区.其中:PURGE_TXABORT 用于中止后台写操作;PRUGE_RXABORT用于中止后台
file://读操作 ;PRUGE_TXCLEAR用于清除发送缓冲区;PRUGE_RXCLEAR用于清除接收缓冲区
PurgeComm(idComDev,PURGE_TXABORT|PURGE_RXABORT|PURGE_TXCLEAR|PURGE_RXCLEAR);
file://根据设置的参数填充DCB结构对象dcb的各个数据成员变量
dcb.DCBlength = sizeof( DCB ) ;
GetCommState( idComDev, &dcb ) ;
file://设置端口通讯参数
dcb.BaudRate =g_Com_Baud[g_com_config.nBaud];
dcb.ByteSize =g_Com_ByteSize[g_com_config.nData];
dcb.Parity =g_Com_Parity[g_com_config.nParity] ;
dcb.StopBits =g_Com_StopBits[g_com_config.nStop];
file://硬件流控制
dcb.fDtrControl = DTR_CONTROL_DISABLE ;
dcb.fOutxCtsFlow = FALSE ;
dcb.fRtsControl = RTS_CONTROL_DISABLE ;
file://软件流控制
dcb.fInX = dcb.fOutX = FALSE ;
dcb.XonChar = (char)0xFF ;
dcb.XoffChar = (char)0XFF ;
dcb.XonLim = 100 ;
dcb.XoffLim = 100 ;
dcb.EvtChar=0x0d;
dcb.fBinary = TRUE ;
dcb.fParity = TRUE ;
file://超时控制的设置。超时有两种:区间超时:(仅对从端口中读取数据有用)它指定在读取两个字符之间要经历的时间;总超时: 当读或写特定的字节数需要的总时间超过某一阈值时,超时触发。计算超时可以根据公式:
file://ReadTotalTimeout = (ReadTotalTimeoutMultiplier * bytes_to_read)+
// ReadToTaltimeoutConstant
file://WriteTotalTimeout = (WriteTotalTimeoutMuliplier * bytes_to_write)+
// WritetoTotalTimeoutConstant
file://如果在设置超时时参数为0则为无限等待,即无超时。
CommTimeOuts.ReadIntervalTimeout =MAXDWORD;
CommTimeOuts.ReadTotalTimeoutMultiplier =0;
CommTimeOuts.ReadTotalTimeoutConstant = 0 ;
CommTimeOuts.WriteTotalTimeoutMultiplier =2*9600/dcb.BaudRate ;
CommTimeOuts.WriteTotalTimeoutConstant = 25 ;
SetCommTimeouts(idComDev , &CommTimeOuts ) ;
file://根据设置好的dcb结构设置好通讯口的状态,并开启用于侦听端口,监视从外设传来的数
file://据的线程COMReadThreadProc。
if (SetCommState( idComDev, &dcb ))
{
m_bComPortOpen=TRUE;
g_hCom=idComDev;
AfxBeginThread(COMReadThreadProc,NULL,THREAD_PRIORITY_NORMAL);
return;
}