MF32BSP_XerolySkinner 2.0.0
C++版本的驱动库
载入中...
搜索中...
未找到
bsp_ModBus.cpp
浏览该文件的文档.
1/*----------------------------------------------------------------------------------------------------
2 #
3 # Copyright (c) 2022 Yuankang Liang(XerolySkinner)
4 #
5 # 本软件按原样提供,无任何明示或暗示
6 # 在任何情况下,作者都不承担任何损害赔偿责任
7 #
8 # 使用的许可声明:
9 # 1. 不得歪曲本软件的来源,你不能声称你编写了原始软件.
10 # 2. 免费授予以任何目的,前提是版权声明出现在所有副本中.
11 # 并且版权声明和许可声明同时出现.
12 # 3. 你有使用,复制,修改,分发,和销售本软件的许可.
13 # 4. 如果你在产品中使用,产品文档中的声明是赞赏的但不是必须的.
14 # 5. 本通知不得从任何来源删除或更改.
15 #
16 # Yuankang Liang(XerolySkinner)
17 # E-mail:zabbcccbbaz@163.com
18 # QQ:2715099320
19 # Mobile Phone:13005636215
20 #
21 # All rights reserved.
22 */
23
33#pragma once
35//----------------------------------------------------------------------------------------------------
36// 头文件
37#include "bsp_ModBus.h"
38#include "bsp_CRC.h"
39#include <stdio.h>
40#include <stdlib.h>
42//----------------------------------------------------------------------------------------------------
43// 类函数
51 u8 dat[8];
52 u16 crc;
53 dat[0] = ID;
54 dat[1] = Fun_R_KeepReg;
55 dat[2] = ((u8*)(&address))[1];
56 dat[3] = ((u8*)(&address))[0];
57 dat[4] = ((u8*)(&mem))[1];
58 dat[5] = ((u8*)(&mem))[0];
59 crc = CRC16_MODBUS(dat, 6);
60 dat[6] = ((u8*)(&crc))[0];
61 dat[7] = ((u8*)(&crc))[1];
62 Transmit(dat,8);}
63//----------------------------------------------------------------------------------------------------
70void bsp_ModBus_Tx::ReadInReg(u16 address, u16 mem) {
71 u8 dat[8];
72 u16 crc;
73 dat[0] = ID;
74 dat[1] = Fun_R_InReg;
75 dat[2] = ((u8*)(&address))[1];
76 dat[3] = ((u8*)(&address))[0];
77 dat[4] = ((u8*)(&mem))[1];
78 dat[5] = ((u8*)(&mem))[0];
79 crc = CRC16_MODBUS(dat,6);
80 dat[6] = ((u8*)(&crc))[0];
81 dat[7] = ((u8*)(&crc))[1];
82 Transmit(dat, 8);}
83//----------------------------------------------------------------------------------------------------
91 u8 dat[8];
92 u16 crc;
93 dat[0] = ID;
94 dat[1] = Fun_W_OneReg;
95 dat[2] = ((u8*)(&address))[1];
96 dat[3] = ((u8*)(&address))[0];
97 dat[4] = ((u8*)(&var))[1];
98 dat[5] = ((u8*)(&var))[0];
99 crc = CRC16_MODBUS(dat, 6);
100 dat[6] = ((u8*)(&crc))[0];
101 dat[7] = ((u8*)(&crc))[1];
102 Transmit(dat, 8);}
103//----------------------------------------------------------------------------------------------------
112void bsp_ModBus_Tx::WriteRegs(u16 address,u16 mem,u16* var) {
113 u8 bytes = 9 + mem * 2;
114 u8* dat = (u8*)malloc(bytes);
115 if (dat == NULL)return;
116 u16 crc;
117 dat[0] = ID;
118 dat[1] = Fun_W_Regs;
119 dat[2] = ((u8*)(&address))[1];
120 dat[3] = ((u8*)(&address))[0];
121 dat[4] = ((u8*)(&mem))[1];
122 dat[5] = ((u8*)(&mem))[0];
123 dat[6] = mem*2;
124 // 填入数据
125 for (u8 i = 0; i < mem; i++){
126 dat[7 + i*2] = ((u8*)var)[1+i*2];
127 dat[8 + i*2] = ((u8*)var)[0+i*2];}
128 crc = CRC16_MODBUS(dat, bytes - 2);
129 dat[bytes - 2] = ((u8*)(&crc))[0];
130 dat[bytes - 1] = ((u8*)(&crc))[1];
131 Transmit(dat, bytes);
132 free(dat);}
133//----------------------------------------------------------------------------------------------------
142void bsp_ModBus_Tx::WriteRegsVar(u16 address, u16 mem,...) {
143 va_list table;
144 va_start(table,mem);
145 u16 vars;
146 u8 bytes = 9 + mem * 2;
147 u8* dat = (u8*)malloc(bytes);
148 if (dat == NULL)return;
149 u16 crc;
150 dat[0] = ID;
151 dat[1] = Fun_W_Regs;
152 dat[2] = ((u8*)(&address))[1];
153 dat[3] = ((u8*)(&address))[0];
154 dat[4] = ((u8*)(&mem))[1];
155 dat[5] = ((u8*)(&mem))[0];
156 dat[6] = mem*2;
157 // 填入数据
158 for (u8 i = 0; i < mem; i++){
159 vars=va_arg(table, u32);
160 dat[7 + i*2] = ((u8*)(&vars))[1];
161 dat[8 + i*2] = ((u8*)(&vars))[0];}
162 crc = CRC16_MODBUS(dat, bytes - 2);
163 dat[bytes - 2] = ((u8*)(&crc))[0];
164 dat[bytes - 1] = ((u8*)(&crc))[1];
165 Transmit(dat, bytes);
166 free(dat);
167 va_end(table);}
168//----------------------------------------------------------------------------------------------------
176 u8 dat[8];
177 u16 crc;
178 dat[0] = ID;
179 dat[1] = Fun_R_OutCoil;
180 dat[2] = ((u8*)(&address))[1];
181 dat[3] = ((u8*)(&address))[0];
182 dat[4] = ((u8*)(&mem))[1];
183 dat[5] = ((u8*)(&mem))[0];
184 crc = CRC16_MODBUS(dat, 6);
185 dat[6] = ((u8*)(&crc))[0];
186 dat[7] = ((u8*)(&crc))[1];
187 Transmit(dat, 8);}
188//----------------------------------------------------------------------------------------------------
196 u8 dat[8];
197 u16 crc;
198 dat[0] = ID;
199 dat[1] = Fun_R_InCoil;
200 dat[2] = ((u8*)(&address))[1];
201 dat[3] = ((u8*)(&address))[0];
202 dat[4] = ((u8*)(&mem))[1];
203 dat[5] = ((u8*)(&mem))[0];
204 crc = CRC16_MODBUS(dat, 6);
205 dat[6] = ((u8*)(&crc))[0];
206 dat[7] = ((u8*)(&crc))[1];
207 Transmit(dat, 8);}
208//----------------------------------------------------------------------------------------------------
218 u8 dat[8];
219 u16 var = state ? 0xFF00 : 0x0000;
220 u16 crc;
221 dat[0] = ID;
222 dat[1] = Fun_W_OneCoil;
223 dat[2] = ((u8*)(&address))[1];
224 dat[3] = ((u8*)(&address))[0];
225 dat[4] = ((u8*)(&var))[1];
226 dat[5] = ((u8*)(&var))[0];
227 crc = CRC16_MODBUS(dat, 6);
228 dat[6] = ((u8*)(&crc))[0];
229 dat[7] = ((u8*)(&crc))[1];
230 Transmit(dat, 8);}
231//----------------------------------------------------------------------------------------------------
240void bsp_ModBus_Tx::WriteCoils(u16 address, u16 mem, u8* var) {
241 u8 bytes = (mem / 8) + (mem % 8 != 0) + 9;
242 u8* dat = (u8*)malloc(bytes);
243 if (dat == NULL)return;
244 u16 crc;
245 dat[0] = ID;
246 dat[1] = Fun_W_Coils;
247 dat[2] = ((u8*)(&address))[1];
248 dat[3] = ((u8*)(&address))[0];
249 dat[4] = ((u8*)(&mem))[1];
250 dat[5] = ((u8*)(&mem))[0];
251 dat[6] = bytes - 9;
252 // 填入数据
253 for (u8 i = 0; i < bytes - 9; i++)dat[7 + i] = var[i];
254 crc = CRC16_MODBUS(dat, bytes - 2);
255 dat[bytes - 2] = ((u8*)(&crc))[0];
256 dat[bytes - 1] = ((u8*)(&crc))[1];
257 Transmit(dat, bytes);
258 free(dat);}
259//----------------------------------------------------------------------------------------------------
268void bsp_ModBus_Tx::WriteCoilsVar(u16 address, u16 mem,...) {
269 va_list table;
270 va_start(table,mem);
271 u8 var=0;
272 u16 crc;
273 u8 bytes = (mem / 8) + (mem % 8 != 0) + 9;
274 u8* dat = (u8*)malloc(bytes);
275 if (dat == NULL)return;
276 dat[0] = ID;
277 dat[1] = Fun_W_Coils;
278 dat[2] = ((u8*)(&address))[1];
279 dat[3] = ((u8*)(&address))[0];
280 dat[4] = ((u8*)(&mem))[1];
281 dat[5] = ((u8*)(&mem))[0];
282 dat[6] = bytes - 9;
283 // 填入管脚信息
284 for(u16 i=0;i<mem;i++){
285 var=va_arg(table,u32);
286 if(var)
287 dat[7 + (i/8)]|=1<<(i%8);
288 else
289 dat[7 + (i/8)]&=~(1<<(i%8));}
290 crc = CRC16_MODBUS(dat, bytes - 2);
291 dat[bytes - 2] = ((u8*)(&crc))[0];
292 dat[bytes - 1] = ((u8*)(&crc))[1];
293 Transmit(dat, bytes);
294 free(dat);
295 va_end(table);}
297//----------------------------------------------------------------------------------------------------
298// 类函数
305 u16 crc = 0;
306 ID = dat[0];
307 Func = dat[1];
308 // 释放缓存内存
309 free(OutCoilDat);
310 free(InCoilDat);
311 free(KeepRegDat);
312 free(InRegDat);
313 // CRC检验
314 if (Func == Fun_R_OutCoil ||
315 Func == Fun_R_InCoil ||
316 Func == Fun_R_KeepReg ||
317 Func == Fun_R_InReg) {
318 crc = CRC16_MODBUS(dat, dat[2] + 3);
319 crcts = ( ((u8*)(&crc))[1] == dat[dat[2] + 3] &&
320 ((u8*)(&crc))[0] == dat[dat[2] + 4]);}
321 switch (Func) {
322 case Fun_R_OutCoil:
323 // 输出线圈
324 OutCoilMem = dat[2];
325 OutCoilDat = (u8*)malloc(OutCoilMem);
326 if (OutCoilDat == NULL)break;
327 for (u8 i = 0; i < OutCoilMem; i++)
328 OutCoilDat[i] = dat[3 + i];
329 break;
330 case Fun_R_InCoil:
331 // 输入线圈
332 InCoilMem = dat[2];
333 InCoilDat = (u8*)malloc(InCoilMem);
334 if (InCoilDat == NULL)break;
335 for (u8 i = 0; i < InCoilMem; i++)
336 InCoilDat[i] = dat[3 + i];
337 break;
338 case Fun_R_KeepReg:
339 // 保持寄存器
340 KeepRegMem = dat[2] / 2;
341 KeepRegDat = (u16*)malloc(KeepRegMem * 2);
342 if (KeepRegDat == NULL)break;
343 for (u8 i = 0; i < KeepRegMem; i++) {
344 ((u8*)KeepRegDat)[1 + i * 2] = dat[3 + i * 2];
345 ((u8*)KeepRegDat)[0 + i * 2] = dat[4 + i * 2];}
346 break;
347 case Fun_R_InReg:
348 // 输入寄存器
349 InRegMem = dat[2] / 2;
350 InRegDat = (u16*)malloc(InRegMem * 2);
351 if (InRegDat == NULL)break;
352 for (u8 i = 0; i < InRegMem; i++) {
353 ((u8*)InRegDat)[1 + i * 2] = dat[3 + i * 2];
354 ((u8*)InRegDat)[0 + i * 2] = dat[4 + i * 2];}
355 break;
356 default:
357 // 写回显与其他
358 break;}}
360//----------------------------------------------------------------------------------------------------
361// 构造函数
364//----------------------------------------------------------------------------------------------------
366 KeepRegDat = NULL;
367 InRegDat = NULL;
368 OutCoilDat = NULL;
369 InCoilDat = NULL;}
370//----------------------------------------------------------------------------------------------------
372 free(OutCoilDat);
373 free(InCoilDat);
374 free(KeepRegDat);
375 free(InRegDat);}
u16 CRC16_MODBUS(u8 *pucFrame, u16 usLen)
Definition: bsp_CRC.cpp:91
CRC16校验
ModBus通信函数
@ Fun_W_Coils
写入多线圈
Definition: bsp_ModBus.h:49
@ Fun_W_OneReg
写入单寄存
Definition: bsp_ModBus.h:48
@ Fun_W_Regs
写入多寄存
Definition: bsp_ModBus.h:50
@ Fun_R_InCoil
读取输入线圈
Definition: bsp_ModBus.h:43
@ Fun_W_OneCoil
写入单线圈
Definition: bsp_ModBus.h:47
@ Fun_R_KeepReg
读取保持寄存
Definition: bsp_ModBus.h:44
@ Fun_R_InReg
读取输入寄存
Definition: bsp_ModBus.h:45
@ Fun_R_OutCoil
读取输出线圈
Definition: bsp_ModBus.h:42
u8 ID
器件ID
Definition: bsp_ModBus.h:89
u16 * KeepRegDat
Definition: bsp_ModBus.h:93
u8 Func
功能号
Definition: bsp_ModBus.h:90
void analysis(u8 *dat)
以ModBus协议分析缓冲区内数据
Definition: bsp_ModBus.cpp:304
u8 * OutCoilDat
Definition: bsp_ModBus.h:99
bsp_ModBus_Rx(void)
Definition: bsp_ModBus.cpp:365
u16 * InRegDat
Definition: bsp_ModBus.h:96
u8 crcts
CRC测试
Definition: bsp_ModBus.h:91
~bsp_ModBus_Rx(void)
Definition: bsp_ModBus.cpp:371
void WriteOneReg(u16 address, u16 var)
发送写一个寄存器的指令
Definition: bsp_ModBus.cpp:90
void WriteRegs(u16 address, u16 mem, u16 *var)
发送写多个寄存器的指令
Definition: bsp_ModBus.cpp:112
void WriteCoilsVar(u16 address, u16 mem,...)
发送写多个线圈的指令
Definition: bsp_ModBus.cpp:268
u8 ID
器件ID
Definition: bsp_ModBus.h:76
void WriteCoils(u16 address, u16 mem, u8 *var)
发送写多个线圈的指令
Definition: bsp_ModBus.cpp:240
void ReadInCoil(u16 address, u16 mem)
发送读输入线圈的指令
Definition: bsp_ModBus.cpp:195
void WriteOneCoil(u16 address, u16 state)
发送写入一个线圈的指令
Definition: bsp_ModBus.cpp:217
void ReadOutCoil(u16 address, u16 mem)
发送读输出线圈的指令
Definition: bsp_ModBus.cpp:175
virtual void Transmit(u8 *dat, u16 len)=0
bsp_ModBus_Tx(u8 ID)
Definition: bsp_ModBus.cpp:362
void WriteRegsVar(u16 address, u16 mem,...)
发送写多个寄存器的指令
Definition: bsp_ModBus.cpp:142
void ReadKeepReg(u16 address, u16 mem)
发送读取保存寄存器的指令
Definition: bsp_ModBus.cpp:50
void ReadInReg(u16 address, u16 mem)
发送读取输入寄存器的指令
Definition: bsp_ModBus.cpp:70
uint8_t u8
8位无符号数类型
Definition: varint.h:40
uint16_t u16
16位无符号数类型
Definition: varint.h:41
uint32_t u32
32位无符号数类型
Definition: varint.h:42