SimpleModbusRTUPacket
Modbus.c
浏览该文件的文档.
1 
9 #include "Modbus.h"
10 
11 static uint16_t Modbus_ReadUint16_From_2Bytes(uint8_t *pos)
12 {
13  //modbus的16位数据高字节在前,低字节在后
14  uint16_t ret=pos[0];
15  ret<<=8;
16  ret+=pos[1];
17 
18  return ret;
19 };
20 
21 static void Modbus_WriteUint16_To_2Bytes(uint8_t *pos,uint16_t dat)
22 {
23  //modbus的16位数据高字节在前,低字节在后
24  pos[0]=(dat>>8);
25  pos[1]=(dat&0xff);
26 }
27 
28 static uint16_t CRC16(uint8_t *arr_buff,size_t len)
29 {
30  uint16_t crc=0xFFFF;
31  size_t i, j;
32  for ( j=0; j<len; j++)
33  {
34  crc=crc ^*arr_buff++;
35  for ( i=0; i<8; i++)
36  {
37  if( ( crc&0x0001) >0)
38  {
39  crc=crc>>1;
40  crc=crc^ 0xa001;
41  }
42  else
43  crc=crc>>1;
44  }
45  }
46  return ( crc);
47 }
48 
49 /*
50  检查数据的crc,payload:整帧数据(包含CRC),payload_length:长度(包含CRC)
51 */
52 bool Modbus_Payload_Check_CRC(uint8_t *payload,size_t payload_length)
53 {
54  if(payload_length<=2)
55  {
56  return false;
57  }
58 
59  uint16_t crc1=CRC16(payload,payload_length-2);
60  uint16_t crc2=payload[payload_length-1];
61  crc2<<=8;
62  crc2+=payload[payload_length-2];
63 
64  return crc1==crc2;
65 
66 }
67 
68 /*
69  添加末尾的crc校验,payload:整帧数据(不包含CRC),payload_length:长度(包含CRC)
70 */
71 bool Modbus_Payload_Append_CRC(uint8_t *payload,size_t payload_length)
72 {
73  if(payload_length<=2)
74  {
75  return false;
76  }
77 
78  uint16_t crc=CRC16(payload,payload_length-2);
79 
80  payload[payload_length-2]=(crc&0xff);
81  payload[payload_length-1]=(crc>>8);
82 
83  return true;
84 }
85 
86 /*
87 Modbus从机解析输入。ctx:上下文指针,input_data:输入数据指针,input_data_length:输入数据长度,buff:缓冲(存放临时数据),buff_length:缓冲长度
88 */
89 
90 bool Modbus_Slave_Parse_Input(modbus_slave_context_t *ctx,uint8_t *input_data,size_t input_data_length,uint8_t *buff,size_t buff_length)
91 {
92  if(ctx==NULL || input_data ==NULL || input_data_length <=2 || buff==NULL || buff_length <=2 || buff_length<input_data_length)
93  {
94  return false;
95  }
96 
97  if(!Modbus_Payload_Check_CRC(input_data,input_data_length))
98  {
99  return false;
100  }
101 
102  size_t output_length=0;
103 
104  switch(input_data[1])
105  {
106  case 0x01:
107  {
108  //读取线圈
109 
110  if(input_data[0]!=ctx->slave_addr)
111  {
112  //非本从机
113  break;
114  }
115 
116  if(input_data!=buff)
117  {
118  //将下发的指令复制到buff
119  memcpy(buff,input_data,input_data_length);
120  }
121 
122 
123  if(ctx->read_OX!=NULL)
124  {
125  uint16_t start_addr=Modbus_ReadUint16_From_2Bytes(&buff[2]);
126  uint16_t length=Modbus_ReadUint16_From_2Bytes(&buff[4]);
127  uint8_t byte_count=length/8+((length%8!=0)?1:0);
128  buff[2]=byte_count;
129 
130  output_length=5+byte_count;
131 
132  if(output_length>buff_length)
133  {
134  break;
135  }
136 
137  for(size_t i=0; i<length; i++)
138  {
139  if(i%8==0)
140  {
141  buff[3+i/8]=0xff;
142  }
143 
144  if(ctx->read_OX(start_addr+i))
145  {
146  buff[3+i/8]|=(0x01<<(i%8));
147  }
148  else
149  {
150  buff[3+i/8]&=(~(0x01<<(i%8)));
151  }
152  }
153 
154 
155  }
156 
157  }
158  break;
159 
160  case 0x02:
161  {
162  //读输入线圈
163 
164  if(input_data[0]!=ctx->slave_addr)
165  {
166  //非本从机
167  break;
168  }
169 
170  if(input_data!=buff)
171  {
172  //将下发的指令复制到buff
173  memcpy(buff,input_data,input_data_length);
174  }
175 
176 
177  if(ctx->read_IX!=NULL)
178  {
179  uint16_t start_addr=Modbus_ReadUint16_From_2Bytes(&buff[2]);
180  uint16_t length=Modbus_ReadUint16_From_2Bytes(&buff[4]);
181  uint8_t byte_count=length/8+((length%8!=0)?1:0);
182  buff[2]=byte_count;
183 
184  output_length=5+byte_count;
185 
186  if(output_length>buff_length)
187  {
188  break;
189  }
190 
191  for(size_t i=0; i<length; i++)
192  {
193  if(i%8==0)
194  {
195  buff[3+i/8]=0xff;
196  }
197 
198  if(ctx->read_IX(start_addr+i))
199  {
200  buff[3+i/8]|=(0x01<<(i%8));
201  }
202  else
203  {
204  buff[3+i/8]&=(~(0x01<<(i%8)));
205  }
206  }
207 
208 
209  }
210 
211  }
212  break;
213  case 0x03:
214  {
215  //读保持寄存器
216  if(input_data[0]!=ctx->slave_addr)
217  {
218  //非本从机
219  break;
220  }
221 
222  if(input_data!=buff)
223  {
224  //将下发的指令复制到buff
225  memcpy(buff,input_data,input_data_length);
226  }
227 
228 
229  if(ctx->read_hold_register!=NULL)
230  {
231  uint16_t start_addr=Modbus_ReadUint16_From_2Bytes(&buff[2]);
232  uint16_t length=Modbus_ReadUint16_From_2Bytes(&buff[4]);
233  if(length >127)
234  {
235  break;
236  }
237  uint8_t byte_count=length*2;
238  buff[2]=byte_count;
239 
240  output_length=5+byte_count;
241 
242  if(output_length>buff_length)
243  {
244  break;
245  }
246 
247  for(size_t i=0; i<length; i++)
248  {
249  uint16_t dat=ctx->read_hold_register(start_addr+i);
250  Modbus_WriteUint16_To_2Bytes(&buff[3+2*i],dat);
251  }
252 
253 
254  }
255  }
256  break;
257 
258  case 0x04:
259  {
260  //读输入寄存器
261  if(input_data[0]!=ctx->slave_addr)
262  {
263  //非本从机
264  break;
265  }
266 
267  if(input_data!=buff)
268  {
269  //将下发的指令复制到buff
270  memcpy(buff,input_data,input_data_length);
271  }
272 
273 
274  if(ctx->read_input_register!=NULL)
275  {
276  uint16_t start_addr=Modbus_ReadUint16_From_2Bytes(&buff[2]);
277  uint16_t length=Modbus_ReadUint16_From_2Bytes(&buff[4]);
278  if(length >127)
279  {
280  break;
281  }
282  uint8_t byte_count=length*2;
283  buff[2]=byte_count;
284 
285  output_length=5+byte_count;
286 
287  if(output_length>buff_length)
288  {
289  break;
290  }
291 
292  for(size_t i=0; i<length; i++)
293  {
294  uint16_t dat=ctx->read_input_register(start_addr+i);
295  Modbus_WriteUint16_To_2Bytes(&buff[3+2*i],dat);
296  }
297 
298 
299  }
300 
301  }
302  break;
303 
304  case 0x05:
305  {
306  //强制设置单个输出线圈
307  if(input_data[0]!=ctx->slave_addr)
308  {
309  //非本从机
310  break;
311  }
312 
313  if(input_data!=buff)
314  {
315  //将下发的指令复制到buff
316  memcpy(buff,input_data,input_data_length);
317  }
318 
319  output_length=input_data_length;
320 
321  if(ctx->write_OX!=NULL)
322  {
323  uint16_t addr=Modbus_ReadUint16_From_2Bytes(&buff[2]);
324  uint16_t data=Modbus_ReadUint16_From_2Bytes(&buff[4]);
325  ctx->write_OX(addr,data);
326  }
327 
328  }
329  break;
330 
331  case 0x06:
332  {
333  //设置单个保持寄存器
334  if(input_data[0]!=ctx->slave_addr)
335  {
336  //非本从机
337  break;
338  }
339 
340  if(input_data!=buff)
341  {
342  //将下发的指令复制到buff
343  memcpy(buff,input_data,input_data_length);
344  }
345 
346  output_length=input_data_length;
347 
348  if(ctx->write_hold_register!=NULL)
349  {
350  uint16_t addr=Modbus_ReadUint16_From_2Bytes(&buff[2]);
351  uint16_t data=Modbus_ReadUint16_From_2Bytes(&buff[4]);
352  ctx->write_hold_register(addr,data);
353  }
354 
355  }
356  break;
357 
358  case 0x0F:
359  {
360  //设置多个输出线圈
361  if(input_data[0]!=ctx->slave_addr && input_data[0]==0)
362  {
363  //非本从机或广播地址
364  break;
365  }
366 
367  if(input_data!=buff)
368  {
369  //将下发的指令复制到buff
370  memcpy(buff,input_data,input_data_length);
371  }
372 
373  buff[0]=ctx->slave_addr;
374  output_length=8;
375 
376  if(ctx->write_OX!=NULL)
377  {
378  uint16_t start_addr=Modbus_ReadUint16_From_2Bytes(&buff[2]);
379  uint16_t length=Modbus_ReadUint16_From_2Bytes(&buff[4]);
380 
381  for(size_t i=0; i<length; i++)
382  {
383  if((buff[7+i/8]&(0x01<<(i%8)))!=0)
384  {
385  ctx->write_OX(start_addr+i,0xFF00);
386  }
387  else
388  {
389  ctx->write_OX(start_addr+i,0x0000);
390  }
391  }
392 
393 
394  }
395  }
396  break;
397  case 0x10:
398  {
399  //设置多个保持寄存器
400  if(input_data[0]!=ctx->slave_addr && input_data[0]==0)
401  {
402  //非本从机或广播地址
403  break;
404  }
405 
406  if(input_data!=buff)
407  {
408  //将下发的指令复制到buff
409  memcpy(buff,input_data,input_data_length);
410  }
411 
412  buff[0]=ctx->slave_addr;
413  output_length=8;
414 
415  if(ctx->write_hold_register!=NULL)
416  {
417  uint16_t start_addr=Modbus_ReadUint16_From_2Bytes(&buff[2]);
418  uint16_t length=Modbus_ReadUint16_From_2Bytes(&buff[4]);
419 
420  for(size_t i=0; i<length; i++)
421  {
422  ctx->write_hold_register(start_addr+i,Modbus_ReadUint16_From_2Bytes(&buff[7+2*i]));
423  }
424 
425  }
426 
427 
428  }
429  break;
430 
431  default:
432  break;
433  }
434 
435  if(output_length>2)
436  {
437  if(buff_length>=output_length)
438  {
439  Modbus_Payload_Append_CRC(buff,output_length);
440  if(ctx->output!=NULL)
441  {
442  ctx->output(buff,output_length);
443  }
444  }
445  else
446  {
447  return false;
448  }
449  }
450  return true;
451 }
452 
453 bool Modbus_Master_Read_OX(modbus_master_context_t *ctx,uint16_t start_addr,bool *data,size_t number,uint8_t *buff,size_t buff_length)
454 {
455  if(ctx==NULL || data ==NULL || buff == NULL || number == 0 || buff_length == 0 || ctx->output ==NULL ||ctx->request_reply ==NULL)
456  {
457  //参数不正确
458  return false;
459  }
460 
461  if(number > MODBUS_MAX_READ_BITS)
462  {
463  return false;
464  }
465 
466  size_t output_length=8;
467  size_t input_length=5+number/8+((number%8==0)?0:1);
468 
469  if(output_length>buff_length || input_length> buff_length)
470  {
471  return false;
472  }
473 
474  {
475  //填写参数
476  buff[0]=ctx->slave_addr;
477  buff[1]=0x01;//查询输出状态
478  Modbus_WriteUint16_To_2Bytes(&buff[2],start_addr);
479  Modbus_WriteUint16_To_2Bytes(&buff[4],number);
480  Modbus_Payload_Append_CRC(buff,output_length);
481  }
482 
483  ctx->output(buff,output_length);
484 
485  if(input_length== ctx->request_reply(buff,input_length))
486  {
487  if(Modbus_Payload_Check_CRC(buff,input_length))
488  {
489  for(size_t i=0; i<number; i++)
490  {
491  data[i]=((buff[3+i/8]&(0x01<<(i%8)))!=0);
492  }
493 
494  return true;
495  }
496  }
497 
498 
499 
500  return false;
501 
502 }
503 
504 bool Modbus_Master_Read_IX(modbus_master_context_t *ctx,uint16_t start_addr,bool *data,size_t number,uint8_t *buff,size_t buff_length)
505 {
506  if(ctx==NULL || data ==NULL || buff == NULL || number == 0 || buff_length == 0 || ctx->output ==NULL ||ctx->request_reply ==NULL)
507  {
508  //参数不正确
509  return false;
510  }
511 
512  if(number > MODBUS_MAX_READ_BITS)
513  {
514  return false;
515  }
516 
517  size_t output_length=8;
518  size_t input_length=5+number/8+((number%8==0)?0:1);
519 
520  if(output_length>buff_length || input_length> buff_length)
521  {
522  return false;
523  }
524 
525  {
526  //填写参数
527  buff[0]=ctx->slave_addr;
528  buff[1]=0x02;//查询输入状态
529  Modbus_WriteUint16_To_2Bytes(&buff[2],start_addr);
530  Modbus_WriteUint16_To_2Bytes(&buff[4],number);
531  Modbus_Payload_Append_CRC(buff,output_length);
532  }
533 
534  ctx->output(buff,output_length);
535 
536  if(input_length== ctx->request_reply(buff,input_length))
537  {
538  if(Modbus_Payload_Check_CRC(buff,input_length))
539  {
540  for(size_t i=0; i<number; i++)
541  {
542  data[i]=((buff[3+i/8]&(0x01<<(i%8)))!=0);
543  }
544 
545  return true;
546  }
547  }
548 
549 
550 
551  return false;
552 
553 }
554 
555 bool Modbus_Master_Read_Hold_Register(modbus_master_context_t *ctx,uint16_t start_addr,uint16_t *data,size_t number,uint8_t *buff,size_t buff_length)
556 {
557  if(ctx==NULL || data ==NULL || buff == NULL || number == 0 || buff_length == 0 || ctx->output ==NULL ||ctx->request_reply ==NULL)
558  {
559  //参数不正确
560  return false;
561  }
562 
563  if(number > MODBUS_MAX_READ_REGISTERS)
564  {
565  return false;
566  }
567 
568  size_t output_length=8;
569  size_t input_length=5+number*2;
570 
571  if(output_length>buff_length || input_length> buff_length)
572  {
573  return false;
574  }
575 
576  {
577  //填写参数
578  buff[0]=ctx->slave_addr;
579  buff[1]=0x03;//查询保持寄存器
580  Modbus_WriteUint16_To_2Bytes(&buff[2],start_addr);
581  Modbus_WriteUint16_To_2Bytes(&buff[4],number);
582  Modbus_Payload_Append_CRC(buff,output_length);
583  }
584 
585  ctx->output(buff,output_length);
586 
587  if(input_length== ctx->request_reply(buff,input_length))
588  {
589  if(Modbus_Payload_Check_CRC(buff,input_length))
590  {
591  for(size_t i=0; i<number; i++)
592  {
593  data[i]=Modbus_ReadUint16_From_2Bytes(&buff[3+2*i]);
594  }
595 
596  return true;
597  }
598  }
599 
600 
601 
602  return false;
603 
604 }
605 
606 bool Modbus_Master_Read_Input_Register(modbus_master_context_t *ctx,uint16_t start_addr,uint16_t *data,size_t number,uint8_t *buff,size_t buff_length)
607 {
608  if(ctx==NULL || data ==NULL || buff == NULL || number == 0 || buff_length == 0 || ctx->output ==NULL ||ctx->request_reply ==NULL)
609  {
610  //参数不正确
611  return false;
612  }
613 
614  if(number > MODBUS_MAX_READ_REGISTERS)
615  {
616  return false;
617  }
618 
619  size_t output_length=8;
620  size_t input_length=5+number*2;
621 
622  if(output_length>buff_length || input_length> buff_length)
623  {
624  return false;
625  }
626 
627  {
628  //填写参数
629  buff[0]=ctx->slave_addr;
630  buff[1]=0x04;//查询输入寄存器
631  Modbus_WriteUint16_To_2Bytes(&buff[2],start_addr);
632  Modbus_WriteUint16_To_2Bytes(&buff[4],number);
633  Modbus_Payload_Append_CRC(buff,output_length);
634  }
635 
636  ctx->output(buff,output_length);
637 
638  if(input_length== ctx->request_reply(buff,input_length))
639  {
640  if(Modbus_Payload_Check_CRC(buff,input_length))
641  {
642  for(size_t i=0; i<number; i++)
643  {
644  data[i]=Modbus_ReadUint16_From_2Bytes(&buff[3+2*i]);
645  }
646 
647  return true;
648  }
649  }
650 
651 
652 
653  return false;
654 
655 }
656 
657 /*
658 单个线圈
659 */
660 static bool Modbus_Master_Write_OX_05(modbus_master_context_t *ctx,uint16_t start_addr,bool *data,size_t number,uint8_t *buff,size_t buff_length)
661 {
662  if(ctx==NULL || data ==NULL || buff == NULL || number == 0 || buff_length == 0 || ctx->output ==NULL ||ctx->request_reply ==NULL)
663  {
664  //参数不正确
665  return false;
666  }
667 
668  size_t output_length=8;
669  size_t input_length=8;
670 
671  if(output_length>buff_length || input_length> buff_length)
672  {
673  return false;
674  }
675 
676  {
677  //填写参数
678  buff[0]=ctx->slave_addr;
679  buff[1]=0x05;//强制单个线圈
680  Modbus_WriteUint16_To_2Bytes(&buff[2],start_addr);
681  Modbus_WriteUint16_To_2Bytes(&buff[4],data[0]?(0xFF00):(0x0000));
682  buff[6]=number/8+((number%8!=0)?1:0);
683 
684 
685  Modbus_Payload_Append_CRC(buff,output_length);
686  }
687 
688  ctx->output(buff,output_length);
689 
690  if(input_length== ctx->request_reply(buff,input_length))
691  {
692  if(Modbus_Payload_Check_CRC(buff,input_length))
693  {
694  return true;
695  }
696  }
697 
698 
699 
700  return false;
701 }
702 
703 bool Modbus_Master_Write_OX(modbus_master_context_t *ctx,uint16_t start_addr,bool *data,size_t number,uint8_t *buff,size_t buff_length)
704 {
705  if(ctx==NULL || data ==NULL || buff == NULL || number == 0 || buff_length == 0 || ctx->output ==NULL ||ctx->request_reply ==NULL)
706  {
707  //参数不正确
708  return false;
709  }
710 
711  if(number > MODBUS_MAX_WRITE_BITS)
712  {
713  return false;
714  }
715 
716  if(number==1)
717  {
718  return Modbus_Master_Write_OX_05(ctx,start_addr,data,number,buff,buff_length);
719  }
720 
721  size_t output_length=9+number/8+((number%8!=0)?1:0);
722  size_t input_length=8;
723 
724  if(output_length>buff_length || input_length> buff_length)
725  {
726  return false;
727  }
728 
729  {
730  //填写参数
731  buff[0]=ctx->slave_addr;
732  buff[1]=0x0F;//强制多个线圈
733  Modbus_WriteUint16_To_2Bytes(&buff[2],start_addr);
734  Modbus_WriteUint16_To_2Bytes(&buff[4],number);
735  buff[6]=number/8+((number%8!=0)?1:0);
736 
737  for(size_t i=0; i<number; i++)
738  {
739  if(i%8==0)
740  {
741  buff[7+i/8]=0xFF;
742  }
743  if(data[i])
744  {
745  buff[7+i/8]|=(0x01<<(i%8));
746  }
747  else
748  {
749  buff[7+i/8]&=(~(0x01<<(i%8)));
750  }
751  }
752 
753  Modbus_Payload_Append_CRC(buff,output_length);
754  }
755 
756  ctx->output(buff,output_length);
757 
758  if(input_length== ctx->request_reply(buff,input_length))
759  {
760  if(Modbus_Payload_Check_CRC(buff,input_length))
761  {
762  return true;
763  }
764  }
765 
766 
767 
768  return false;
769 }
770 
771 
772 static bool Modbus_Master_Write_Hold_Register_06(modbus_master_context_t *ctx,uint16_t start_addr,uint16_t *data,size_t number,uint8_t *buff,size_t buff_length)
773 {
774  if(ctx==NULL || data ==NULL || buff == NULL || number == 0 || buff_length == 0 || ctx->output ==NULL ||ctx->request_reply ==NULL)
775  {
776  //参数不正确
777  return false;
778  }
779 
780  size_t output_length=8;
781  size_t input_length=8;
782 
783  if(output_length>buff_length || input_length> buff_length)
784  {
785  return false;
786  }
787 
788  {
789  //填写参数
790  buff[0]=ctx->slave_addr;
791  buff[1]=0x06;//强制单个保持寄存器
792  Modbus_WriteUint16_To_2Bytes(&buff[2],start_addr);
793  Modbus_WriteUint16_To_2Bytes(&buff[4],data[0]);
794  Modbus_Payload_Append_CRC(buff,output_length);
795  }
796 
797  ctx->output(buff,output_length);
798 
799  if(input_length== ctx->request_reply(buff,input_length))
800  {
801  if(Modbus_Payload_Check_CRC(buff,input_length))
802  {
803  return true;
804  }
805  }
806 
807 
808 
809  return false;
810 }
811 
812 bool Modbus_Master_Write_Hold_Register(modbus_master_context_t *ctx,uint16_t start_addr,uint16_t *data,size_t number,uint8_t *buff,size_t buff_length)
813 {
814  if(ctx==NULL || data ==NULL || buff == NULL || number == 0 || buff_length == 0 || ctx->output ==NULL ||ctx->request_reply ==NULL)
815  {
816  //参数不正确
817  return false;
818  }
819 
820  if(number > MODBUS_MAX_WRITE_REGISTERS)
821  {
822  return false;
823  }
824 
825  if(number==1)
826  {
827  return Modbus_Master_Write_Hold_Register_06(ctx,start_addr,data,number,buff,buff_length);
828  }
829 
830  size_t output_length=9+number*2;
831  size_t input_length=8;
832 
833  if(output_length>buff_length || input_length> buff_length)
834  {
835  return false;
836  }
837 
838  {
839  //填写参数
840  buff[0]=ctx->slave_addr;
841  buff[1]=0x10;//强制多个线圈
842  Modbus_WriteUint16_To_2Bytes(&buff[2],start_addr);
843  Modbus_WriteUint16_To_2Bytes(&buff[4],number);
844  buff[6]=number*2;
845 
846  for(size_t i=0; i<number; i++)
847  {
848  Modbus_WriteUint16_To_2Bytes(&buff[7+i*2],data[i]);
849  }
850 
851  Modbus_Payload_Append_CRC(buff,output_length);
852  }
853 
854  ctx->output(buff,output_length);
855 
856  if(input_length== ctx->request_reply(buff,input_length))
857  {
858  if(Modbus_Payload_Check_CRC(buff,input_length))
859  {
860  return true;
861  }
862  }
863 
864 
865 
866  return false;
867 }
bool Modbus_Master_Read_OX(modbus_master_context_t *ctx, uint16_t start_addr, bool *data, size_t number, uint8_t *buff, size_t buff_length)
Modbus主机读取输出线圈
Definition: Modbus.c:453
bool Modbus_Master_Write_Hold_Register(modbus_master_context_t *ctx, uint16_t start_addr, uint16_t *data, size_t number, uint8_t *buff, size_t buff_length)
Modbus主机写保持寄存器
Definition: Modbus.c:812
bool Modbus_Master_Write_OX(modbus_master_context_t *ctx, uint16_t start_addr, bool *data, size_t number, uint8_t *buff, size_t buff_length)
Modbus主机写输出线圈
Definition: Modbus.c:703
bool Modbus_Slave_Parse_Input(modbus_slave_context_t *ctx, uint8_t *input_data, size_t input_data_length, uint8_t *buff, size_t buff_length)
Modbus从机解析输入。 当从机接收到一帧数据后,调用此函数。 此函数会自动调用相关回调函数完成Modbus输出。
Definition: Modbus.c:90
bool Modbus_Master_Read_IX(modbus_master_context_t *ctx, uint16_t start_addr, bool *data, size_t number, uint8_t *buff, size_t buff_length)
Modbus主机读取输入点
Definition: Modbus.c:504
bool Modbus_Payload_Check_CRC(uint8_t *payload, size_t payload_length)
检查一帧数据的crc
Definition: Modbus.c:52
bool Modbus_Master_Read_Input_Register(modbus_master_context_t *ctx, uint16_t start_addr, uint16_t *data, size_t number, uint8_t *buff, size_t buff_length)
Modbus主机读取输入寄存器
Definition: Modbus.c:606
bool Modbus_Master_Read_Hold_Register(modbus_master_context_t *ctx, uint16_t start_addr, uint16_t *data, size_t number, uint8_t *buff, size_t buff_length)
Modbus主机读取保持寄存器
Definition: Modbus.c:555
bool Modbus_Payload_Append_CRC(uint8_t *payload, size_t payload_length)
在数据帧末尾的添加crc校验
Definition: Modbus.c:71
Modbus RTU模式下数据包处理头文件
#define MODBUS_MAX_READ_REGISTERS
Definition: Modbus.h:39
#define MODBUS_MAX_WRITE_BITS
Definition: Modbus.h:30
#define MODBUS_MAX_READ_BITS
Definition: Modbus.h:29
#define MODBUS_MAX_WRITE_REGISTERS
Definition: Modbus.h:40
size_t(* request_reply)(uint8_t *data, size_t data_length)
请求数据(读串口输入),当Modbus请求发出后,会调用此函数等待从机回应,不可为NULL。
Definition: Modbus.h:182
void(* output)(uint8_t *data, size_t data_length)
串口输出函数,当解析完成后,将调用此函数输出数据,不可为NULL。
Definition: Modbus.h:172
bool(* read_IX)(size_t addr)
读取输入点(线圈)
Definition: Modbus.h:100
void(* output)(uint8_t *data, size_t data_length)
串口输出函数,当解析完成后,将调用此函数输出数据,不可为NULL。
Definition: Modbus.h:92
void(* write_hold_register)(size_t addr, uint16_t data)
写保持寄存器
Definition: Modbus.h:132
bool(* read_OX)(size_t addr)
读输出线圈
Definition: Modbus.h:116
uint16_t(* read_hold_register)(size_t addr)
读保持寄存器
Definition: Modbus.h:124
void(* write_OX)(size_t addr, uint16_t data)
写输出线圈
Definition: Modbus.h:109
uint8_t slave_addr
Definition: Modbus.h:83
uint16_t(* read_input_register)(size_t addr)
读输入寄存器
Definition: Modbus.h:140