?? unit1.~cpp
字號:
#include <vcl.h>
#pragma hdrstop
#include "Unit1.h"
#include "assert.h"
#include "mmsystem.h" //精確計時
HANDLE hCom = 0;
DCB dcb;
OVERLAPPED OverRead, OverWrite;
COMSTAT comstat;
OVERLAPPED os;
DWORD dwEvtMask=0;
String dat;
hComThread *Read232;
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
//內(nèi)部函數(shù)
/*常用串行通訊API函數(shù)及其作用
函數(shù)名 作用
CreateFile 打開串口
GetCommState 檢測串口設(shè)置
SetCommState 設(shè)置串口
BuilderCommDCB 用字符串中的值來填充設(shè)備控制塊
GetCommTimeouts 檢測通信超時設(shè)置
SetCommTimeouts 設(shè)置通信超時參數(shù)
SetCommMask 設(shè)定被監(jiān)控事件
WaitCommEvent 等待被監(jiān)控事件發(fā)生
WaitForMultipleObjects 等待多個被監(jiān)測對象的結(jié)果
WriteFile 發(fā)送數(shù)據(jù)
ReadFile 接收數(shù)據(jù)
GetOverlappedResult 返回最后重疊(異步)操作結(jié)果
PurgeComm 清空串口緩沖區(qū),退出所有相關(guān)操作
ClearCommError 更新串口狀態(tài)結(jié)構(gòu)體,并清除所有串口硬件錯誤
CloseHandle 關(guān)閉串行口 */
//------ Create COM ----------------------------------------------------------
int __stdcall OpenCom(int port)
{
String comname;
comname = "COM" + IntToStr(port);
if (hCom==INVALID_HANDLE_VALUE)
{
ShowMessage("Can not open the port !");
CloseHandle(hCom);
hCom = 0;
return 0;
}
if(hCom != 0)
return 0;
hCom=CreateFile( comname.c_str(), //文件名
GENERIC_READ|GENERIC_WRITE,//訪問模式允許讀寫
0, //此項必須是0
NULL,//無安全參數(shù)
OPEN_EXISTING,//創(chuàng)建方式
FILE_FLAG_OVERLAPPED,//異步工作方式
NULL);
if (hCom==INVALID_HANDLE_VALUE)
{
ShowMessage("Can not open the port !");
CloseHandle(hCom);
hCom = 0;
return 0;
}
if(!GetCommState(hCom,&dcb)) //獲得串口設(shè)置并用它填充dcb結(jié)構(gòu)體
ShowMessage("GetCommState failed");
if (!SetupComm(hCom,1024,1024)) //設(shè)置輸入輸出緩沖區(qū)大小
ShowMessage("SetupComm failed");
//設(shè)置dcb結(jié)構(gòu)成員變量
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");
//設(shè)置事件掩碼,EV_RXCHAR表示接收一個字符并放到緩沖區(qū)劃
if (!SetCommMask(hCom,EV_RXCHAR))
ShowMessage("SetCommMask failed");
//創(chuàng)建事件對象,在WaitCommEvent使用
COMSTAT comstat;
DWORD dwError=0;
OverRead.hEvent=CreateEvent(NULL,
true,
false,
NULL);
ClearCommError(hCom,&dwError,&comstat);
//清空串口緩沖區(qū),退出所有相關(guān)操作
PurgeComm(hCom, PURGE_TXCLEAR | PURGE_RXCLEAR);
Form1->Caption=comname+" 通信成功!";
Form1->RadioGroup1->Enabled=false;
// Form1->Button1->Enabled=false;
// Form1->Button2->Enabled=true;
//創(chuàng)建線程
Read232 = new hComThread(false); // (false/true) (run/not run )WatchThread when begin
return true;
}
void __fastcall SendDatas( char chStr[1024], unsigned long StrLen)
{
//發(fā)送數(shù)據(jù)
BOOL WriteState;
unsigned long Written ;
DWORD dwError;
WriteState = WriteFile(hCom,//用CreateFile 獲得的文件句柄
chStr,//輸出緩沖區(qū)首址
StrLen,//要求輸出的字節(jié)數(shù)
&Written,//實際輸出字節(jié)數(shù)
&OverWrite);//重疊操作方式數(shù)據(jù)結(jié)構(gòu)地址
if (WriteState && GetLastError()== ERROR_IO_PENDING )
{
ShowMessage("Error !!!");
}
}
bool StopCom()
{
if (hCom) //Stop COM
{
if (CloseHandle(hCom))
{
Read232->Terminate();
ShowMessage("CloseHandle(hCom) successed");
}
else
{ ShowMessage("Can not close the com !!!");
return false;
}
Form1->RadioGroup1->Enabled=true;
Form1->Caption="通信停止中";
}
else ShowMessage("The com has been stoped !!");
hCom=0;
return true;
}
//---------------------------------------------------------------------------
//線程部分
//---------------------------------------------------------------------------
__fastcall hComThread::hComThread(bool CreateSuspended)
: TThread(CreateSuspended)
{
FreeOnTerminate = true;
}
//---------------------------------------------------------------------------
void __fastcall hComThread::Execute()
{
//---- Place thread code here ----
char ReadBuff[1];
memset(&OverRead,0,sizeof(OVERLAPPED));
OverRead.hEvent=CreateEvent(NULL,true,true,NULL);
if (OverRead.hEvent==NULL) Terminate();
if (!SetCommMask(hCom,EV_RXCHAR|EV_TXEMPTY)) Terminate();
while (!Terminated)
{
WaitForSingleObject(OverRead.hEvent,INFINITE);
bool WaitComEv;
DWORD dwError;
AnsiString Gotstr;
DWORD ReadStat;
DWORD BytesRead;
//等待被監(jiān)控事件發(fā)生
WaitComEv=WaitCommEvent(hCom,&dwEvtMask,&OverRead);
if (WaitComEv)
ClearCommError(hCom,&dwError,&comstat); //更新串口狀態(tài)結(jié)構(gòu)體,并清除所有串口硬件錯誤
else if (!WaitComEv && GetLastError()==ERROR_IO_PENDING)
{
ClearCommError(hCom,&dwError,&comstat);//更新串口狀態(tài)結(jié)構(gòu)體,并清除所有串口硬件錯誤
while (comstat.cbInQue>0)// && dwEvtMask==EV_RXCHAR)使用后部分在win98中不行
{
ReadStat=ReadFile(hCom,//用CreateFile 獲得的文件句柄
ReadBuff,//輸入緩沖區(qū)首址
1, //設(shè)定讀入字節(jié)數(shù)
&BytesRead,//實際讀入字節(jié)數(shù)
&os); //重疊操作方式數(shù)據(jù)結(jié)構(gòu)地址
if (!ReadStat && GetLastError()==ERROR_IO_PENDING )
{
while (!GetOverlappedResult(hCom,&os,&BytesRead,true))
{
dwError=GetLastError();
if (dwError==ERROR_IO_INCOMPLETE)
continue;
else
break;
}
}
dat=dat+ReadBuff[0];
//更新串口狀態(tài)結(jié)構(gòu)體,并清除所有串口硬件錯誤
ClearCommError(hCom,&dwError,&comstat);
}
}
}
}
//---------------------------------------------------------------------------
//窗體部分
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button2Click(TObject *Sender)
{
//清輸入輸出緩沖區(qū)
PurgeComm(hCom, PURGE_TXCLEAR | PURGE_RXCLEAR);
dat = "";
String str; int t;
str = Memo1->Lines->GetText();
char *pt = str.c_str();
t = str.Length();
// pt[0] = 0x55; pt[1] = 0x33; pt[2] = 0x34;
SendDatas(pt, t);
Label1->Caption = "ok";
// Label1->Caption = dat;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
OpenCom(RadioGroup1->ItemIndex +1 );
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button4Click(TObject *Sender)
{
Label1->Caption = dat;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button3Click(TObject *Sender)
{
StopCom();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::BitBtn1Click(TObject *Sender)
{
// DWORD timeGetTime(void)
// 返回從Windows啟動開始經(jīng)過的毫秒數(shù)。最大值為4294967295,約49.71天。
DWORD k = 0, k0; String str = "";
k0 = timeGetTime();
while(k < 1000)
k = timeGetTime() - k0;
str =str + "1000ms,誤差1 - 2ms ";
Label1->Caption = str;
k0 = 4294967295; k = 100;//測試
k = k - k0;
if(k > 90)
k = 20;
}
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
void __fastcall TForm1::Timer1Timer(TObject *Sender)
{
Label1->Caption = dat;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::ListBox2Click(TObject *Sender)
{
int i;
DWORD dwBytesWritten;
AnsiString AtString;
i=ListBox2->ItemIndex ;
if(i<0) return;
switch(i)
{case 0:
AtString="AT+CSCA?";
break;
case 1:
AtString="AT+CMGL=0;
break;
case 2:
//AtString="AT+CPMS=1";
AtString="AT+CMGL=1";
break;
case 3:
AtString="ATA";
break;
case 4:
AtString="AT+CHUP";
break;
case 5:
AtString="ATD13337319991;";
break;
case 6:
AtString="ATH0";
break;
case 7:
AtString="AT+CMGF?";
}
AtString=AtString+char(13);
Memo1->Text =AtString;
Button2Click(Button2);
//dwBytesWritten =AtString.Length() ;
//com2.write(AtString.c_str() , dwBytesWritten);
}
//---------------------------------------------------------------------------
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -