类似通讯程序的编写一般分三步:
1、初始化串口
2、发送协议数据
3、接收协议数据(关键点,待讨论)
可参考代码:
1、初始化串口
try
if Mscomm1.PortOpen then
begin
Mscomm1.PortOpen := False;
//关闭串口
end;
InitCom;
Mscomm1.CommPort := seCOM.Value;
Mscomm1.PortOpen := True;
// 打开串口
Log('成功打开 COM 口:' + inttostr(Mscomm1.CommPort));
except on E: Exceptiondo
begin
Log(Format('打开 COM%d 口发生错误:%s', [mscomm1.CommPort, E.Message]));
Log('故障可能原因1:COM口已经被其他程序打开');
Log('故障可能原因2:此COM口不存在');
Log('故障可能原因3:COM口波特率等属性设置有误');
Log('故障可能原因4:COM口已经损坏');
end;
end;
procedure InitCom;
begin
//先初始化,再打开com
Mscomm1.InBufferCount := 0;
// 0 清空接收缓冲区,否则返回当前接受缓冲区中等待的字符数
mscomm1.OutBufferCount := 0;
// 0 清除传输缓冲区,否则返回在传输缓冲区中等待的字符数
Mscomm1.InputLen := 1;
// 1 每次读取 1 个字符,0 读取整个缓冲区内容。多用于读取定长数据
Mscomm1.RThreshold := 1;
// 每次接收到1个字符即产生OnComm事件
Mscomm1.SThreshold := 0;
// =0,不产生OnComm事件. Sthreshold=1,当传输缓冲区完全空时,产生此ComEvSend事件
Mscomm1.InputMode := 0;
// ComInputModeText 0数据通过Input属性以文本形式取回(默认),ComInputModeBinary 1 以二进制形式取回
Mscomm1.Settings := Trim(setting.Text);
// 设置波特率等
end;
2、发送协议数据:
MSComm1.output := trim(atcmd.text) + #13;
3、接收协议数据
procedure TFrmMain.MSComm1Comm(Sender: TObject);
var
recstr: Olevariant;
s: string;
c: char;
begin
case Mscomm1.CommEvent of
// 正常事件
comEvReceive: // 接收数据
begin
recstr := Mscomm1.Input;
// 一次处理一个字符
s := recstr;
c := s[1];
// 组装协议
// 判断协议是否合法
// 处理协议数据
end
end;
第3步的协议解析比较有看点。
我遇到的协议根据起始终止符来看有两种结构(含校验位):
A结构、1个起始符+中间数据+1个结束符
B结构、多个起始符+中间数据+多个结束符
其实第3步协议解析与 mscomm32 没有关系,关键是对协议的处理。
A结构、B结构处理方式类似但是复杂度差别挺大,不知道各位都是如何处理的?希望探讨一下这些协议的处理方式。