?? pasmycomm.pas
字號:
unit pasMyComm;
interface
uses
Windows,Messages,SysUtils,Classes,Graphics,Controls,Forms,Dialogs;
type
//分配單獨(dú)的線程
TReadThread=class(TThread)
protected
//重載Excute函數(shù)
procedure Execute;override;
public
hCommFile:THandle; //作為一個文件打開的串口
bReadThread:boolean; //讀寫線程的標(biāo)志
end;
//繼承TComponent的子類TComm
TComm=class(TComponent)
private
hCommFile:THandle; //作為一個文件打開的串口
ReadThread:TReadThread; //讀線程
procedure CloseReadThread;
public
bOpened:boolean; //串口是否打開
CommName:string; //串口名稱
INQUESIZE,QUTQUESIZE:integer; //讀寫緩沖隊(duì)列長度
//重載構(gòu)造函數(shù)
constructor Create(AOwner:TComponent);override;
//重載析構(gòu)函數(shù)
destructor Destroy;override;
//初始化串口
function InitComm(ThisCommName:string;BaudRate,DataByte,StopByte,ParityByte:integer):boolean;
//釋放串口
procedure FreeComm;
//串口操作
function WriteData(pDataToWrite:PChar;dwSizeofDataToWrite:DWord):boolean; //寫數(shù)據(jù)
function WriteDelayData(pDataToWrite:PChar;dwSizeofDataToWrite:DWord):boolean; //延遲寫數(shù)據(jù)
function ReadData(pBuffer:pChar;BufferSize:DWord):boolean; //讀數(shù)據(jù)
function BytesInInQue:DWord; //輸入隊(duì)列中數(shù)據(jù)長度
function BytesInOutQue:DWord; //輸出隊(duì)列中數(shù)據(jù)長度
function WaitForBytes(Bytes:DWord;TimeLen:DWord):boolean; //等待讀入數(shù)據(jù)
procedure ClearComm; //清除串口數(shù)據(jù)
procedure SendStr(str:String); //發(fā)送字符串?dāng)?shù)據(jù)
function OutputByte(const ByteData:array of Byte):Boolean;
function GetCheckResult: boolean;
end;
const
PWM_COMMWRITE=WM_USER+1;
implementation
//構(gòu)造函數(shù),初始化變量
constructor TComm.Create(AOWner:TComponent);
begin
inherited Create(AOwner);
ReadThread:=nil;
hCommFile:=0;
bOpened:=False;
//缺省隊(duì)列長度
INQUESIZE:=129600;
QUTQUESIZE:=129600;
end;
//析構(gòu)函數(shù),釋放串口
destructor TComm.Destroy;
begin
FreeComm;
inherited Destroy; //執(zhí)行父類的析構(gòu)函數(shù)
end;
//初始化串口
function TComm.InitComm(ThisCommName:string;BaudRate,DataByte,StopByte,ParityByte:integer):boolean;
var
dcb:Tdcb; //Data Control Block 控制信息
begin
//判斷有沒有打開該串口
if hCommFile<>0 then
begin
InitComm:=False;
exit;
end;
//用CreateFile打開串口
hCommFile:=CreateFile(pChar(ThisCommName),GENERIC_READ or GENERIC_WRITE,0,{not shared}nil,{no security ??}OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);
//如果打開失敗
if hCommFile=INVALID_HANDLE_VALUE then
begin
hCommFile:=0;
InitComm:=False;
exit;
end;
//如果打開的文件類型不是FILE_TYPE_CHAR也算失敗,則關(guān)閉文件
if GetFileType(hCommFile)<>FILE_TYPE_CHAR then
begin
CloseHandle(hCommFile);
hCommFile:=0;
InitComm:=False;
exit;
end;
//如果設(shè)置失敗,則關(guān)閉文件
if not SetupComm(hCommFile,INQUESIZE,QUTQUESIZE) then
begin
CloseHandle(hCommFile);
hCommFile:=0;
InitComm:=False;
exit;
end;
//讀入串口信息
PurgeComm(hCommFile,PURGE_TXABORT or PURGE_RXABORT or PURGE_TXCLEAR or PURGE_RXCLEAR);
GetCommState(hCommFile,dcb);
//設(shè)置串口參數(shù)
dcb.BaudRate:=BaudRate; //波特率
dcb.ByteSize:=DataByte; //數(shù)據(jù)位數(shù),如每byte4-8個bit
dcb.Parity:=ParityByte; //是否有校驗(yàn)位0-4=no,odd,even,mark,space
dcb.StopBits:=StopByte; //停止位,0,1,2=1,1.5,2
dcb.Flags:=1;
//如果設(shè)置串口參數(shù)失敗,則關(guān)閉文件
if not SetCommState(hCommFile,dcb) then
begin
CloseHandle(hCommFile);
hCommFile:=0;
InitComm:=False;
exit;
end;
//設(shè)置打開文件成功標(biāo)志
InitComm:=True;
bOpened:=True;
CommName:=ThisCommName;
end;
//釋放串口
procedure Tcomm.FreeComm;
begin
if hCommFile=0 then exit; //如果沒有打開的串口,則直接退出
//關(guān)閉讀數(shù)據(jù)線程
CloseReadThread;
//關(guān)閉文件
PurgeComm(hCommFile,PURGE_RXABORT+PURGE_RXCLEAR+PURGE_TXABORT+PURGE_TXCLEAR);
CloseHandle(hCommFile);
bOpened:=False;
end;
//調(diào)用WriteFile向串口寫數(shù)據(jù)
function TComm.WriteData(pDataToWrite:PChar;dwSizeofDataToWrite:DWord):boolean;
var
nSent:DWord;
begin
Result:=WriteFile(hCommFile,pDataToWrite^,dwSizeofDataToWrite,nSent,Nil);
end;
//調(diào)用WriteFile和sleep向串口延遲寫數(shù)據(jù)
function TComm.WriteDelayData(pDataToWrite:PChar;dwSizeofDataToWrite:DWord):boolean;
var
nSent:DWord;
i:integer;
begin
Result:=False;
for i:=1 to dwSizeofDataToWrite do
begin
Result:=WriteFile(hCommFile,(i-1+pDataToWrite)^,dwSizeofDataToWrite,nSent,Nil);
Sleep(50); //延遲一段時間再寫下一段數(shù)據(jù)
end;
end;
//發(fā)送字符串
procedure TComm.SendStr(str:String);
begin
str:=str+Chr(13)+Chr(10); //添加回車,換行
WriteData(pChar(str),Length(str));
end;
//調(diào)用ReadFile讀入數(shù)據(jù)
function Tcomm.ReadData(pBuffer:pChar;BufferSize:DWord):boolean;
var
nRead:DWord;
begin
Result:=ReadFile(hCommFile,pBuffer^,BufferSize,nRead,Nil);
end;
//通過CloseEvent事件關(guān)閉讀線程
procedure TComm.CloseReadThread;
begin
//如果讀線程存在則關(guān)閉
if ReadThread<>nil then
begin
ReadThread.bReadThread:=False;
//清除讀的數(shù)據(jù)
PurgeComm(hCommFile,PURGE_RXABORT+PURGE_RXCLEAR);
//等待一段時間,結(jié)束線程
if(WaitForSingleObject(ReadThread.Handle,10000)=WAIT_TIMEOUT) then
ReadThread.Terminate;
ReadThread.Free;
ReadThread:=nil;
end;
end;
//返回輸入隊(duì)列中數(shù)據(jù)的長度
function TComm.BytesInInQue:DWord;
var
stat:TCOMSTAT;
errs:DWord;
begin
ClearCommError(hCommFile,errs,@stat);
Result:=stat.cbInQue;
end;
//返回輸出隊(duì)列中數(shù)據(jù)的長度
function TComm.BytesInOutQue:DWord;
var
stat:TCOMSTAT;
errs:DWord;
begin
ClearCommError(hCommFile,errs,@stat);
Result:=stat.cbOutQue;
end;
//等待數(shù)據(jù)
function TComm.WaitForBytes(Bytes:DWord;TimeLen:DWord):boolean;
var
time1,time2:DWord;
begin
//得到當(dāng)前時間
time1:=GetTickCount;
time2:=time1;
//循環(huán)等待,直到TimeLen秒或讀入Bytes個數(shù)據(jù)
while (BytesInInQue<Bytes) and (hCommFile<>0) and ((time2-time1)<TimeLen) do
begin
Application.ProcessMessages;
time2:=GetTickCount;
end;
//返回是否成功讀入Bytes個數(shù)據(jù)
if BytesInInQue>=Bytes then
Result:=True
else
Result:=False;
end;
//清除串口
procedure TComm.ClearComm;
begin
PurgeComm(hCommFile,PURGE_TXABORT or PURGE_RXABORT or PURGE_TXCLEAR or PURGE_RXCLEAR);
end;
//傳送二進(jìn)制的數(shù)據(jù)
function TComm.OutputByte(const ByteData: array of Byte ): Boolean;
var
lrc: LongWord;
i: Integer;
begin
for i:=Low(ByteData) to High(ByteData) do
WriteFile(hCommFile,ByteData[i],1,lrc, nil);
Result := True;
end;
//讀數(shù)據(jù)線程
procedure TReadThread.Execute;
begin
while bReadThread do
begin
end;
end;
//設(shè)置校驗(yàn)項(xiàng)目
function TComm.GetCheckResult:boolean;
var
dwEventMask: DWORD;
stat:TCOMSTAT;
errs:DWord;
begin
Result:=TRUE;
dwEventMask:=0;
SetCommMask(hCommFile,EV_ERR);
ClearCommError(hCommFile,errs,@stat);
WaitCommEvent(hCommFile,dwEventMask,nil);
if ((dwEventMask and EV_ERR)=EV_ERR) then
Result:=FALSE;
end;
end.
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -