发信人: wenbobo(事了拂衣去)
整理人: wenbobo(2002-05-23 11:48:31), 站内信件
|
//这是头文件:
//---------------------------------------------------------------------------
#ifndef CommCtrlH
#define CommCtrlH
//---------------------------------------------------------------------------
enum TWAITEVENT {WaitTillTimeout,
WaitTillAnyCharDetected,
WaitTillPatternDetected,
RepeatWriteBetweenPatterns
};
//---------------------------------------------------------------------------
// 此类基本上没有做什么数据封装,每个成员函数独立地使用各自的参数。
//---------------------------------------------------------------------------
class TCommCtrl
{
private: // Serial Port
HANDLE ComPortHandle;
public: // Serial Port
__fastcall TCommCtrl(void);
__fastcall ~TCommCtrl(void);
VOID Delay(DWORD MicroSecond);
HANDLE ComOpen(AnsiString ComPortName);
BOOL ComClose(void);
BOOL ComConfig(DWORD BaudRate, BYTE ByteSize, BYTE Parity, BYTE StopBits);
BOOL ComTimeouts(DWORD RTInterval, DWORD RTMulti, DWORD RTConstant,
DWORD WTMulti, DWORD WTConstant);
BOOL ComWriteString(char* String, BOOL SlowWrite);
BOOL ComReadString(char* String, DWORD BufferSize);
BOOL ComWriteWaitRead(AnsiString CommandString, AnsiString &RespondString,
TWAITEVENT WaitType, DWORD Timeouts, AnsiString Pattern1="",
AnsiString Pattern2="");
BOOL ComConnected(void);
};
//---------------------------------------------------------------------------
#endif
//这是实现部分:
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include <time.h>
#include "CommCtrl.h"
#pragma package(smart_init)
//---------------------------------------------------------------------------
#define RXBufferSize 1024*4
#define TXBufferSize 1024*2
//---------------------------------------------------------------------------
__fastcall TCommCtrl::TCommCtrl(void)
{
ComPortHandle = NULL;
}
//---------------------------------------------------------------------------
__fastcall TCommCtrl::~TCommCtrl(void)
{
}
//---------------------------------------------------------------------------
void TCommCtrl::Delay(DWORD MilliSecond)
{
DWORD BeginTime = GetTickCount();
while (abs(MilliSecond) && !Application->Terminated)
{
Application->ProcessMessages();
if (abs(GetTickCount()-BeginTime) >= abs(MilliSecond)) break;
}
}
//---------------------------------------------------------------------------
HANDLE TCommCtrl::ComOpen(AnsiString ComPortName)
{
if (ComPortHandle != NULL)
return NULL;
ComPortHandle = CreateFile(ComPortName.c_str(), GENERIC_READ|GENERIC_WRITE,
0, NULL, OPEN_EXISTING, 0, NULL);
if (ComPortHandle == INVALID_HANDLE_VALUE)
return NULL;
else
return ComPortHandle;
}
//---------------------------------------------------------------------------
BOOL TCommCtrl::ComClose(void)
{
if ((ComPortHandle==NULL) || CloseHandle(ComPortHandle))
{
ComPortHandle = NULL;
return true;
}else
return false;
}
//---------------------------------------------------------------------------
BOOL TCommCtrl::ComConfig(DWORD BaudRate, BYTE ByteSize, BYTE Parity, BYTE StopBits)
{
DCB dcb;
GetCommState(ComPortHandle, &dcb);
dcb.DCBlength = sizeof(DCB);
dcb.fBinary = true;
dcb.BaudRate = BaudRate;
dcb.ByteSize = ByteSize;
dcb.fParity = true;
dcb.Parity = Parity;
dcb.StopBits = StopBits;
dcb.fAbortOnError = false;
// 不需要任何流控制.
dcb.fOutxCtsFlow = false;
dcb.fOutxDsrFlow = false;
dcb.fOutX = false;
dcb.fInX = false;
// 设置缺省的超时值.
ComTimeouts(1,1,100,1,100);
////
SetupComm(ComPortHandle, RXBufferSize, TXBufferSize);
if (!SetCommState(ComPortHandle, &dcb))
return false;
else
return true;
}
//---------------------------------------------------------------------------
BOOL TCommCtrl::ComTimeouts(DWORD RTInterval, DWORD RTMulti, DWORD RTConstant,
DWORD WTMulti, DWORD WTConstant)
{
COMMTIMEOUTS timeouts;
GetCommTimeouts(ComPortHandle, &timeouts);
timeouts.ReadIntervalTimeout = RTInterval;
timeouts.ReadTotalTimeoutMultiplier = RTMulti;
timeouts.ReadTotalTimeoutConstant = RTConstant;
timeouts.WriteTotalTimeoutMultiplier = RTConstant;
timeouts.WriteTotalTimeoutConstant = WTConstant;
return SetCommTimeouts(ComPortHandle, &timeouts);
}
//---------------------------------------------------------------------------
BOOL TCommCtrl::ComWriteString(char* String, BOOL SlowWrite)
{
COMSTAT cs;
DWORD dwWritten,dwError;
char Buffer[2];
ClearCommError(ComPortHandle, &dwError, &cs);
if (SlowWrite)
{
// 每次写一个命令字符并且延时一段时间。
for (int i=0; i<(int)StrLen(String); i++)
{
Delay(10);
Buffer[1] = 0;
Buffer[0] = String[i];
if (!WriteFile(ComPortHandle, Buffer, 1, &dwWritten, NULL)
|| (dwWritten != 1))
return false;
}
}else
{
// 一次写完整条命令。
if (!(WriteFile(ComPortHandle, String, StrLen(String), &dwWritten, NULL))
&& (dwWritten < StrLen(String)))
return false;
FlushFileBuffers(ComPortHandle);
}
return true;
}
//---------------------------------------------------------------------------
BOOL TCommCtrl::ComReadString(char* String, DWORD BufferSize)
{
int i,j;
COMSTAT cs;
DWORD dwRead,dwError;
ClearCommError(ComPortHandle, &dwError, &cs);
for (i=0; i<(int)BufferSize; i++) String[i]=0;
// 注意:要保留缓冲区的最后一个字符空间(BufferSize-1)!
if (ReadFile(ComPortHandle, String, BufferSize-1, &dwRead, NULL)&&(dwRead>0))
{
// 删除最后的一个不可打印字符!
if (!isprint(String[dwRead-1]))
String[i]=0;
if (strlen(String))
return true;
else
return false;
}
else
return false;
}
//---------------------------------------------------------------------------
// Write: 向串口写一条命令“CommandString”。
// Read : 从串口读响应结果“RespondString”。
// Wait : 等待指定的事件“WaitType”发生,同时根据不同的等待类型传入相应的参数。
//---------------------------------------------------------------------------
BOOL TCommCtrl::ComWriteWaitRead(AnsiString CommandString, AnsiString &RespondString,
TWAITEVENT WaitType, DWORD Timeouts, AnsiString Pattern1, AnsiString Pattern2)
{
COMSTAT cs;
COMMTIMEOUTS timeouts;
DWORD dwError,dwBeginTime;
AnsiString Pattern = Pattern1;
char Buffer[255];
RespondString = "";
PurgeComm(ComPortHandle, PURGE_TXCLEAR);
PurgeComm(ComPortHandle, PURGE_RXCLEAR);
if (!ComWriteString(CommandString.c_str(), true))
return false;
switch (WaitType)
{
case WaitTillTimeout:
// 一直等待直到超时事件发生为止,需要的参数是Timeouts.
Delay(Timeouts);
break;
case WaitTillAnyCharDetected:
// 一直等待直到有字符返回为止,需要的参数是Timeouts.
dwBeginTime = GetTickCount();
while (abs(Timeouts) && !Application->Terminated)
{
Application->ProcessMessages();
if (abs(GetTickCount()-dwBeginTime) >= abs(Timeouts)) break;
////
ClearCommError(ComPortHandle, &dwError, &cs);
if ((int)cs.cbInQue > CommandString.Length()+1) break;
}
break;
case WaitTillPatternDetected:
// 一直等待直到模式匹配为止,需要的参数是Timeouts, Pattern1.
dwBeginTime = GetTickCount();
while (abs(Timeouts) && !Application->Terminated)
{
Application->ProcessMessages();
if (abs(GetTickCount()-dwBeginTime) >= abs(Timeouts)) break;
////
ClearCommError(ComPortHandle, &dwError, &cs);
if ((int)cs.cbInQue > 1)
{
ComReadString(Buffer, cs.cbInQue);
RespondString = RespondString + AnsiString(Buffer);
if (RespondString.Pos(Pattern1))
break;
}
}
break;
case RepeatWriteBetweenPatterns:
// 在两个指定的模式出现的时间段内一直重复写命令。
// 重复写命令,主要用来模拟一直按着某个键不放。
// 需要的参数是Timeouts, Pattern1, Pattern2.
GetCommTimeouts(ComPortHandle, &timeouts);
ComTimeouts(1,1,10,1,10); // 提高读写灵敏度!
dwBeginTime = GetTickCount();
while (abs(Timeouts) && !Application->Terminated)
{
Application->ProcessMessages();
if (abs(GetTickCount()-dwBeginTime) >= abs(Timeouts)) break;
////
if (Pattern == Pattern2)
ComWriteString(CommandString.c_str(), false);
ClearCommError(ComPortHandle, &dwError, &cs);
if ((int)cs.cbInQue > 1)
{
ComReadString(Buffer, cs.cbInQue);
RespondString = RespondString + AnsiString(Buffer);
if (RespondString.Pos(Pattern))
{
if (Pattern == Pattern1)
{
Pattern = Pattern2;
continue;
}else
break;
}
}
}
SetCommTimeouts(ComPortHandle, &timeouts);
break;
default:
break;
}
while (ComReadString(Buffer, sizeof(Buffer)))
RespondString = RespondString + AnsiString(Buffer);
return true;
}
//---------------------------------------------------------------------------
BOOL TCommCtrl::ComConnected(void)
{
AnsiString RespondString;
ComWriteWaitRead("\r", RespondString, WaitTillAnyCharDetected, 1000);
if (RespondString.Length())
return true;
else
return false;
}
//---------------------------------------------------------------------------
---- http://screensaver.coc.cc
原创屏保,原汁原味,每一个小程序凝聚着主人的独特构思。 |
|