APro控件使用的问题(200分)

  • 主题发起人 主题发起人 bjaman
  • 开始时间 开始时间
B

bjaman

Unregistered / Unconfirmed
GUEST, unregistred user!
使用APro控件的TApdComPort来监听串口数据,insize和outsize均为默认的4096字节。我这里一条数据的完整一帧是84个字符,可是我接收到的数据被断成六个小帧了。请问是什么原因?
看了APro控件附带的Demo程序,也只是用了TApdComPort一个控件,只是它比我的程序额外设置了BufferFull = trunc(insize * 0.9),BufferResume = trunc(insize * 0.1)。是否设置了此属性就可以接收到一个完整的帧呢?
是否必须用TApdDataPacket来与TApdComPort配合使用才能接收到完整的一个数据帧?如果使用TApdDataPacket组件,是否不再需要在TApdComPort的OnTriggerAvail事件里获取接收到的数据,而只需要在TApdDataPacket的事件OnPacket或OnStringPacket中获取并解析数据了?
有做过的朋友麻烦给点提示,或给个示例! 因我手头没有调试设备,现在还只能猜测.....
 
参考一下这个吧:
http://www.winu.cn/viewthread.php?tid=108563
 
to LSUPER:
您的推荐下载是一个.exe文件,上传者附言:
“本程序也凝聚了我一定的劳动心血,源程序如需要,请给我发Email,一份源程序需要20元,在接收到您的Email后我会在回复中留下具体汇款方式,凡购买用户我都会提供串口方面的问题解答。”
 
呵呵 不好意思,没想多随手 google 到垃圾了
turbo 的网站上有do
c 啊
 
问题解决! 用TApdComPort与TApdDataPacket相结合,控制数据接收,并保证一帧数据的完整性。APro控件的应用,在《DELPHI串口及语音传真高级编程》一书之第三章有详细介绍,并有大量示例程序。此书电子版及附书源码在网上可以下载得到。
现把主要处理代码贴出,可供参考:
procedure TForm_Main.CommInitialize;//串口初始化
type
ComSet = record
ComPort : SmallInt;
BaudRate : Integer;
VerifyBit : TParity;
DataBit : SmallInt;
StopBit : SmallInt;
end;
var
iniFile : TIniFile;
aStr : string;
aInt : Word;
aComSet : ComSet;
begin
//读取串口参数设置信息,进行串口初始设置
iniFile := TIniFile.Create(ExtractFilePath(Application.ExeName) + 'SysParams.ini');
try
aStr := iniFile.ReadString('Machine','MachineModel','HJK-120');
ComBox_Machine.ItemIndex := ComBox_Machine.Items.IndexOf(aStr);
aStr := iniFile.ReadString('COMParam','COMPort','COM1');
if DM.GetComList(ComBox_ComPort.Items) then
ComBox_ComPort.ItemIndex := ComBox_ComPort.Items.IndexOf(aStr);
aStr := Copy(aStr,4,Length(astr) - 3);
aComSet.ComPort := StrToInt(aStr);//值为 1、2时分别设置coml、com2
aInt := iniFile.ReadInteger('COMParam','BaudRate',2400);
Combox_Baud.ItemIndex := Combox_Baud.Items.IndexOf(IntToStr(aInt));
aComSet.BaudRate := aInt;
aInt := iniFile.ReadInteger('COMParam','VerifyBit',NOPARITY);
ComBox_CheckBit.ItemIndex := ComBox_CheckBit.Items.IndexOf(IntToStr(aInt));
case aInt of
NOPARITY : aComSet.VerifyBit := pNone;
ODDPARITY : aComSet.VerifyBit := pOdd;
EVENPARITY : aComSet.VerifyBit := pEven;
MARKPARITY : aComSet.VerifyBit := pMark;
else
aComSet.VerifyBit := pSpace;
end;
aInt := iniFile.ReadInteger('COMParam','DataBit',8);
ComBox_DataBit.ItemIndex := ComBox_DataBit.Items.IndexOf(IntToStr(aInt));
aComSet.DataBit := aInt;
aInt := iniFile.ReadInteger('COMParam','StopBit',2);
ComBox_StopBit.ItemIndex := ComBox_StopBit.Items.IndexOf(IntToStr(aInt));
aComSet.StopBit := aInt;
try
ApdComPort.Open := False;
ApdComPort.ComNumber := aComSet.ComPort;
ApdComPort.Baud := aComSet.BaudRate;
ApdComPort.Parity := aComSet.VerifyBit;
ApdComPort.DataBits := aComSet.DataBit;
ApdComPort.StopBits := aComSet.StopBit;
ApdComPort.PromptForPort := False;//不显示选择串口对话框
With ApdDataPacketdo
begin
Enabled := False;
IgnoreCase := True;
if Trim(ComBox_Machine.Text) = 'HJK-120' then
//串口设备
begin
endCond := [ecString,ecPacketSize];
EndString := #13#10;//协议约定一帧的结束符
PacketSize := 84;
//协议约定一帧的字符数
StartCond := scString;
StartString := 'T';
//协议约定一帧的起始符
IncludeStrings := True;
end;
Enabled := True;
end;

ApdComPort.Open := True;
//打开串口
StatusBar1.Panels[0].Text := '串行口' + ComBox_ComPort.Text + '已打开,处于待命状态...';
except
on e : Exceptiondo
begin
StatusBar1.Panels[0].Text := '串行口' + ComBox_ComPort.Text + '打开失败! 错误信息:' + e.Message;
Application.MessageBox('打开串口错误,请检查串口参数设定或硬件连接!',提示',64);
end;
end;
finally
FreeAndNil(iniFile);
end;
end;
TApdDataPacket的OnStringPacket()事件,在这里获取接收到的完整一帧数据并解析处理:
procedure TForm_Main.ApdDataPacketStringPacket(Sender: TObject;
Data: String);
var
ReadStr,ErrorInfo : string;
begin
ReadStr := Data;
if ReadStr <> '' then
begin
StatusBar1.SimpleText := '串行口' + ComBox_ComPort.Text + '接收到的数据:' + Trim(ReadStr);
Memo1.Lines.Append(Trim(ReadStr));
//原数据,用Trim()去除末尾的回车换行符
if SameText(trim(ComBox_Machine.Text),'HJK-120') then
begin
if (Length(ReadStr) = 84) and (Copy(ReadStr,1,1) = 'T')
and (Copy(ReadStr,Length(ReadStr) - 1,2) = #13#10) then
//协议约定,正确的是84个字符,第一位是T,最后二位是回车换行符
begin
//通过串口接收正确以后, 就要在这里解析,并保存数据到数据库的表中去
if not WriteDataIntoDB(ReadStr,ErrorInfo) then
begin
//如果写入失败,则需要写错误日志
StatusBar1.SimpleText := ErrorInfo;
dm.WriteINIFile(FormatDateTime('yyyyMMDD',Now()),
'ErrorInfo',FormatDateTime('yyyy-MM-DD HH:mm:ss',Now()),ErrorInfo);;
end;
end;
end;
end;
end;
在此应该感谢盒子上的朋友:huangxw,是他给我指明了方向。
 
谢谢LSUPER为我尽力搜索相关资料!
 
俺是盒子上huangxw,很久没有用 Delphi 了,拿分了:)
 
后退
顶部