遵循Modbus协议通过Usb(Ch375)通信的上位机传输问题
http://www.delphi2007.net/DelphiNetwork/html/delphi_20061129164355231.html
Usb芯片:Ch375
协议:Modbus
上位机开发软件:delphi
传输格式(RTU):
帧定义:
头|命令|长度|数据(高) ---- 数据(低)|CRC
C0C1C2 S0S1S2 T10T11 T20T21 P0P1
01 02 0C 000000 000000 0000 0000 0000 XX
第一次做这种软件,还没有在下位机上测试,先贴出部分源码,请大家帮忙改正。
还有对于从下位机取出来的数据(已从16进制转换成10进制)有几个疑问:
1。是不是就代表了真实的值,是否还需要再转换;
2。如何处理浮点型数据。
下面是部分源码:
//读数据
function ReadData(iIndex:Integer;var oBuffer:PChar;var ioLength:Integer):Boolean;
stdcall; external DllFile name 'CH375ReadData';
function TPublicFun.GetData:Integer;
var
Buff_HAdd : Byte;//帧:头地址
Buff_Cmd : Byte;//帧:命令
Buff_Len : Byte;//帧:长度
Buff_DatLC : array[1..3] of Byte;//帧:LC数据
Buff_DatLS : array[1..3] of Byte;//帧:LS数据
Buff_DatT1 : array[1..2] of Byte;//帧:T1数据
Buff_DatT2 : array[1..2] of Byte;//帧:T2数据
Buff_DatP : array[1..2] of Byte;//帧:P数据
Buff_Send : array of Byte;//用于存放各个域合成的总的串
I,BuffLen,TempLen : Integer;//传输的实际数据长度
TempStr,CSort : string;//用于存放string类型的测试传输帧
Rtl : Boolean;
PChar_Send : PChar;
begin
Result := -1;
//测试用,假设Usb设备已打开
Usb_Opened := True;
if Usb_Opened then
begin
//设置头地址
Buff_HAdd := HeadCode;
//设置命令
Buff_Cmd := StatusCode;
//设置长度
Buff_Len := strtohex1(IntToHex(17,2),2);
TempLen := 17;
//初始化LC,LS
for I:=1 to 3 do
begin
Buff_DatLC[I] := $00;
Buff_DatLS[I] := $00;
end;
//初始化T,P
for I:=1 to 2 do
begin
Buff_DatT1[I] := $00;
Buff_DatT2[I] := $00;
Buff_DatP[I] := $00;
end;
SetLength(Buff_Send,TempLen);
//设置总串
Buff_Send[1] := Buff_HAdd;
Buff_Send[2] := Buff_Cmd;
Buff_Send[3] := Buff_Len;
Buff_Send[4] := Buff_DatLC[1];
Buff_Send[5] := Buff_DatLC[2];
Buff_Send[6] := Buff_DatLC[3];
Buff_Send[7] := Buff_DatLS[1];
Buff_Send[8] := Buff_DatLS[2];
Buff_Send[9] := Buff_DatLS[3];
Buff_Send[10] := Buff_DatT1[1];
Buff_Send[11] := Buff_DatT1[2];
Buff_Send[12] := Buff_DatT2[1];
Buff_Send[13] := Buff_DatT2[2];
Buff_Send[14] := Buff_DatP[1];
Buff_Send[15] := Buff_DatP[2];
//CRC校验:即校验域前的几个域的集合
I := CRC(Buff_Send[1],15);
Buff_Send[16] := I div 256;
Buff_Send[17] := I mod 256;
//获得string类型的测试传输帧
TempStr := '';
for I:= 1 to TempLen do
TempStr := TempStr + inttohex(Buff_Send[i],2);
BuffLen := TempLen * 2;
PChar_Send := PChar(TempStr);
//发送命令
//测试屏蔽
Rtl := ReadData(Usb_Index,PChar_Send,BuffLen);
if Rtl then
begin
//读取返回串
for I:= 0 to TempLen-1 do
Buff_rev[I+1] := strtohex1(copy(PChar_Send,I*2+1,2),2);
//CRC校验
if CRC_Check=1 then
begin
TempStr := '';
//校验成功,读出数据
//TempStr := TempStr + inttohex(Buff_rev[i+4],2);
for I:= 0 to 2 do
begin
Buff_DatLC[I+1] := Buff_rev[I+4];
Buff_DatLS[I+1] := Buff_rev[I+7];
end;
for I:= 0 to 1 do
begin
Buff_DatT1[I+1] := Buff_rev[I+10];
Buff_DatT2[I+1] := Buff_rev[I+12];
Buff_DatP[I+1] := Buff_rev[I+14];
end;
//数据处理
Result := 1;
//初始化接受串
for I:=1 to Maxlen do Buff_rev[I]:=0;
end;
end
else
begin
ShowMessage('数据传输出错,无法得到正确的值!','提示');
end;
end
else
begin
ShowMessage('没有发现可用的Usb设备!','提示');
end;
end;
对于传输帧,我现在有点疑惑:
我传向下位机请求和从下位机得到数据都是以上面我和下位机开发人员定义的格式传输并不象下面Modbus中的例子,不知可行否?
因为我定义的帧中要获取5个参数的值:LC由C0C1C2构成(高-低)、LS由S0S1S2构成、T1由T10T11构成、T2由T20T21构成、P由P0P1构成。
下面是Modbus RTU中一个例子:
主机请求:
地址 功能码 第一个寄存器的高位地址 第一个寄存器的低位地址 寄存器的数量的高位 寄存器的数量的低位 错误校验
01 03 00 38 00 01 XX
从机应答:
地址 功能码 字节数 数据高字节 数据低字节 错误校验
01 03 2 41 24 XX
数据:16进制=4124,转换成十进制=16676
//发送命令
//测试屏蔽
Rtl := ReadData(Usb_Index,PChar_Send,BuffLen);
ReadData应该是读吧?
你的例子:
请求:
0103 00380001XX
01=>hdr
03=>cmd
00=>len
38=>crc
即无数据,后面的数据就错了
按协议,好像是这样写的
PRTUData = ^TRTUData;
TRTUData = packed record
hdr: Byte;
cmd: Byte;
len: Byte;
data: array [0..0] of Byte;
crc: Byte;
end;
data取决于len的长度
var
P: PByte;
rtuLen: Byte;
rtu: PRTUData;
begin
rtuLen := SizeOf(TRTUData) + DataLen - 1;
rtu := allocMem(rtuLen);
rtu.hdr := $01;
rtu.cmd := $02;
rtu.len := DataLen;
P := @rtu.data[0];
for I := 0 to DataLen - 1 do
beg
P^ := $XX;
inc(P);
end;
P^ := crc(xxx); // P ==> crc
WriteData(..., rtu, rtuLen)
end;
先谢谢ERR0RC0DE()
我知道了,你是先发送命令,WriteData(..., rtu, rtuLen),然后在通过ReadData(Usb_Index,PChar_Send,BuffLen);读取数据,是吧?
看不懂,^_^
顶下!
有兴趣的朋友欢迎继续讨论阿
遵循Modbus协议通过Usb(Ch375)通信的上位机传输问题相关推荐
- C#实现串口通信的上位机开发
目录 上位机 串口通信 C#串口通信:SerialPort类 列出所有的串口 C#串口通信:读写数据 写数据: 读数据: DataReceived事件: 数据发送不同步问题: 界面设计 波形显示(ch ...
- ftp上位机编程c语言,基于USB芯片CY7C68013A的上位机C++程序
标签: 基于USB芯片CY7C68013A的上位机C 基于USB芯片CY7C68013A的上位机C程序 在国标<质量管理体系 基础和术语>GB/T19000-2008/ISO9000:20 ...
- C#做一个简单的进行串口通信的上位机
C#做一个简单的进行串口通信的上位机 乱世中的单纯 发布于 1年前,共有 10 条评论 1.上位机与下位机 上位机相当于一个软件系统,可以用于接收数据.控制数据.即可以对接收到的数据直接发送操控命令来 ...
- C# 实现自定义的USB设备与上位机进行通信(上位机部分)
因为以前没用过USB,对USB也不了解,于是上网查了很多资料,不过网上的资料都是零零散散,不清不楚的,于是我自己总结了一下,下面几个链接是网上这么多零散资料里,我觉得比较有参考意义的. USB设备连接 ...
- STM32 USB 开发(二)HID Slave 通信 --- 简单上位机开发
文章目录 前言 一.准备数据 二.在VS中开发上位机 1.引入国外大神写的USB通讯库HidLibary 2.新建HID管理类 CustomHIDManager.cs 3.运行结果 总结 前言 在网上 ...
- “Xilinx ZYNQ+TCP通信+Python上位机”实现实时视频传输系统
笔者在CSDN的第一篇万字长文,请多多支持. 本文是笔者的公众号 IC设计者笔记 文章的转载.很多优质原创内容都会第一时间发布在公众号,欢迎关注公众号,一起交流学习.公众号后台回复"ZYNQ ...
- 触摸屏mtp文件转c语言,F28335与上位机(触摸屏)之间的通讯遵循modbus协议使用C语言编程...
资料介绍 touch_test\.cdtbuild ..........\.cdtproject ..........\.launches\Example_2833xSci_Autobaud.laun ...
- Fins协议-欧姆龙PLC数据采集读写操作上位机软件工具
本软件基于.net开发,可支持主流PLC通信协议测试,支持读取写入操作:支持ModBus.Bacnet等常用工业通讯协议 支持功能如下: ModBusTcp读写操作 ModBusRtu读写操作 Mod ...
- matlab写的串口通信图像上位机,MATLAB的串口通信
属性 BaudRate Specify the rate at which bits are transmitted BreakInterruptFcn Specify t ...
最新文章
- OWA修改密码注意事项
- python dataframe转图片_Python:dataframe转html
- onenote快捷键_onenote链接系列:4种链接笔记的地址
- 全球超算500强新榜发布:美国卫冕 中国力争
- 【转】Mac系统中安装homebrew(类似redhat|Centos中的yum;类似Ubuntu中的apt-get)
- 2021年中国以太网转换器市场趋势报告、技术动态创新及2027年市场预测
- linux虚拟化桌面协议,桌面虚拟化传输协议之android spice
- 原生js实现form表单序列化
- java多商户商城系统源码下载
- Oracle排序查询语句
- STM32F103ZET6【标准库函数开发】----- 04串口4的IO口收发数据实验测试
- 天龙八部八部显示服务器堵塞,天龙八部服务端各目录说明
- 为什么要用谷歌浏览器翻译插件?| 文末福利
- P1293 班级聚会
- 垃圾分类的正确姿势?用 OpenCV 人工智能图像识别技术来进行
- SpringFox 学习
- 关于计算几何一些算法
- 前端酷炫效果之那些漂亮的登录界面
- 阿里云计算ACP认证经验分享(一)
- Oracle账号注册、下载、安装与卸载
热门文章
- 可靠性不是测试出来的,是设计出来的!
- TransparentBitmap函数设置透明位图的原理分析
- 托盘图标菜单_全新开始菜单和任务栏,Windows 10X 抢先体验
- php中的全局异常,PHP的全局错误处理详解
- Kotlin实践(2)-生成jvm程序
- python3精要(33)-字典解析与集合解析,if else 用于解析
- access开发精要(2)-参照完整性
- vb.net2019- 目录
- 【CV】目标检测:常用名词与mAP评价指标的引出
- 【学术相关】高校教师提前离职需支付“天价违约金”,坑!