BCB中使用API函数写简单串口程序(定时器接收)

一:常用函数:

⑴CreateFile()和CloseHandle()函数。用于打开和关闭串口,函数原型如下:

HANDLE CreateFile(LPCTSTR lpFileName,DWORD dwDesiredAccess, DWORD dwShareMode,LPSECURITY_ATTRIBUTES lpSecurityAttributes,DWORD dwCreationDistribution,DWORD dwFlagsAndAttributes,HANDLE hTemplateFile);
BOOL CloseHandle(HANDLE hObjedt);

⑵GetCommState()和SetCommState()函数。用于取得和设置串口工作状态,函数原型如下:

BOOL GetCommState/SetCommState(HANDLE hFile,LPDCB lpDCB);这两个函数常用来初始化串口,其中涉及到的几个常用的DCB 结构参数是:DWORD BaudRate:串口波特率;DWORD fParity:为1 时激活奇偶校验检查;DWORD Parity:校验方式,0~4 分别对应无校验、奇校验、偶校验、校验置位、校验清零;DWORD ByteSize:数据位个数,范围是5~8;DWORD StopBits:停止位个数,0~2 分别对应1

位、1.5 位、2 位停止位。
⑶GetCommTimeouts()和SetCommTimeouts()
用于取得和设置串口数据收发的超时时间,通过改变COMMTIMEOUTS 结构体的成员变量值来实现,函数原型如下:BOOL GetCommTimeouts/SetCommTimeouts
(HANDLE hFile,LPCOMMTIMEOUTS lpCommTimeouts);其中,参数COMMTIMEOUTS 是一个表达读写操作相关时间限制的结构体,其原型为:
typedef struct _COMMTIMEOUTS{ DWORD ReadIntervalTimeout;DWORD ReadTotalTimeoutMultiplier;DWORD ReadTotalTimeoutConstant;DWORD WriteTotalTimeoutMultiplier;DWORD WriteTotalTimeoutConstant;} COMMTIMEOUTS, *LPCOMMTIMEOUTS;

⑷SetupComm()和PurgeComm()函数用于设置数据缓冲区的大小和清零数据缓冲区,函数原型如下:

BOOL SetupComm(HANDLE hFile,DWORD dwInQueue, DWORD dwOutQueue);BOOL PurgeComm(HANDLE hFile,DWORD dwFlags);

⑸ReadFile()和WriteFile()函数用于读写访问串口作,函数原型如下:BOOL ReadFile/WriteFile (HANDLE hFile,LPCVOID lpBuffer,DWORD nNumberOfBytesToRead/Write,LPDWORD lpNumberOfBytesRead/Written,LPOVERLAPPED lpOverlapped);
参数lpBuffer 表示待读或写的数据首地址,nNumberOfBytesToRead/Write 表示待读出或写入数据的字节数长度,lpNumberOfBytesRead 收入从串口实际读出的字节个数;lpNumberOfBytesWritten 收入实际写入串口的数据个数,lpOverlapped 是指向一个可重叠型的I/O 结构的指针。

⑹ClearCommError()函数用于清除串口错误或者读取串口当前的状态,

函数原型如下:BOOL ClearCommError(HANDLE hFile,LPDWORD lpErrors, LPCOMATAT lpStat);

⑺Get/SetCommMask()和WaitCommEvent()

用于获得、设置或等待串行端口上的监视指定事件,函数原型如下:BOOL Set/GetCommMask(HANDLE hFile,DWORD dwEvtMask);BOOL WaitCommEvent(HANDLE hFile, LPDWORDlpEvtMask, LPOVERLAPPED lpOverlapped);

二:例程

1.定义变量

bool ComState = FALSE;   //串口状态
HANDLE hCom = 0;           //串口打开返回值
DCB dcb;
OVERLAPPED OverRead, OverWrite;
COMSTAT comstat;
OVERLAPPED os;
DWORD dwEvtMask=0;
String dat;
HANDLE m_pThread;

COMMTIMEOUTS ComTimeouts;

char ReadBuff[1024];        //读缓冲区
DWORD ReadCount;        //读字节数

2.串口初始化

void __fastcall TForm1::btn1ClickSerialPortInit(TObject *Sender)
{
                AnsiString comname;
        if(FALSE == ComState)
        {
            comname = "COM" + IntToStr(3);

            hCom=CreateFile( "COM3", //文件名
                             GENERIC_READ|GENERIC_WRITE,//访问模式允许读写
                             0, //此项必须是0
                             NULL,//无安全参数
                             OPEN_EXISTING,//创建方式
                          //   FILE_FLAG_OVERLAPPED,//异步工作方式
                            0,
                             NULL);
            if (hCom==INVALID_HANDLE_VALUE)
            {
                    ShowMessage("Can not open the port !");
                    CloseHandle(hCom);
                    hCom = 0;

            }

            if(!GetCommState(hCom,&dcb)) //获得串口设置并用它填充dcb结构体
            {
                ShowMessage("GetCommState failed");
            }      

            if (!SetupComm(hCom,1024,1024)) //设置输入输出缓冲区大小
            {
                ShowMessage("SetupComm failed");
            }

            // 设置接收超时限定

            ComTimeouts.ReadIntervalTimeout = MAXDWORD;
            ComTimeouts.ReadTotalTimeoutMultiplier = MAXDWORD;
            ComTimeouts.ReadTotalTimeoutConstant = 1000;
            SetCommTimeouts(hCom,&ComTimeouts);


            //设置dcb结构成员变量
            dcb.BaudRate=9600;
            dcb.fParity=0;
            dcb.Parity=NOPARITY;
            dcb.StopBits=ONESTOPBIT;
            dcb.ByteSize=8;
            dcb.fNull=FALSE;

            if(!SetCommState(hCom,&dcb)) //重新配置串口
            {
                ShowMessage("SetCommState failed");
            }

            //清空串口缓冲区,退出所有相关操作
            PurgeComm(hCom, PURGE_TXCLEAR | PURGE_RXCLEAR);
            Form1->Caption=comname+" 通信成功!";

//-----------------------------------------------------------------------------------------
            ComState = TRUE;
            btn1->SetTextBuf("关闭串口");
        }
        else
        {
            CloseHandle(hCom);

            ComState = FALSE;
            btn1->SetTextBuf("打开串口");
        }


}
//---------------------------------------------------------------------------

2.发送函数

void __fastcall TForm1::btn2ClickSendData(TObject *Sender)
{
         //发送数据
        BOOL WriteState;
        unsigned long Written ;
        DWORD dwError;

        int Size = EditSndData->GetTextLen(); //Get length of string in Edit1
        char *p = new char[Size];               //Creates Buffer dynamic variable
   //分配内存,必须有,要不然程序会出现错误
        EditSndData->GetTextBuf(p,Size);

        WriteState = WriteFile(hCom,//用CreateFile 获得的文件句柄
                                p,//输出缓冲区首址
                                Size,//要求输出的字节数
                                &Written,//实际输出字节数
                                &OverWrite);//重叠操作方式数据结构地址

        if (WriteState && GetLastError()== ERROR_IO_PENDING )
        {
             ShowMessage("Error !!!");
        }
        
}

3.接收数据(定时查询接收)

void __fastcall TForm1::tmr1TimerReceiveData(TObject *Sender)
{
             //TODO: Add your source code here
 

        DWORD nBytesRead, dwEvent, dwError;
          COMSTAT cs; // 用于存放串口状态

          if(hCom==INVALID_HANDLE_VALUE) return;
          ClearCommError(hCom,&dwError,&cs);
          if(cs.cbInQue>sizeof(ReadBuff))
          {
                PurgeComm(hCom, PURGE_RXCLEAR);
                 return;
          } // 数据多于缓冲区?是:接收数据无效,清除
          ReadFile (hCom, ReadBuff, cs.cbInQue, &nBytesRead,
          NULL); // 读取接收数据
            ReadBuff[cs.cbInQue] = '\0';
          if(cs.cbInQue > 0)
          {
                 EditRcvData->Text = ReadBuff; // 将数据显示出来
          }
        

}


你可能感兴趣的:(数据结构,工作,api,String,null,attributes)