?? 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;
//---------------------------------------------------------------------------
//內部函數(shù)
/*常用串行通訊API函數(shù)及其作用
函數(shù)名 作用
CreateFile 打開串口
GetCommState 檢測串口設置
SetCommState 設置串口
BuilderCommDCB 用字符串中的值來填充設備控制塊
GetCommTimeouts 檢測通信超時設置
SetCommTimeouts 設置通信超時參數(shù)
SetCommMask 設定被監(jiān)控事件
WaitCommEvent 等待被監(jiān)控事件發(fā)生
WaitForMultipleObjects 等待多個被監(jiān)測對象的結果
WriteFile 發(fā)送數(shù)據(jù)
ReadFile 接收數(shù)據(jù)
GetOverlappedResult 返回最后重疊(異步)操作結果
PurgeComm 清空串口緩沖區(qū),退出所有相關操作
ClearCommError 更新串口狀態(tài)結構體,并清除所有串口硬件錯誤
CloseHandle 關閉串行口 */
//------ 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)) //獲得串口設置并用它填充dcb結構體
ShowMessage("GetCommState failed");
if (!SetupComm(hCom,1024,1024)) //設置輸入輸出緩沖區(qū)大小
ShowMessage("SetupComm failed");
//設置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");
//設置事件掩碼,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ū),退出所有相關操作
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ù)結構地址
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)結構體,并清除所有串口硬件錯誤
else if (!WaitComEv && GetLastError()==ERROR_IO_PENDING)
{
ClearCommError(hCom,&dwError,&comstat);//更新串口狀態(tài)結構體,并清除所有串口硬件錯誤
while (comstat.cbInQue>0)// && dwEvtMask==EV_RXCHAR)使用后部分在win98中不行
{
ReadStat=ReadFile(hCom,//用CreateFile 獲得的文件句柄
ReadBuff,//輸入緩沖區(qū)首址
1, //設定讀入字節(jié)數(shù)
&BytesRead,//實際讀入字節(jié)數(shù)
&os); //重疊操作方式數(shù)據(jù)結構地址
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)結構體,并清除所有串口硬件錯誤
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);
}
//---------------------------------------------------------------------------
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -