先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前阿里P7
深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年最新Golang全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上Go语言开发知识点,真正体系化!
由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新
如果你需要这些资料,可以添加V获取:vip1024b (备注go)
正文
从机不会自己发送消息给主站,只能回复从主机发送的消息请求。
并且,Modbus并没有忙机制判断,比方说主机给从机发送命令, 从机没有收到或者正在处理其他东西,这时候就不能响应主机,因为modbus的总线只是传输数据,没有其他仲裁机制,所以需要通过软件的方式来判断是否正常接收。
举例
现在,我们来探讨Modbus数据传输的方式,可以简单地理解成打电话。并且是单向通信的打电话
主机发送数据,首先需要从机的电话号码(区分每个从机,每个地址必须唯一),告诉从机打电话要干什么事情,然后是需要发送的内容,最后再问问从机,我说的话你都听清楚了没有呀,没有听错吧?
然后从机这里,得到了主机打过来的电话,从机回复主机需要的内容,主机得到从机数据,这样就是一个主机到从机的通信过程
就好比老师和你打电话,老师拨通了你的电话号,然后老师跟你说,小王呀,我这里需要你给我发东西,发的内容是上周的一周总结,你说好的,然后打开你电脑的文件夹,把你的周报发给老师,这就是一个通信过程。
Modbus存储区
既然从机存储数据,那么肯定要有一个存储区,那就需要文件操作,我们都知道这文件可以分为只读(-r)和读写(-wr)两种类型
并且存储的数据类型可以分为 :布尔量 和 16位寄存器
- 布尔量比如IO口的电平高低,灯的开关状态等。
- 16位寄存器比如 传感器的温度数据,存储的密码等。
Modbus协议规定了4个存储区 分别是0 1 3 4区 其中1区和4区是可读可写,1区和3区是只读。
区号 | 名称 | 读写 | 地址范围 |
---|---|---|---|
0区 | 输出线圈 | 可读可写布尔量 | 00001-09999 |
1区 | 输入线圈 | 只读布尔量 | 10001-19999 |
3区 | 输入寄存器 | 只读寄存器 | 30001-39999 |
4区 | 保持寄存器 | 可读可写寄存器 | 40001-49999 |
并且Modbus还给每个区都划分了地址范围 主机向从机获取数据时,只需要告诉从机数据的起始地址,还有获取多少字节的数据,从机就可以发送数据给主机
Modbus数据模型规定了具体的地址范围,每一个从机,都有实际的物理存储,跟modbus的存储区相对应,主机读写从机的存储区,实际上就是对从机设备对应的实际存储空间进行读写。
Modbus协议类型
在上面我们已经说明了Modbus可以在各种介质上传输,那么他的传输模式也分为三种。包括ASCII、RTU(远程终端控制系统)、TCP三种报文类型
串行端口存在多个版本的Modbus协议,而最常见的是下面四种:
- Modbus-Rtu
- Modbus-Ascii
- Modbus-Tcp
- ModbusPlus
Modbus RTU是一种紧凑的,十六进制表示数据的方式,Modbus ASCII是一种采用Ascii码表示数据,并且每个8Bit 字节都作为两个ASCII字符发送的表示方式。
RTU格式后续的命令/数据带有循环冗余校验的校验和,而ASCII格式采用纵向冗余校验的校验和。
Modbus协议使用串口传输时可以选择RTU或ASCII模式,并规定了消息、数据结构、命令和应答方式并需要对数据进行校验。ASCII 模式采用LRC校验,RTU模式采用16 位CRC校验。通过以太网传输时使用TCP,这种模式不使用校验,因为TCP协议是一个面向连接的可靠协议。
当然常用的就是RTU模式,ASCII一般很少
举一个简单的例子,如果我们需要发送一个数字10
那么RTU模式下,只需要发送 0x0A
总线上传输数据形式为: 0000 1010
而ASCII码模式则将数据1和0转为’1’和’0’,需要发送0x31(1) 0x30(0)
两个字节数据。总线上传输数据形式为: 0011 0001 0011 0000
详细的我们等下再阐述
Modbus-RTU协议
Modbus报文帧结构
一个报文就是一帧数据,一个数据帧就一个报文: 指的是一串完整的指令数据,本质就是一串数据。
Modbus报文是指主机发送给从机的一帧数据,其中包含着从机的地址,主机想执行的操作,校验码等内容
Modbus协议在串行链路上的报文格式如下所示:
从站地址 | 功能码 | 数据 | CRC/LRC |
---|---|---|---|
1 byte | 1 byte | N bytes | 2 bytes |
- 帧结构 = 从机地址 + 功能吗 + 数据 + 校验
- 从机地址: 每个从机都有唯一地址,占用一个字节,范围0-255,其中有效范围是1-247,其中255是广播地址(广播就是对所有从机发送应答)
- 功能码: 占用一个字节,功能码的意义就是,知道这个指令是干啥的,比如你可以查询从机的数据,也可以修改从机的数据,所以不同功能码对应不同功能.
- 数据: 根据功能码不同,有不同功能,比方说功能码是查询从机的数据,这里就是查询数据的地址和查询字节数等。
- 校验: 在数据传输过程中可能数据会发生错误,CRC检验检测接收的数据是否正确
Modbus功能码
Modbus规定了多个功能,那么为了方便的使用这些功能,我们给每个功能都设定一个功能码,也就是指代码。
Modbus协议同时规定了二十几种功能码,但是常用的只有8种,用于对存储区的读写,如下表所示:
功能码 | 功能说明 |
---|---|
01H | 读取输出线圈 |
02H | 读取输入线圈 |
03H | 读取保持寄存器 |
04H | 读取输入寄存器 |
05H | 写入单线圈 |
06H | 写入单寄存器 |
0FH | 写入多线圈 |
10H | 写入多寄存器 |
当然我们用的最多的就是03和06 一个是读取数据,一个是修改数据。
CRC校验
错误校验(CRC)域占用两个字节包含了一个16位的二进制值。CRC值由传输设备计算出来,然后附加到数据帧上,接收设备在接收数据时重新计算CRC值,然后与接收到的CRC域中的值进行比较,如果这两个值不相等,就发生了错误。
比如主机发出01 06 00 01 00 17 98 04, 98 04 两个字节是校验位,那么从机接收到后要根据01 06 00 01 00 17 再计算CRC校验值,从机判断自己计算出来的CRC校验是否与接收的CRC校验(98 04主机计算的)相等,如果不相等那么说明数据传输有错误,这些数据就不能要。
CRC校验流程:
1、预置一个16位寄存器为0FFFFH(全1),称之为CRC寄存器。
2 、把数据帧中的第一个字节的8位与CRC寄存器中的低字节进行异或运算,结果存回CRC寄存器。
3、将CRC寄存器向右移一位,最高位填以0,最低位移出并检测。
4 、如果最低位为0:重复第三步(下一次移位);如果最低位为1:将CRC寄存器与一个预设的固定值(0A001H)进行异或运算。
5、重复第三步和第四步直到8次移位。这样处理完了一个完整的八位。
6 、重复第2步到第5步来处理下一个八位,直到所有的字节处理结束。
7、最终CRC寄存器的值就是CRC的值。
此外还有一种利用预设的表格计算CRC的方法,它的主要特点是计算速度快,但是表格需要较大的存储空间,该方法此处不在阐述
下面我们来看详细的发送和接收数据:
1、主机对从机读数据操作
主机发送报文格式如下:
从站地址 | 功能码 | 起始(高) | 起始(低) | 数量(高) | 数量(低) | 校验 |
---|---|---|---|---|---|---|
0x01 | 0x03 | 0x00 | 0x01 | 0x00 | 0x01 | 0xD5 0xCA |
含义:
0x01:从机的地址
0x03:查询功能,读取从机寄存器的数据
0x00 0x01: 代表读取的起始寄存器地址.说明从0x0001开始读取.
0x00 0x01: 查询的寄存器数量为0x0001个 Modbus把数据存放在寄存器中,通过查询寄存器来得到不同变量的值,一个寄存器地址对应2字节数据; 寄存器地址对应着从机实际的存储地址
0xD5 0xCA: 循环冗余校验 CRC
从机回复报文格式如下:
| 从站地址 | 功能码 | 字节计数 | 字节1 |字节2 | 校验 |
|–|–|-|-|-|-|-|
| 0x01 | 0x03| 0x02| 0x01 | 0x00| 0x17| 0xF8 0x4A |
含义:
0x01:从机的地址
0x03:查询功能,读取从机寄存器的数据
0x02: 返回字节数为2个 一个寄存器2个字节
0x00 0x17:寄存器的值是0017
0xF8 0x4A: 循环冗余校验 CRC
2、主机对从机写数据操作
主机发送报文格式如下:
从站地址 | 功能码 | 数据地址(高) | 数据地址(低) | 数据(高) | 数据(低) | 校验 |
---|---|---|---|---|---|---|
0x01 | 0x06 | 0x00 | 0x01 | 0x00 | 0x17 | 0x98 0x04 |
含义:
0x01:从机的地址
0x06:修改功能,修改从机寄存器的数据
0x00 0x01: 代表修改的起始寄存器地址.说明修改0x0000-0x0001的存储内容
0x00 0x17: 要修改的数据值为0017
0x98 0x04: 循环冗余校验 CRC
从机回复报文格式如下:
从站地址 | 功能码 | 数据地址(高) | 数据地址(低) | 数据(高) | 数据(低) | 校验 |
---|---|---|---|---|---|---|
0x01 | 0x06 | 0x00 | 0x01 | 0x00 | 0x17 | 0x98 0x04 |
含义:
0x01:从机的地址
0x06:修改功能,修改从机寄存器的数据
0x00 0x01: 代表修改的起始寄存器地址.说明是0x0000
0x00 0x17:修改的值为0017
0x98 0x04: 循环冗余校验 CRC
从机的回复和主机的发送是一样的,如果不一样说明出现了错误
Modbus-ACSII协议
在消息中的每个字节都作为两个ASCII字符发送
十六进制的0-F 分别对应ASCII字符的0…9,A…F
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
需要这份系统化的资料的朋友,可以添加V获取:vip1024b (备注Go)
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
Modbus-ACSII协议
在消息中的每个字节都作为两个ASCII字符发送
十六进制的0-F 分别对应ASCII字符的0…9,A…F
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
需要这份系统化的资料的朋友,可以添加V获取:vip1024b (备注Go)
[外链图片转存中…(img-TGoBXJJa-1713244823098)]
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!