目录
0 起因
最近朋友公司需要做一个PC端的工业控制工具,问到我。
再三考虑下决定直接自己帮他做出来,下面我将详细记录中间的经过和问题如何解决。
多年前曾经用过delphi,安装包等资源还在,C语言基础还在,别的已经忘得一干二静了,看我是如何搞定的。
以下记录的意义在于告诉大家,工程实践和理论学习以及科研区别,由于我用到的工具比较老就不一一截图了。
此工具大致需要实现的是通过PC串口和设备通信,一方面获取设备当前的状态,另一方面需要对设备进行一些配置。被控制的设备是已经有的现成设备不需要开发,到需要生产后和此工具联调,后续也将记录联调过程。
1 选择风格和控件
计划用到iocomp控件包,由于对iocomp控件并不熟悉,打算找别人做的界面看看;
网上一顿搜索发现介绍都不全面,决定去官网尝试一下,官网找到4个文档,梭哈了;
虽然没有全面介绍的文档,但能做的东西已基本做到心中有数。
2 大胆的决定
综上所述,决定一边摸索一边做(做工程就是这样,虽然对全貌一知半解但不影响实现功能)前提是你的方案都是成熟的东西,没有任何科学探索的成分。
3 干就完了
做PC工具都是通过第三方或者集成开发环境自带的空间实现,例如我当前用的delphi是通过spcomm控件实现,c#则是用serialPort控件实现。
3.1 新建工程
3.1.1 工程名字不能随意取
遇到第一个问题,project的名字取了好几个都不行:
ctrl-8808
8808-ctrl
ctrl-ld
什么情况?这是要从入门到放弃吗??
借助某娘,搜索发现,有如下规则:
3.2 实现串口基本操作
需要获取当前电脑的串口,开关串口,串口收数据处理,串口发送报文。
3.2.1 通过读取注册表信息获取当前电脑的串口
procedure Tform1.EnumComPorts(Ports: TStrings);
var
KeyHandle: HKEY;
ErrCode, Index: Integer;
ValueName, Data: string;
ValueLen, DataLen, ValueType: DWORD;
TmpPorts: TStringList;
begin
ErrCode := RegOpenKeyEx(HKEY_LOCAL_MACHINE, 'HARDWARE\DEVICEMAP\SERIALCOMM', 0,
KEY_READ, KeyHandle);
if ErrCode <> ERROR_SUCCESS then
raise ERegError.Create('打开串口列表的注册表项出错');
TmpPorts := TStringList.Create;
try
Index := 0;
repeat
ValueLen := 256;
DataLen := 256;
SetLength(ValueName, ValueLen);
SetLength(Data, DataLen);
ErrCode := RegEnumValue(KeyHandle, Index, PChar(ValueName),
Cardinal(ValueLen), nil, @ValueType, PByte(PChar(Data)), @DataLen);
if ErrCode = ERROR_SUCCESS then
begin
SetLength(Data, DataLen);
TmpPorts.Add(Data);
Inc(Index);
end
else if ErrCode <> ERROR_NO_MORE_ITEMS then
raise ERegError.Create('打开串口列表的注册表项出错');
until (ErrCode <> ERROR_SUCCESS);
TmpPorts.Sort;
Ports.Assign(TmpPorts);
finally
RegCloseKey(KeyHandle);
TmpPorts.Free;
end;
end;
3.2.2 发送数据包
Var
MySendStr:string;
DataLen:Interger;
MySendStr := Char($1B) + Char($5B) + Char($48) + Char($1B) + Char($5B) + Char($4A) + Char($EA);
SetLength(MySendStr,DataLen);
Move(SendBuf,Pchar(MySendStr)^,DataLen);
Form1.Comm1.WriteCommData(PChar(MySendStr),DataLen);
3.2.3 数据接收处理
需要在spcomm控件的接收事件中用以下方式处理数据
procedure TForm1.Comm1ReceiveData(Sender: TObject; Buffer: Pointer;
BufferLength: Word);
var
str:string;
begin
if s_com then
begin
application.ProcessMessages;
SetLength(str,BufferLength);
Move(Buffer^,Pchar(str)^,BufferLength);
Memo2.Lines.Add(datetimetostr(now) + chr($0d) + chr($0a) + IntToStr(BufferLength));
Memo2.Lines.Add(str + chr($0d) + chr($0a));
end;
end;
3.2.4 串口开关操作
需要调用控件自带的方法。
Comm1.StartComm ;
Comm1.StopComm;
3.3 调试串口开关和收发数据
经过简单调试,已经可以接收数据。
欲知后事如何,请看下回。
【创作不易,欢迎转载,转载请注明出处】
如果大家对相关文章感兴趣,可以关注公众号“嵌入式毛哥”,持续分享嵌入式干货,不限于疑难故障分析解决、算法共享、开发设计思想等,志在帮助更多人在嵌入式行业发光发热。