RS485协议是什么?它和Modbus协议的区分以及C语言实现

1.RS485的定义

相信做自动化或者智能设备的朋友都听说过RS485协议,RS485通信协议是一种多点通信协议,它允许多个设备在同一总线上进行通信,且每个设备都可以发送和接收数据。RS485通讯协议采用差分信号传输,具有高速、远距离、可靠性强等特点,可实现长距离的数据传输。

RS485通信协议支持半双工通信模式,在同一总线上可以连接多个驱动器和接收器,方便建立设备网络。此外,RS485通信协议的接口电平低,不易损坏芯片,电平与TTL电平兼容,方便与TTL电路连接。RS485通信协议是一种适用于工业控制系统和智能家居等领域的通信协议,具有高速、远距离、可靠性强等优点,能够满足大量数据传输的需求,并提高数据传输的效率和实时性。

2.RS485与Modbus区别

协议性质:RS485是一种物理层通信标准,主要定义了电气特性、信号传输方式和连接方式等,而Modbus是一种通信协议,定义了一种常用的通信格式和规则,用于在主设备和从设备之间进行数据交换。

应用范围:RS485通常用作物理层协议,支持Modbus协议,而Modbus更常用于工业控制领域,是一种通用的通信数据格式,支持RS485、RS232等串口。

所以,RS485和Modbus在协议性质、应用范围和功能特性方面存在明显的区别。在工业控制和智能设备通信领域,二者常常被结合使用,以实现高效、稳定的数据传输。

在物联网中,RS485协议被广泛应用于各种领域,如工业控制、智能家居、城市管理、智能交通等。在这些领域中,RS485协议可以实现设备之间的快速、稳定、可靠的数据传输,提高设备的智能化程度和用户体验。例如,在智能家居中,RS485协议可以用于家庭内部的各种设备之间的通信,包括智能电视、智能音响、智能照明、智能安防等,实现设备的互联互通和集中控制。

3.MODBUS通讯协议及编程

MODBUS通讯协议大致分为以下几种

Modbus-RTU+Modbus-ASCII
Modbus-TCP
Modbus-Plus

Modbus是主从方式通信,也就是说,不能同步进行通信,总线上每次只有一个数据进行传输,即主机发送,从机应答,主机不发送,总线上就没有数据通信.,本文主要讲解RTU协议

3.1. Modbus-RTU协议

这种协议是基于异步串行通信上,一般的介质有:RS-232,RS485,RS-422上,这也是工业上使用的最多的。

3.1.1. 帧结构

帧结构 = 地址 + 功能吗 + 数据 + 校验

地址: 占用一个字节,范围0-255,其中有效范围是1-247,其他有特殊用途,比如255是广播地址(广播地址就是应答所有地址,正常的需要两个设备的地址一样才能进行查询和回复)

功能码:" 占用一个字节,功能码的意义就是,知道这个指令是干啥的,比如你可以查询从机的数据,也可以修改数据,所以不同功能码对应不同功能.

数据: 根据功能码不同,有不同结构,在后续的实例中有说明;

校验: 为了保证数据不错误,增加这个,然后再把前面的数据进行计算看数据是否一致,如果一致,就说明这帧数据是正确的,我再回复;如果不一样,说明你这个数据在传输的时候出了问题,数据不对的,所以就抛弃了;

字符结构

通讯数据结构

3.1.2.常用功能码

03-主机需要发送起始地址+寄存器数量,从机回复总字节数+数据;
06-主机发送起始地址+数据内容(因为你只需要修改一个,所以起始地址就是所要修改的地址),从机返回起始地址+数据内容(发现居然一样!)
10-主机发送起始地址+寄存器个数+总字节数+数据,从机返回起始地址+寄存器数量

.3常用功能码使用举例分析
1.3.1 功能码-0x03读保持寄存器

测试功能描述:
现在我是主机,我要查询从机地址为1的数据

主机发送: 01 03 00 00 00 01 84 0A
从机回复: 01 03 02 12 34 B5 33

3.2.C语言实现

mbrtu_master.h

#ifndef MBRTU_MASTER_H_
#define MBRTU_MASTER_H_

#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include "mbrtu_master.h"
#include "usart.h"
#include "tim.h"
#include "main.h"
#include "usart.h"
#include "stdio.h"  
///
/// MODBUS RTU 主机控制结构
///
///
typedef struct
{
	//
	// 收发数据缓存
	//
	uint8_t ucBuf[8];//读取可能是4个字节
	
	//
	// 收发数据状态
	//
	uint16_t usStatus;
	
	//
	// 如果使用了RTOS需要进行互斥,那么需要实现以下两个函数的绑定
	//
	void (*lock)(void);
	void (*unlock)(void);
	
	//
	// 微秒延时函数,用于等待超时
	//
	void (*delayms)(uint32_t nms);
	
	//
	// 定时器启动和停止函数
	//
	void (*timerStop)(void);
	void (*timerStart)(void);
	
	//
	// 发送数据函数,可以是串口、TCP等
	//
	uint32_t (*sendData)(const void* buf, uint32_t len);
	//把接受的数   
	uint32_t (*sendDataLog)(const void *buf, uint32_t len);
	//
	// 以下四个回调函数分别是:读线圈、读离散量输入、读保持寄存器、读输入寄存器
	//
	void (*readCoilsCallback)(uint16_t usStartAddr, uint16_t usNum, const uint8_t* pucBitsOfCoilsState, uint16_t usLen);
	void (*readDiscreteInputsCallback)(uint16_t usStartAddr, uint16_t usNum, const uint8_t* pucBitsOfDiscreteInputsState, uint16_t usLen);
	void (*readHoldingRegistersCallback)(uint16_t usStartAddr, uint16_t usNum, const uint8_t* pusHoldingRegistersVal, uint8_t usLen);
	void (*readInputRegistersCallback)(uint16_t usStartAddr, uint16_t usNum, const uint16_t* pusInputRegistersVal, uint16_t usLen);

}MBRTUMaterTypeDef;


static void timerStop(void);
static void timerStart(void);
static void delayms(uint32_t nms);
static uint32_t sendData(const void *buf, uint32_t len);
static uint32_t sendDataLog(const void *buf, uint32_t len);
static void readCoilsCallback(uint16_t usStartAddr, uint16_t usNum, const uint8_t *pucBitsOfCoilsState, uint16_t usLen);
static void readDiscreteInputsCallback(uint16_t usStartAddr, uint16_t usNum, const uint8_t *pucBitsOfDiscreteInputsState, uint16_t usLen);
static void readHoldingRegistersCallback(uint16_t usStartAddr, uint16_t usNum, const uint8_t *pusHoldingRegistersVal, uint8_t usLen);
static void readInputRegistersCallback(uint16_t usStartAddr, uint16_t usNum, const uint16_t *pusInputRegistersVal, uint16_t usLen);


///
/// MODBUS RTU 主机 API
///
///
int MBRTUMasterReadCoils(MBRTUMaterTypeDef* psModbus, uint8_t ucSlaveAddress, uint16_t usAddress, uint16_t usNum, uint16_t usTimeout);
int MB
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

驽马匠人

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值