unit GetData;interface{ Units used by this unit }
uses
Windows,
Messages,
SysUtils,
Dialogs,
ExtCtrls ; { 调用此函数可以得到重量 ,调用成功返回true,失败返回false,取回的重量在sWeight
内,返回值为string 型 }
function GetWeight(var sWeight:string;tmp:integer=4):boolean;implementationconst
{ Current port number 此值为串口号,根据实际情况可能要修改}
int_PortNumber = 1;
{ Current baud rate }
int_BaudRate = 1200;
{ Current Data bits per byts }
int_DataBits = 7 ;
{ Current Stop bits per byte }
int_StopBits = 2;
{ Current Parity (No/Odd/Even/Mark/Space = 0-4) }
byt_Parity = 2 ;
{ Response terminator string }
sInTerminator = chr($0A); //chr($02);
var
{ Handle of currently open port }
int_PortHandle: Cardinal =INVALID_HANDLE_VALUE;
//int_PortHandle: LongInt =INVALID_HANDLE_VALUE;
{ Set true when a timeout occurs }
boo_TimerExpired: Boolean;
{ True while port is blocked, waiting for response }
boo_InUse: Boolean = False;
{ Wait for the timer to time-out when polling for response }
boo_WaitForResp : boolean = False;
procedure CloseComm;
begin
if int_PortHandle <> INVALID_HANDLE_VALUE then
begin
CloseHandle(int_PortHandle);
int_PortHandle := INVALID_HANDLE_VALUE;
end;
end;function OpenComm: Boolean;
var
str_Com: String;
dcbPort: TDCB; {device control block }
commtimeouts:TCommTimeouts;
begin
{ close port if open already }
if int_PortHandle <> INVALID_HANDLE_VALUE then CloseComm;
{ try to open the port }
str_Com := 'COM' + IntToStr(int_PortNumber);
int_PortHandle := CreateFile(PChar(str_Com),
GENERIC_READ or GENERIC_WRITE,0,nil,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,LongInt(0));
{ If created stream ok, set the baud rate and other parameters }
if (int_PortHandle <> INVALID_HANDLE_VALUE) then
begin
SetupComm(int_PortHandle,1000,1000);
if GetCommState(int_PortHandle, dcbPort) then
begin
{ fill in the fields of the structure }
dcbPort.BaudRate := int_BaudRate;
dcbPort.ByteSize := int_DataBits;
dcbPort.Parity := byt_Parity;
dcbPort.StopBits := int_StopBits;
dcbPort.Flags := 0 ;
dcbPort.Flags := dcbPort.Flags or $10 or $1000;
{ UNSUPPORTED flag bit fields:
dcb_Binary, dcb_Parity, dcb_OutxCtsFlow, dcb_fOutxDsrFlow,
dcb_fOutX, dcb_fInX, dcb_DtrFlow, dcb_RtsFlow}
SetCommState(int_PortHandle, dcbPort);
end;
GetCommTimeouts( int_PortHandle, commtimeouts );
commtimeouts.ReadIntervalTimeout:=100;
commtimeouts.ReadTotalTimeoutMultiplier:= 0;
commtimeouts.ReadTotalTimeoutConstant:= 0;
commtimeouts.WriteTotalTimeoutMultiplier:= 0;
commtimeouts.WriteTotalTimeoutConstant:= 0;
SetCommTimeouts(int_PortHandle,commtimeouts );
end;
{ return True if handle is valid }
Result := (int_PortHandle <> INVALID_HANDLE_VALUE);
end;
{------------------------------------------------------------------------------
Flush the port by reading any characters in the queue
}
procedure Flush;
begin
if int_PortHandle <> INVALID_HANDLE_VALUE then
begin
PurgeComm(int_PortHandle, PURGE_TXABORT);
PurgeComm(int_PortHandle, PURGE_RXABORT);
PurgeComm(int_PortHandle, PURGE_TXCLEAR);
PurgeComm(int_PortHandle, PURGE_RXCLEAR );
end;
end;
{------------------------------------------------------------------------------
Write a string out the COM port, return true if all chars written
}
function WriteComm(const sData: String): Boolean;
var
dwCharsWritten: DWord;
dcbPort : TDCB ;
begin
Result := False; { default to error return }
if GetCommState(int_PortHandle, dcbPort) then
begin
{ fill in the fields of the structure }
dcbPort.Flags := dcbPort.Flags or $10;
SetCommState(int_PortHandle, dcbPort);
end;
if int_PortHandle <> INVALID_HANDLE_VALUE then
begin
dwCharsWritten := 0;
flush;
WriteFile(int_PortHandle, PChar(sData)^, Length(sData), dwCharsWritten, nil);
if dwCharsWritten = Cardinal(Length(sData)) then Result := True;
end;
end;
uses
Windows,
Messages,
SysUtils,
Dialogs,
ExtCtrls ; { 调用此函数可以得到重量 ,调用成功返回true,失败返回false,取回的重量在sWeight
内,返回值为string 型 }
function GetWeight(var sWeight:string;tmp:integer=4):boolean;implementationconst
{ Current port number 此值为串口号,根据实际情况可能要修改}
int_PortNumber = 1;
{ Current baud rate }
int_BaudRate = 1200;
{ Current Data bits per byts }
int_DataBits = 7 ;
{ Current Stop bits per byte }
int_StopBits = 2;
{ Current Parity (No/Odd/Even/Mark/Space = 0-4) }
byt_Parity = 2 ;
{ Response terminator string }
sInTerminator = chr($0A); //chr($02);
var
{ Handle of currently open port }
int_PortHandle: Cardinal =INVALID_HANDLE_VALUE;
//int_PortHandle: LongInt =INVALID_HANDLE_VALUE;
{ Set true when a timeout occurs }
boo_TimerExpired: Boolean;
{ True while port is blocked, waiting for response }
boo_InUse: Boolean = False;
{ Wait for the timer to time-out when polling for response }
boo_WaitForResp : boolean = False;
procedure CloseComm;
begin
if int_PortHandle <> INVALID_HANDLE_VALUE then
begin
CloseHandle(int_PortHandle);
int_PortHandle := INVALID_HANDLE_VALUE;
end;
end;function OpenComm: Boolean;
var
str_Com: String;
dcbPort: TDCB; {device control block }
commtimeouts:TCommTimeouts;
begin
{ close port if open already }
if int_PortHandle <> INVALID_HANDLE_VALUE then CloseComm;
{ try to open the port }
str_Com := 'COM' + IntToStr(int_PortNumber);
int_PortHandle := CreateFile(PChar(str_Com),
GENERIC_READ or GENERIC_WRITE,0,nil,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,LongInt(0));
{ If created stream ok, set the baud rate and other parameters }
if (int_PortHandle <> INVALID_HANDLE_VALUE) then
begin
SetupComm(int_PortHandle,1000,1000);
if GetCommState(int_PortHandle, dcbPort) then
begin
{ fill in the fields of the structure }
dcbPort.BaudRate := int_BaudRate;
dcbPort.ByteSize := int_DataBits;
dcbPort.Parity := byt_Parity;
dcbPort.StopBits := int_StopBits;
dcbPort.Flags := 0 ;
dcbPort.Flags := dcbPort.Flags or $10 or $1000;
{ UNSUPPORTED flag bit fields:
dcb_Binary, dcb_Parity, dcb_OutxCtsFlow, dcb_fOutxDsrFlow,
dcb_fOutX, dcb_fInX, dcb_DtrFlow, dcb_RtsFlow}
SetCommState(int_PortHandle, dcbPort);
end;
GetCommTimeouts( int_PortHandle, commtimeouts );
commtimeouts.ReadIntervalTimeout:=100;
commtimeouts.ReadTotalTimeoutMultiplier:= 0;
commtimeouts.ReadTotalTimeoutConstant:= 0;
commtimeouts.WriteTotalTimeoutMultiplier:= 0;
commtimeouts.WriteTotalTimeoutConstant:= 0;
SetCommTimeouts(int_PortHandle,commtimeouts );
end;
{ return True if handle is valid }
Result := (int_PortHandle <> INVALID_HANDLE_VALUE);
end;
{------------------------------------------------------------------------------
Flush the port by reading any characters in the queue
}
procedure Flush;
begin
if int_PortHandle <> INVALID_HANDLE_VALUE then
begin
PurgeComm(int_PortHandle, PURGE_TXABORT);
PurgeComm(int_PortHandle, PURGE_RXABORT);
PurgeComm(int_PortHandle, PURGE_TXCLEAR);
PurgeComm(int_PortHandle, PURGE_RXCLEAR );
end;
end;
{------------------------------------------------------------------------------
Write a string out the COM port, return true if all chars written
}
function WriteComm(const sData: String): Boolean;
var
dwCharsWritten: DWord;
dcbPort : TDCB ;
begin
Result := False; { default to error return }
if GetCommState(int_PortHandle, dcbPort) then
begin
{ fill in the fields of the structure }
dcbPort.Flags := dcbPort.Flags or $10;
SetCommState(int_PortHandle, dcbPort);
end;
if int_PortHandle <> INVALID_HANDLE_VALUE then
begin
dwCharsWritten := 0;
flush;
WriteFile(int_PortHandle, PChar(sData)^, Length(sData), dwCharsWritten, nil);
if dwCharsWritten = Cardinal(Length(sData)) then Result := True;
end;
end;
Return the number of bytes waiting in the queue
}
function GetInCount: LongInt;
var
statPort: TCOMSTAT;
dwErrorCode: DWord;
// b:BOOLEAN;
begin
Result := 0;
if int_PortHandle <> INVALID_HANDLE_VALUE then
begin
if (ClearCommError(int_PortHandle, dwErrorCode, @statPort))then
Result := statPort.cbInQue
else
Result := 0;
end;
end;function ReadComm: String;
const
BUF_LEN = 1024;
var
cbCharsAvailable, cbCharsRead: DWord;
boo_FoundTerm: Boolean;
sBuffer: String;
TimeCount : integer;
dcbPort: TDCB;
begin
Result:='';
{ check boo_InUse in case of rentrancy }
if not boo_InUse then
begin
boo_InUse := True;
if GetCommState(int_PortHandle, dcbPort) then
begin
{ fill in the fields of the structure }
dcbPort.Flags := dcbPort.Flags or $1000;
SetCommState(int_PortHandle, dcbPort);
end;
if int_PortHandle <> INVALID_HANDLE_VALUE then
begin
{ if no terminator is defined, simply read any available data and return }
if (Length(sInTerminator) = 0) AND (NOT boo_WaitForResp) then
begin
cbCharsAvailable := GetInCount;
if cbCharsAvailable > 0 then
begin
SetLength(sBuffer, cbCharsAvailable + 1); { allocate space }
ReadFile(int_PortHandle, PChar(sBuffer)^, cbCharsAvailable, cbCharsRead, nil);
SetLength(sBuffer, cbCharsRead); { adjust length }
Result := sBuffer;
end;
end
else { a terminator is defined, so read port until terminator found or timed out }
begin
boo_FoundTerm := False;
boo_TimerExpired := False;
{ loop until timeout or terminator recieved }
TimeCount := 100;
repeat
cbCharsAvailable := GetInCount;
if cbCharsAvailable > 0 then
begin
if cbCharsAvailable >= Cardinal(Length(sBuffer)) then
SetLength(sBuffer, cbCharsAvailable + 1); { allocate space }
{ Read what's waiting at the port }
try ReadFile(int_PortHandle, PChar(sBuffer)^, cbCharsAvailable, cbCharsRead, nil) ;
except
dec(TimeCount);
end;
{ append chars read to end of result buffer }
Result := Result + Copy(sBuffer, 0, StrLen(PChar(sBuffer)));
if (Pos(sInTerminator, Result) <> 0) and (Length(sInTerminator) <> 0) then
begin
boo_FoundTerm := True;
end
end
else dec(TimeCount);
if (TimeCount<0)then boo_TimerExpired := true;
until (boo_TimerExpired) or (boo_FoundTerm);
end;
end;
boo_InUse := False;
end;
end;{if ok return true else return false}
function GetWeight(var sWeight:string;tmp:integer=4):boolean;
var
sTemp : string;
begin
{ store the '' for failure}
sWeight := '';
Result := true;
{ open the port }
if not(OpenComm) then
begin
Result := false;
closecomm;
ShowMessage('串口打开失败!');
exit;
end;
// sTemp:='C';
// WriteComm(sTemp);
sTemp:='P';
{ send the command 'P' to scale }
WriteComm(sTemp);
{ wait for scale data ready }
sleep(200);
{ read the data from port }
sTemp:=ReadComm;
{ see if it gets the data }
if (Length(sTemp)=0) then
begin
Result := false;
closecomm;
MessageDlg('取数失败!请等待电子秤重量数据稳定后继续...', MtError,[mbOk], 0);
exit;
end;
{ get the weigth ,unit ,price ,Amount from the result. They are string type }
sWeight:=copy(sTemp,8,7);//这里现在不知怎么取,如果上面取对了,这里我就可以确定了。
{ close the port}
closecomm;
end;end.
//
//sInTerminator = chr($0A); //我不能确定这里应该是什么值?
我在button的click事件中调用GetWeight(sWeight);取到数但总取不对,总是乱码。大侠帮我改改,急!!!(const部分波特率等参数设置没问题的)
返回值是读取的数据个数。