松下快球控制,RS485串口通讯,发出去的数据石沉大海:((,郁闷中。有谁做过,提供点资料参考参考,200分拱手送上!!!!!!!!!!!!!!!!!!!!
解决方案 »
- 已打开几个excel文档的情况下, 如何用delphi对其中一个进行读 写?
- 再问调用存储过程的一个问题??--
- 如何把一张GIF或JPG图片裁剪成自己想要的图片?
- 如何 控制 excel 在单元格中插入一张图片!!!!!! 急!!!!!!!!!!
- Delphi7中FTP、POP3、SMTP这些控件在哪里?
- 我照着书的例子,怎么会出错呢?
- 如何动态改变存储过程中where后的子句?
- 用inner join进行多表连接,在线等着!!!!!
- 有没有D6源码转换为D5的工具
- 网络突然断开或者数据库不能连接,ADO怎么获知?
- 请教:关于数据库自动备份和数据库显示的问题,请大家帮忙。(急)
- TField.EditMask设置只输入两位小时加两位分钟格式问题?
不需要源码,能告诉我串口发出的数据结构说明吗?举个简单的例子就可以了。
Variants;type
TProtocolLayer = class
public
procedure CreateFrame(nAddr, nKind: Integer; data: Variant;var adata: Variant);
procedure DetachFrame(var nAddr, nKind: Integer; InData: Variant; var
OutData: Variant);
end;implementationuses un_Public;//------------------------------------------------------------------------------
//名称: CreateFrame
//参数: nAddr--地址;nKind--帧类型;data --数据
//功能: 根据地址和数据形成一帧
//说明: 序列号和帧校验和没有生成
//
//------------------------------------------------------------------------------procedure TProtocolLayer.CreateFrame(nAddr, nKind: Integer; data: Variant;var adata:variant);var
//varRes : Variant;
nLength, i : Integer;
aHigh, aLow,hsum,fsum : Byte;
begin
nLength := VarArrayHighBound(data,1)+ 10;
adata := varArrayCreate([0,nLength+7], varByte);
//帧头
adata[0] := $FF;
adata[1] := $A5;
DetachWord(nAddr, aHigh, aLow);
adata[2] := aLow; //地址
adata[3] := aHigh;
DetachWord(nLength, aHigh, aLow);
adata[4] := aLow; //帧长度
adata[5] := aHigh;
adata[6] := 0; //序列号
hsum:=0;
for i:=0 to 6 do
hsum:=hsum+byte(adata[i]);
adata[7] := byte(hsum); //帧头校验和
//数据
for i := 0 to VarArrayHighBound(data,1) do
adata[8 + i] := Byte(data[i]);
//整帧校验和
fsum:=0;
for i:=7 to varArrayHighBound(data,1)+1+8 do
fsum:=fsum+byte(adata[i])+byte(hsum);
adata[nLength - 1] := byte(fsum); //整帧校验和
//8个填充字节
for i := 0 to 7 do
adata[nLength + i] := 0;// Result := varRes;
end;//------------------------------------------------------------------------------
//名称: DetachFrame
//参数: nAddr--地址;nKind--类型;InData--要分解的帧;OutData--分解后的数据
//功能: 将应答帧分解成所需要的类型
//说明:
//
//------------------------------------------------------------------------------procedure TProtocolLayer.DetachFrame(var nAddr, nKind: Integer; InData: Variant;
var OutData: Variant);
var
nLength : Integer;
aHigh, aLow : Byte;
i : Integer;
begin
nLength := VarArrayHighBound(InData,1) - 8;
OutData := varArrayCreate([0,nLength-1], varByte);
//地址
aLow := InData[2];
aHigh := InData[3];
nAddr := aHigh shl 8 + aLow;
//类型
nKind := InData[8];
//数据
for i := 0 to nLength - 1 do
OutData[i] := InData[8 + i];
end;
MSCommLib_TLB, ExtCtrls, windows, un_Public, Variants, SysUtils, ActiveX,
Dialogs, Forms;{$DEFINE VER_DEBUG}const
ERR_TIMEOUT = 1; //超时错
ERR_VERIFY = 2; //校验和错type //链路层类,负责串口对象
TLinkLayer = class
constructor Create(iCom: Integer);
destructor Destroy; override;
private
FCom: TMSComm; //串口
FSerial: Byte; //序列号
FRCAddr: Word; //RC地址
FTimer: TTimer; //周期控制时钟
FTimerSend: TTimer; //发送帧时钟
FOutNum: Int64; //记录发送的数据帧个数
FInNum: Int64; //记录收到的数据帧个数
FOKNum: Int64; //记录校验正确帧的个数
FErrorNum: Int64; //记录校验错误帧的个数
FSendData: Variant; //发送的数据
FSendNum: Integer; //帧发送次数
FSendOK: Boolean; //是否发送成功
FSendTime: Integer; //数据发送时间
FReceiveTime: Integer; //数据接收时间
FOpenCOM: Boolean;
FData: Variant; FOnData: TOnData;
FOnError: TOnError;
FOnSendData: TOnSendData;
FOnDebugData: TOnDebugData;
private
//接收字节变量
FNewFrame: Boolean; //是否新帧
FTmpData: string; //临时数据包
FFrameLength: Integer; //帧长度
private
//和校验操作
function VerifyData(data: Variant): Integer;
//事件处理
procedure OnTimer(Sender: TObject);
procedure OnTimerSend(Sender: TObject);
procedure OnComm(Sender: TObject);
//打开串口
procedure DoOpenCOM(bOpen: Boolean);
//其他
function GetRealTime: Integer;
function GetInterval: Integer;
public
function SendData(data: Variant; nLength: Integer): Integer;
property OpenCom: Boolean read FOpenCOM write DoOpenCOM;
procedure SetInterval(nInterval: Integer);
property Interval: Integer read GetInterval;
//事件
property OnData: TOnData read FOnData write FOnData;
property OnError: TOnError read FOnError write FOnError;
property OnSendData: TOnSendData read FOnSendData write FOnSendData;
property OnDebugData: TOnDebugData read FOnDebugData write
FOnDebugData;
//统计数据
property OKNum: Int64 read FOKNum;
property ErrorNum: Int64 read FErrorNum;
property InNum: Int64 read FInNum;
property OutNum: Int64 read FOutNum;
property RealTime: Integer read GetRealTime; //实际帧发送--应答的时间
end;implementation
constructor TLinkLayer.Create(iCom: Integer);
begin
inherited Create(); //创建设置TMSCOMM
FCom := TMSComm.Create(nil);
FCom.CommPort := iCom;
FCom.RThreshold := 1;
FCom.InputMode := comInputModeBinary;
FCom.Settings := '115200,n,8,1';
FCom.OnComm := Self.OnComm;
//创建周期时钟
FTimer := TTimer.Create(nil);
FTimer.Enabled := False;
FTimer.Interval := 50;
FTimer.OnTimer := OnTimer;
//创建发送时钟
FTimerSend := TTimer.Create(nil);
FTimerSend.Enabled := False;
FTimerSend.Interval := 10;
FTimerSend.OnTimer := OnTimerSend;
//初始化值
FSerial := 0;
FOutNum := 0;
FInNum := 0;
FOKNum := 0;
FErrorNum := 0;
FSendNum := 0; FSendData := varArrayCreate([0, 0], varByte); FNewFrame := True;
FTmpData := '';
end;//------------------------------------------------------------------------------
//名称:Destroy
//参数:
//功能:析构函数,释放对象
//说明:
//
//------------------------------------------------------------------------------destructor TLinkLayer.Destroy;
begin
FCOM.Free;
FTimer.Free;
FTimerSend.Free;
end;//------------------------------------------------------------------------------
//名称:SendData
//参数:data : 将要发送的数据帧; iLenth : 数据帧的长度
//功能:将数据帧发向串口,并启动超时重发机制
//说明:
//
//------------------------------------------------------------------------------function TLinkLayer.SendData(data: Variant; nLength: Integer): Integer;
var
i : Integer;
sum : byte;
{$IFDEF VER_DEBUG}
str : string;
{$ENDIF}
begin
//得到RC地址
FRCAddr := UnitWord(data[3], data[2]);
//增加序列号和校验和
Inc(FSerial);
data[6] := FSerial;
sum := 0;
for i := 0 to 6 do //帧头校验和
sum := sum + byte(data[i]);
data[7] := byte(sum);
sum := 0;
for i := 0 to nLength - 8 - 2 do //整帧校验和
sum := sum + byte(data[i]);
data[nLength - 8 - 1] := byte(sum); VarArrayRedim(FSendData, varArrayHighBound(data, 1));
FSendData := data; FCOM.Output := data;
if Assigned(FOnSendData) then FOnSendData(data);
FSendTime := GetTickCount;
//启动超时机制
FTimer.Enabled := True;
FSendOK := False;
FSendNum := 1;
Result := 0;
Inc(FOutNum);
{$IFDEF VER_DEBUG}
str := Format('%12s', ['Send']);
for i := 0 to VarArrayHighBound(data, 1) do
str := str + ' ' + IntToHex(Byte(data[i]), 2);
OutputDebugString(pChar(str));
{$ENDIF} if Assigned(FOnDebugData) then FOnDebugData(data, -1);
end;//------------------------------------------------------------------------------
//名称: VerifyData
//参数: data
//功能: 校验帧是否有效
//说明: 返回值0--有效,1--效验和错误,2--序列号错,3--地址错误
//
//------------------------------------------------------------------------------function TLinkLayer.VerifyData(data: Variant): Integer;
var
nLength : Integer;
i : Integer;
sum : Byte;
begin
//判断帧的长度
if VarArrayHighBound(data,1) < 9 then begin
Result := ERROR_NOLEN;
Exit;
end;
//序列号校验
if FSerial <> data[6] then begin
Result := ERROR_SERIAL;
Exit;
end;
//地址校验
if FRCAddr <> (UnitWord(data[3], data[2])) then begin
Result := ERROR_RCADDR;
Exit;
end;
//和校验
nLength := UnitWord(Byte(data[5]), Byte(data[4]));
sum := 0;
//帧头校验
for i := 0 to 6 do
sum := sum + Byte(data[i]);
if sum <> data[7] then
Result := ERROR_SUM
else begin
//整帧校验
sum := 0;
for i := 0 to nLength - 2 do
sum := sum + Byte(data[i]);
if sum <> Byte(data[nLength - 1]) then
Result := ERROR_SUM
else
Result := 0;
end;
end;//------------------------------------------------------------------------------
//名称: SetTimer
//参数: nInterval
//功能: 设置时钟的Interval
//说明:
//
//------------------------------------------------------------------------------procedure TLinkLayer.SetInterval(nInterval: Integer);
begin
FTimer.Interval := nInterval;
end;//------------------------------------------------------------------------------
//名称: OnTimer
//参数:
//功能: 时钟事件触发处理
//说明:
//
//------------------------------------------------------------------------------procedure TLinkLayer.OnTimer(Sender: TObject);
var
nAddr : Integer;
begin
if not FSendOK then begin
if FSendNum >= 3 then begin
//超时
FTimer.Enabled := False;
FSendNum := 0;
//广播消息不触发事件
nAddr := UnitWord(FSendData[3], FSendData[2]);
if (nAddr <> $FFFF) then
if Assigned(FOnError) then FOnError(FSendData[8])
else
if Assigned(FOnError) then FOnError($FF);
end else begin
FCOM.Output := FSendData;
Inc(FSendNum);
end;
end;
end;
//名称: OnComm
//参数:
//功能: TMSCOMM数据事件处理
//说明:
//
//------------------------------------------------------------------------------procedure TLinkLayer.OnComm(Sender: TObject);
var
nPos : Integer;
i : Integer;
varData : Variant;
nLength : Integer;
nVerifyRes : Integer;
{$IFDEF VER_DEBUG}
str : string;
{$ENDIF}
begin
case FCOM.CommEvent of
comEvReceive: begin
nLength := FCOM.InBufferCount;
varData := FCOM.Input;
for i := 0 to nLength - 1 do
FTmpData := FTmpData + Chr(Byte(varData[i])); if Length(FTmpData) >= 2 then begin
nPos := Pos(#$FF#$A5, FTmpData);
if nPos > 0 then //有帧头标识
Delete(FTmpData, 1, nPos - 1);
end else
Exit;
if Length(FTmpData) >= 8 then begin
//帧头到来
FFrameLength := UnitWord(byte(Ord(FTmpData[6])),
byte(Ord(FTmpData[5])));
if FFrameLength > 256 then begin //帧长度不对,重新接收
FTmpData := '';
FNewFrame := True;
Exit;
end;
if Length(FTmpData) >= FFrameLength then begin
//帧收完毕
FData := VarArrayCreate([0, FFrameLength - 1], varByte);
for i := 0 to FFrameLength - 1 do
FData[i] := byte(Ord(FTmpData[i + 1])); Inc(FInNum);
{$IFDEF VER_DEBUG}
str := Format('%10s', ['Receive']);
for i := 0 to VarArrayHighBound(FData, 1) do
str := str + ' ' + IntToHex(Byte(FData[i]), 2);
OutputDebugString(pChar(str));
{$ENDIF}
nVerifyRes := VerifyData(FData); //校验数据帧
if nVerifyRes = 0 then begin
//帧接受完毕
FTimer.Enabled := False;
FSendOK := True;
FSendNum := 0;
//启动发送下一帧时钟
FTimerSend.Enabled := True;
Inc(FOKNum); //增加正确帧计数
end else begin
Inc(FErrorNum); //增加错误帧计数
end;
//初始化接受变量
FTmpData := '';
FNewFrame := True; FReceiveTime := GetTickCount;
if Assigned(FOnDebugData) then FOnDebugData(FData, nVerifyRes); end;
end;
end;
else
Exit;
end;
end;//------------------------------------------------------------------------------
//名称: DoOpenCOM
//参数:
//功能: 打开端口,将端口状态发向主窗口
//说明:
//
//------------------------------------------------------------------------------procedure TLinkLayer.DoOpenCOM(bOpen: Boolean);
begin
try
FCOM.PortOpen := bOpen;
FOpenCOM := bOpen;
PostMessage(Application.MainForm.Handle, WM_PORTSTATUS, FCOM.CommPort, 0);
except
FOpenCOM := False;
PostMessage(Application.MainForm.Handle, WM_PORTSTATUS, FCOM.CommPort, 1);
end;
end;function TLinkLayer.GetRealTime: Integer;
begin
Result := FReceiveTime - FSendTime;
end;function TLinkLayer.GetInterval: Integer;
begin
Result := FTimer.Interval;
end;procedure TLinkLayer.OnTimerSend(Sender: TObject);
begin
FTimerSend.Enabled := False;
if Assigned(FOnData) then begin
FOnData(FData, VarArrayHighBound(FData, 1) + 1);
end;
end;end.
我的情况是这样的,我手上有一个松下CS850的协议。
协议结构是这样的:
STXAD00;GC7:002110CETX
A D 0 0 : Unit Address 00 - 99, ZZ
Note : Only address 01 - 96 is available for CSR camera series.
Only address 01 - 16 is available for WV-RM70.
ZZ controls all units.
STX:02hex of ASCII code table
GC:Command header, GC:Camera Control Command
F: Number of commands. Refer Fig - 1
002: Command distination, 002:Camera functions,202:Receiver functions
1: Command type, 1:Control command, 0:Status request command, 2:Text data
10C: Function (Preset position call), Refer table 2 Receiver function
ETX :03hex of ASCII code table
有一个Camera functions列表。一个Receiver functions列表。
根据我的理解:就是向串口发送一个$02(开始),然后发送字符串如:
'AD00;GC7:002110C';在发送一个$03(结束)。不知道你们发送的命令是什么一个样子,可否说
下呢。至于串口通讯这一块,我想程序中应该没问题的,对解码器的控制我试过。现在就是不清楚对快球的控制命令我是否发错了!