comm.cpp

来自「本源码主要是通过API函数实现串口打开」· C++ 代码 · 共 202 行

CPP
202
字号
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "Comm.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
__fastcall TComm::TComm()
{
    //TODO: Add your source code here
}
__fastcall TComm::~TComm(){
    //TODO: Add your source code here
}
bool __fastcall TComm::openport(String port,String baud,int &result)
{
    bool errflg;
    DCB *dcb;                   //当前串口设备控制块 Device Control Block
     COMMTIMEOUTS*InterTime;    //串口超时参数设置
    /*COMMTIMEOUTS 结构:
      typedef struct _COMMTIMEOUTS {
           DWORD ReadIntervalTimeout;         //两字符之间最大的延时,当读取串口数据时,一旦两个字符传输的时间差超过该时间,读取函数将返回现有的数据。设置为0表示该参数不起作用
           DWORD ReadTotalTimeoutMultiplier;  // 读取每字符间的超时
           DWORD ReadTotalTimeoutConstant;    //一次读取串口数据的固定超时。
           DWORD WriteTotalTimeoutMultiplier; //写入每字符间的超时
           DWORD WriteTotalTimeoutConstant;   //一次写入串口数据的固定超时
    } COMMTIMEOUTS,*LPCOMMTIMEOUTS;
*/
    LPCTSTR portnum;
    int i,j;
    String str;
    result = 0;
    errflg = false;
    dcb = new DCB;      //
    InterTime = new COMMTIMEOUTS;  //
    try{
        j = port.Length();
        if(j==0) throw Exception("串行口不存在");
        str = "\\\\.\\";
        str += port;
        portnum = str.c_str(); //COM1\COM2\COM3......
        //用指定的方式打开指定的串口。ComHandle为文件句柄
        ComHandle=CreateFile(portnum,GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,0,NULL);
        if (ComHandle==INVALID_HANDLE_VALUE)
        {
            ComHandle=0;
            //throw Exception("试图打开串口"+port+"失败");
        }
        //调用GetCommState(ComHandle,dcb)读取当前串口设备控制块DCB设置
        GetCommState(ComHandle,dcb);
        dcb->BaudRate = baud.ToInt();
        dcb->ByteSize = 8;
        dcb->Parity = 0;
        dcb->StopBits = 0;
        if(!SetCommState(ComHandle,dcb)){
            ComHandle=0;

            throw Exception("设置串口失败,其原因是"+IntToStr(GetLastError()));
        }
        // Set input buffer size to 16k, output buffer size to 1k.
        if(!SetupComm(ComHandle,0x4000,0x400)){ //SetupComm:设置串口输入、输出缓冲区。
            ComHandle=0;
            
            throw Exception("Set I/O buffer failture.");
        }
        GetCommTimeouts(ComHandle,InterTime);
        //接收相邻两个字节所允许的最大时间间隔(ms).
        InterTime->ReadIntervalTimeout=MAXDWORD;
        //接收一个字节平均所用时间(ms).
        InterTime->ReadTotalTimeoutMultiplier=0;
        // 此参数+上个参数*读取的字节数=总共允许的等待时间。
        InterTime->ReadTotalTimeoutConstant=0;
        InterTime->WriteTotalTimeoutMultiplier=0;
        InterTime->WriteTotalTimeoutConstant=30;
        SetCommTimeouts(ComHandle,InterTime);
    }
    catch(Exception&E){
        result = 1;
        //MessageDlg(E.Message,mtWarning,TMsgDlgButtons()<<mbOK,0);
        errflg = true;
    }
    delete dcb;
    delete InterTime;
    return errflg;
}
bool __fastcall TComm::WriteCom(String str)
{
    int i;
    BYTE txbuf[1024];
    unsigned long byteswriten;
    // 实际输出的有效数据的个数。
    try{
        if(ComHandle==0){
            
            throw Exception("串口未打开");
        }
        for(i=0;i<str.Length();i++)
        {
            txbuf[i]=(str[i+1]);
        }
        if(!WriteFile(ComHandle,txbuf,str.Length(),&byteswriten,NULL)){
            
            throw Exception(IntToStr(GetLastError())); //写入串口失败
        }
        //else
        //{
        //    purge_comm(TxClear);
        //}
    }
    catch(Exception&E){
        //ShowMessage(E.Message);
        return false;
    }
    return true;
}
unsigned long __fastcall TComm::ReadCom(char * array)
{
    unsigned long count;
    try{
        if(ComHandle==0){
            return 0;
        }
        ReadFile(ComHandle,array,2048,&count,NULL);
        //purge_comm(RxClear);
        return count;    //返回串口实际读出的有效数据的个数
    }
    catch(Exception&E){
        //ShowMessage(E.Message);
        return 0;
    }
}
void __fastcall TComm::purge_comm(int type)
{
    try{
        if(ComHandle==0){
           
            throw Exception("串口未打开");
        }
        switch(type){
            case TxAbort:   PurgeComm(ComHandle,PURGE_TXABORT);
            break;
            case RxAbort:   PurgeComm(ComHandle,PURGE_TXABORT);
            break;
            case TxClear:   PurgeComm(ComHandle,PURGE_TXCLEAR);
            break;
            case RxClear:   PurgeComm(ComHandle,PURGE_RXCLEAR);
            default :       break;
        }
    }
    catch(Exception&E){
        //ShowMessage(E.Message);
    }
}
void __fastcall TComm::ClosePort()
{
    try{
        if(ComHandle==0)
        return;
        if(!CloseHandle(ComHandle)){
           
            throw Exception("串口未关闭");
        }
    }
    catch(Exception&E){
        //ShowMessage(E.Message);
    }
}
unsigned long __fastcall TComm::GetModemStatus()
{
    unsigned long status;
    try{
        if(ComHandle==0){
            return 0;
            // throw Exception("串口未打开");
        }
         //返回调制解调器Modem控制登录值
        GetCommModemStatus(ComHandle,&status);

        return status;
    }
    catch(Exception&E){
        //                ShowMessage(E.Message);
        return 0;
    }
}
unsigned long __fastcall TComm::ClearError()
{
    unsigned long error;
    try{
        if(ComHandle==0){
            return 0;
            //        throw Exception("串口未打开");
        }
        //purge_comm(RxClear);
        ClearCommError(ComHandle,&error,NULL);  //允许出错后进行通信
        return error;
    }
    catch(Exception&E){
        //ShowMessage(E.Message);
        return 0;
    }
}
//------------ FormatC 03-9-1 12:46:23 ------------

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?