# modbus_demo **Repository Path**: wyfcn/modbus_demo ## Basic Information - **Project Name**: modbus_demo - **Description**: No description available - **Primary Language**: C++ - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2024-08-12 - **Last Updated**: 2024-08-22 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # modbus_demo ## MODBUS调试注意事项 # 串口调试工具 0. 下载SSCOM串口工具 1. 首先确定串口通讯的端口号,波特率,数据位 2. 发送消息时,注意确定设备地址号 3. 处理软件乱码问题 # VSCode调试 1. View进入Terminal 2. 进入文件路径 3. 调试:g++ main.cpp 4. 调试:./a.exe # 代码 # 基本功能: 1. main.cpp 通过串口与外部设备进行通信。程序首先打开串口(COM3),然后初始化一个数组buf并向其中写入一些十六进制数据,再通过串口发送这些数据。接着进入循环,不断尝试从串口读取数据并打印出来,然后再将读取到的数据发送回去。最后在程序结束时关闭了串口。整体实现了一个简单的串口通信回环功能。 2. serial.cpp 是一个串口通信的类,实现了串口的打开、关闭、读取和写入功能。具体来说: 1. `Open`函数用于打开串口,并设置波特率、数据位、校验位和停止位等参数。 2. `Close`函数用于关闭串口。 3. `Write`函数用于向串口写入数据。 4. `Read`函数用于从串口读取数据。 在Windows系统下,使用了`CreateFile`等相关函数来操作串口;在其他系统下,使用了`open`、`tcgetattr`、`tcsetattr`等相关函数来操作串口。整体功能是通过串口与外部设备进行数据交换。 3. timeout.cpp 实现了一个简单的计时器功能。具体来说: 1. `timeout`类的构造函数`timeout::timeout(int time)`用于初始化计时器,传入参数`time`表示计时器的最大时间。 2. `start`函数`void timeout::start(void)`用于启动计时器,记录当前时间。 3. `end`函数`char timeout::end(void)`用于判断计时器是否超时,如果超过设定的最大时间,则返回0,否则返回1。 # 完善功能: modbus.cpp 定义了一个名为 modbus 的类,用于处理 Modbus 协议相关的数据包构建、CRC 校验计算以及数据包解析等功能 1. 构建 Modbus 请求数据包 (1)设置数据包中的从机地址 address 和功能码 function。 (2)将用户提供的数据 data 复制到 m_data 数组中。 (3)计算整个数据包的 CRC-16 校验值,并将高位和低位分别存储在数据包的末尾。 (4)返回构建后的数据包的总长度。 2. 解析 Modbus 响应数据包 (1)检查数据包长度是否至少为 5 字节。 (2)提取从机地址和功能码。 (3)检查数据包长度是否与预期相符。 (4)提取数据包中的有效数据。 (5)计算数据包的 CRC-16 校验值,并与数据包中的校验值比较。 (6)如果校验成功,则返回 0 表示成功;否则返回错误码。 3. 计算 CRC-16 校验值 (1)初始化 CRC 寄存器为 0xFFFF。 (2)对于数据包中的每个字节,进行逐位异或操作,并进行循环右移。 (3)如果最低位为 1,则将 CRC 寄存器与多项式 0xA001 进行异或操作。 (4)最后交换 CRC 寄存器的高低位以符合 Modbus 协议的要求。 (5)返回计算得到的 CRC-16 校验值。 4. 一个Modbus通信协议的响应处理函数。Response(unsigned char *data, unsigned int len) 实现了对Modbus通信协议中不同功能码的响应处理,包括数据解析和校验等操作。 (1)首先检查数据长度是否小于5,如果是则返回-1。 (2)然后检查数据的第一个字节是否等于设定的地址m_address,如果不相等则返回-2。 (3)接着从数据中提取功能码和数据长度,并检查数据长度是否与实际接收到的数据长度匹配,如果不匹配则返回-3。 (4)计算接收到数据的CRC校验值,并与数据中的CRC校验值进行比较,如果不相等则返回-3。 (5)根据功能码调用相应的处理函数,比如根据不同的功能码调用response_read_DI函数来处理读取数字输入的情况。 (6)在response_read_DI函数中,首先获取实际数据长度,然后逐个解析数据并输出。 完善main.cpp 串口打开后,进入死循环,不断尝试从串口读取数据并打印出来,然后再将读取到的数据发送回去。在循环中设置Sleep(1000),每隔1秒读取一次数据,提高效率。 注意事项: 1. 调试的时候注意关闭其他地方的串口,避免串口冲突。 2. 出现”Error Opening COM3 Port”时解决方法: (1)控制面板设备管理器查看端口是否连接上 (2)右键属性,驱动程序,更新驱动程序 (3)重新安装驱动程序 先remove再重新安装