精华区 [关闭][返回]

当前位置:网易精华区>>讨论区精华>>编程开发>>C/C++>>硬件、外设相关>>串口专题>>庆祝我的1000分大关,放送BCB的串口控件源码

主题:庆祝我的1000分大关,放送BCB的串口控件源码
发信人: 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
原创屏保,原汁原味,每一个小程序凝聚着主人的独特构思。
    

[关闭][返回]