技术专栏
ModBus RTU协议 -->c语言实现
文章目录
ModBus RTU协议
前言: 最近在SS528上适配传感器,其中就有一款传感器是rs485通信,于是就接触到ModBus RTU协议,我赶紧上网查找相应的资料,发现相关代码多还是多,就是全都要money,经过一小段时间的摸索和尝试,基本完成了通信功能,能够实现数据的接收与发送,代码我就放在最后啦,有需要的朋友可以自取
1 ModBus RTU协议简介
Modbus RTU(Remote Terminal Unit,远程终端单元)是一种串行通信协议,用于在自动化领域中的设备之间进行通信。它通常用于工业控制系统和自动化领域中的设备之间进行数据传输。
ModBus RTU协议格式:
帧格式: Modbus RTU协议的数据帧包含了地址、功能码、数据、CRC(循环冗余校验)和结束位。它可以被分为发送方和接收方。
地址: 每个设备在总线上都有一个唯一的地址,用于识别通信的目标设备。
功能码: 它指示了设备执行的特定功能,如读取寄存器、写入寄存器、读取输入状态等。
数据: 数据部分包含了传输的实际信息。
CRC校验: 用于检测数据传输的错误,以保证数据的准确性。
2 ModBus RTU数据帧示例
示例数据问询帧如下图所示:
示例数据应答帧如下图所示:
3 ModBus RTU 具体代码实现
我们根据2 的数据帧示例来进行编写代码,具体代码如下
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <termios.h>
#include <stdint.h>
int init_port(int serialPort)
{
const char *serialPort = "/dev/ttyAMA3";
int serial_fd ;
// Open the serial port
serial_fd = open(serialPort, O_RDWR | O_NOCTTY);
if (serial_fd == -1) {
handleError("Error opening serial port");
}
struct termios tty;
if (tcgetattr(serial_fd, &tty) != 0) {
perror("Error from tcgetattr");
close(serial_fd);
return -1;
}
// 设置为非规范模式(二进制模式)
tty.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON);
tty.c_oflag &= ~OPOST;
tty.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
tty.c_cflag &= ~(CSIZE | PARENB);
tty.c_cflag |= CS8;
// 设置波特率
cfsetospeed(&tty, B9600);
cfsetispeed(&tty, B9600);
if (tcsetattr(serial_fd, TCSANOW, &tty) != 0) {
perror("Error from tcsetattr");
close(serial_fd);
return -1;
}
return serial_fd;
}
int pm_get(int serialPort)
{
unsigned char modbus_setframe[] = {0x01,0x03,0x00,0x07,0x00,0x03,0xB4,0x0A};
write(serialPort, modbus_setframe, 8);
// Read data from the serial port
char buffer[20];
ssize_t bytesRead=0;
bytesRead = read(serialPort, buffer, 20);
if (bytesRead == 0) {
printf("No data received.\n");
} else {
handleError("Error reading from serial port");
}
uint8_t address = buffer[0];
uint8_t functioncode = buffer[1];
uint16_t PM1_0 = (buffer[3] << 8) | buffer[4];
uint16_t PM2_5 = (buffer[5] << 8) | buffer[6];
uint16_t PM10_0 = (buffer[7] << 8) | buffer[8];
//此处省略crc校验
printf("addr:0x%02X,Funcode:0x%02X \n",address,functioncode);
printf("PW1.5 data is %d ,PWD2.5 data is %d,PWD10 data is %d\n",PM1_0,PM2_5,PM10_0);
return 0;
}
int main() {
int ret;
int len;
int serialPort = open("/dev/ttyAMA3", O_RDWR);
if (serialPort == -1) {
perror("Error opening serial port");
exit(1);
}
// 配置串口参数
ret=init_port(serialPort);
pm_get(serialPort );
close(serialPort);
}
声明:本文内容由易百纳平台入驻作者撰写,文章观点仅代表作者本人,不代表易百纳立场。如有内容侵权或者其他问题,请联系本站进行删除。
红包
1
1
评论
打赏
- 分享
- 举报
评论
0个
手气红包
暂无数据
相关专栏
-
浏览量:2423次2020-07-17 17:00:06
-
浏览量:2595次2020-12-07 10:07:25
-
浏览量:5830次2024-05-09 13:53:10
-
浏览量:412次2023-09-07 10:23:44
-
浏览量:714次2024-05-27 19:35:18
-
浏览量:1818次2019-11-14 09:08:28
-
浏览量:654次2023-08-04 10:52:30
-
浏览量:2355次2024-05-17 12:55:02
-
浏览量:553次2023-10-10 17:06:12
-
浏览量:1913次2022-11-17 15:30:20
-
浏览量:2920次2020-07-24 10:45:35
-
浏览量:9176次2020-12-12 14:56:13
-
浏览量:2366次2020-09-04 13:47:44
-
浏览量:6902次2021-01-22 15:28:47
-
浏览量:650次2023-08-21 10:31:38
-
浏览量:1883次2023-04-19 09:11:40
-
浏览量:4180次2020-10-28 23:08:53
-
浏览量:6482次2020-10-28 23:03:59
-
浏览量:5401次2021-01-12 18:39:45
置顶时间设置
结束时间
删除原因
-
广告/SPAM
-
恶意灌水
-
违规内容
-
文不对题
-
重复发帖
打赏作者
易百纳用户53690
您的支持将鼓励我继续创作!
打赏金额:
¥1
¥5
¥10
¥50
¥100
支付方式:
微信支付
打赏成功!
感谢您的打赏,如若您也想被打赏,可前往 发表专栏 哦~
举报反馈
举报类型
- 内容涉黄/赌/毒
- 内容侵权/抄袭
- 政治相关
- 涉嫌广告
- 侮辱谩骂
- 其他
详细说明
审核成功
发布时间设置
发布时间:
请选择发布时间设置
是否关联周任务-专栏模块
审核失败
失败原因
请选择失败原因
备注
请输入备注