你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

【经验分享】STM32移植FreeModbus实现ModBusRTU协议

[复制链接]
STMCU小助手 发布时间:2022-4-23 15:41
首先将FreeModbus移植到自己工程中,如下图所示:
$ B, x: c6 }8 j" N- }( W. _ 20200323104757628.png
, x4 ?& f2 n! O  l9 M
& e: Y' K3 P/ }: W- @然后修改portserial.c和porttimer.c文件:; C+ [' z; j6 n
portserial.c
+ P# x1 I/ F8 K: M, ~
% q/ Y: T2 u% E" c$ g; \: e1 q
  1. /*
    & S* _( C; Y( m) k# m: H
  2. * FreeModbus Libary: BARE Port0 n+ F5 A3 i/ B/ B( Y8 R/ ]
  3. * Copyright (C) 2006 Christian Walter
    ; G! U2 S4 R- H2 R; ]
  4. *7 |4 ~" Y  j( Z6 Y
  5. * This library is free software; you can redistribute it and/or
    / b2 X: h/ R$ Q0 k, g! @8 y
  6. * modify it under the terms of the GNU Lesser General Public
    # A; I; |1 A& j+ O$ {  v8 }/ e3 r
  7. * License as published by the Free Software Foundation; either
    + J3 h& S( b2 }
  8. * version 2.1 of the License, or (at your option) any later version.3 W% Q8 w- I3 x9 _& y
  9. *
    ! Y& U) v/ d$ a4 l2 k) \; G# E% l0 m
  10. * This library is distributed in the hope that it will be useful,* P& L/ p  W; R- K; ~: j/ g, J0 P9 K; Z
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
    / s# J/ o" d* V; ~- v
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU9 k/ _! }" F% `# P1 k: M
  13. * Lesser General Public License for more details.9 I- ^; \2 y3 J4 s' l8 m2 j; M
  14. *
    4 K$ a0 x' v6 N3 `0 W
  15. * You should have received a copy of the GNU Lesser General Public' p; P+ {. g6 c0 B- P
  16. * License along with this library; if not, write to the Free Software2 |; v* ~. B+ n1 f/ l6 j0 Q
  17. * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA" ]- N) ?# c" t: n  p7 M
  18. *
    1 K- e. ?0 M/ Y" }: O; [  z4 J& {
  19. * File: $Id: portserial.c,v 1.1 2006/08/22 21:35:13 wolti Exp $
    ' q7 j- K% }: v- t* O4 e3 A3 Y
  20. */
    - U1 D! ?' L" U: E( f, n
  21. * e5 [. I0 r3 N' V6 F
  22. #include "port.h"
    8 c/ z' C9 G, ]  }5 O  H. i
  23. #include "stm32f10x.h"5 w& g0 G' [6 J, }" s
  24. #include "modbus.h"/ n1 i* x8 N9 w
  25. /* ----------------------- Modbus includes ----------------------------------*/. s3 b, f; O; c- R/ {( C! h" A
  26. #include "mb.h"
    0 G3 q. g" V6 L! e& A) U5 Z
  27. #include "mbport.h"
    7 ~1 f5 D1 n7 o5 w

  28. . |4 N/ a' E" _! ], A: Y& G
  29. /* ----------------------- static functions ---------------------------------*/7 M  H( W% Q3 g6 r
  30. static void prvvUARTTxReadyISR( void );
    * Q; x+ P/ e3 v% S3 G
  31. static void prvvUARTRxISR( void );( `: o7 t( A6 e$ N0 i* H
  32. # w* a& @$ {3 s4 ?  c6 ]/ M% `# P
  33. /* ----------------------- Start implementation -----------------------------*/
    1 M/ \  O8 E$ K; Q
  34. void6 L& }' F4 Z" @+ ?$ V
  35. vMBPortSerialEnable( BOOL xRxEnable, BOOL xTxEnable )
    - U( N6 O  X$ k; `; I& q
  36. {$ y& Y: \5 N0 M/ n8 M
  37.     /* If xRXEnable enable serial receive interrupts. If xTxENable enable
    # C- E9 t* v2 c, r/ n
  38.      * transmitter empty interrupts.  }: s. G% a, i% m" W% f5 j( ?
  39.      */' m# A% C; w7 F, m1 z" N2 R9 |: Q
  40.         if(xRxEnable == TRUE); \6 D. E6 J+ V7 u; l/ Z
  41.         {
    3 I+ d) y% F9 S+ ^# A
  42.                 USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);( F/ b% v1 g' k6 I! d3 `' t
  43.         }* w7 D! c& z) s* M
  44.         else
    ; f/ e* ~$ t1 }- R1 E* n
  45.         {
    % G* s6 u: {# P  k" ^, ^& X0 V
  46.                 USART_ITConfig(USART2, USART_IT_RXNE, DISABLE);
    8 w9 {9 }# H  a- v( M! M0 m2 U
  47.         }- |7 e( U5 Y" _1 q1 n$ C
  48.           g' B( a2 v9 A% _; `3 C" c
  49.         if(xTxEnable == TRUE)
    % R$ J* u" G& B$ t% l) ^) g
  50.         {: D# g. y, w! z, i5 B  A
  51.                 USART_ITConfig(USART2, USART_IT_TC, ENABLE);2 A) I) K% r9 m5 k. D! c- A
  52.         }
    # Z% {' _( i1 M# b# \% R! z
  53.         else' y% x  q. Q3 _# j9 f
  54.         {
    + A$ L9 X  Y: M% e, t7 E
  55.                 USART_ITConfig(USART2, USART_IT_TC, DISABLE);
    9 g4 V- g1 G- Q  V) j
  56.         }
    * v5 B$ \8 q* h  a3 s; H
  57. }
    # m1 f( L$ T$ M( q7 J, U% [  e
  58. , K+ h1 E* i; N* j
  59. BOOL/ p7 s! @- |* l* j, J0 A9 j$ o
  60. xMBPortSerialInit( UCHAR ucPORT, ULONG ulBaudRate, UCHAR ucDataBits, eMBParity eParity )( P; t4 E  n. M1 ]' l; ]$ G
  61. {
      t# p- C: Z3 U9 P) A' X& |
  62.         modbus_uart_init((uint16_t)ulBaudRate);  
    - D/ ^- C  E) a! s6 I& i. e
  63. 9 F8 Q. _3 l) k2 J) t4 r1 i: U3 `
  64.         return TRUE;- f% [. E; q. C- X3 m( Q7 X$ U/ E
  65. }
    / O* C0 |5 N/ Q

  66. / Z5 C/ B  K1 J8 E" O: L& n
  67. BOOL8 U, M* |2 e0 D# A8 X7 a- i: H( q
  68. xMBPortSerialPutByte( CHAR ucByte )
    % g7 r5 N* ~9 \1 @1 g9 Y0 `6 v
  69. {
    8 d, J5 b2 G! j1 I0 V
  70.     /* Put a byte in the UARTs transmit buffer. This function is called
    7 b0 K. u+ j) _* P" A! A. L2 M
  71.      * by the protocol stack if pxMBFrameCBTransmitterEmpty( ) has been
    3 O( l- d- v/ Z3 H) C0 D4 ^
  72.      * called. */& y  U9 ~  `/ O: U: i
  73.         2 S0 R* l1 f2 W
  74.         USART_SendData(USART2, ucByte);! ], F9 \& a8 \
  75.     return TRUE;% c/ j# T- A0 c( I* ^) C: ^: H
  76. }1 U! L+ r2 z# E' a* N+ y
  77. ! b" l. p/ j! M+ u6 M
  78. BOOL+ G4 [% x% n7 x  u
  79. xMBPortSerialGetByte( CHAR * pucByte )4 E# Q6 l; ]) }! M5 X; K" w
  80. {
    - t# V' F& Z, N4 }& B
  81.     /* Return the byte in the UARTs receive buffer. This function is called
    . C4 m0 T0 W$ l  P8 }/ [' Q, I
  82.      * by the protocol stack after pxMBFrameCBByteReceived( ) has been called.  Z7 ?# ?( d0 B! E( }1 l8 n
  83.      */* U4 ]% F0 L1 J, u. f( B5 ^* c3 ]
  84.   *pucByte = USART_ReceiveData(USART2); 4 M" W- m. W3 e* ^# }
  85.         return TRUE;( \( \* i9 ~+ u7 K7 w
  86. }: o+ z+ _* ?( ?

  87. 0 v. E9 Z% l8 d# w" S9 z
  88. /* Create an interrupt handler for the transmit buffer empty interrupt
    0 X& e0 d& \8 d) c' A
  89. * (or an equivalent) for your target processor. This function should then$ p2 v7 P) f1 Z# |+ p# ]
  90. * call pxMBFrameCBTransmitterEmpty( ) which tells the protocol stack that$ F, D! Y. q4 U- f, r7 H0 R5 \
  91. * a new character can be sent. The protocol stack will then call
    ( j5 b, Y; W# L! a" n: c
  92. * xMBPortSerialPutByte( ) to send the character.
    6 ?9 |1 C2 I6 V/ O; y: z' q8 [
  93. */+ J: s3 c' U; M0 Q4 I! O
  94. static void prvvUARTTxReadyISR( void )
    4 H. |) Q. j# |9 i
  95. {/ j) ^, T3 z% [
  96.     pxMBFrameCBTransmitterEmpty(  );) {4 y3 z1 e) t7 ]; k& d$ N
  97. }
    6 Y( \5 I; s5 \# r% L
  98. 9 s6 j1 X% d) T6 B' {) L
  99. /* Create an interrupt handler for the receive interrupt for your target
    8 H# Q; P6 a4 y' ~1 T. H
  100. * processor. This function should then call pxMBFrameCBByteReceived( ). The
    % J$ j, Q4 B* C3 J
  101. * protocol stack will then call xMBPortSerialGetByte( ) to retrieve the1 V1 \7 g: G7 E. E# O; J
  102. * character.
    ) {# O! D+ g# H) ~. B/ b
  103. *// P( s% B0 U4 Y% b
  104. static void prvvUARTRxISR( void )6 ^( Q% V# \6 t) q2 z
  105. {
    # V" e% D4 ?0 h" d' z
  106.     pxMBFrameCBByteReceived(  );
    ; C) A' \; D& h2 i2 c% t- D
  107. }
    ) ]& D. }# J9 ~3 {2 R
  108. 0 `+ q- s3 g) S% j; h  \# _
  109. /**+ g* ?& ~) b5 {& G5 A. k: \
  110.   * @brief  This function handles usart1 Handler.$ u6 P9 f9 Y) m" N  r0 }
  111.   * @param  None
    % X) r- r! w5 m2 v
  112.   * @retval None8 O0 N' N, R+ a. x- e/ H; o. f
  113.   */
    . i' S1 K% d( H4 [. j
  114. void USART2_IRQHandler(void)
    2 C5 t. p8 g5 |9 y1 c
  115. {
    * J3 E% K: @6 ?0 p( D
  116.         //发生接收中断! Z( A& j$ V& z
  117.         if(USART_GetITStatus(USART2, USART_IT_RXNE) == SET)7 i8 Q& h$ ^+ h* g- e
  118.         {& _5 M- ^' g7 w) g
  119.                 prvvUARTRxISR();
    4 x, B: d, B% x( G9 J
  120.                 //清除中断标志位   
    0 v1 H- S/ M) t) f6 P' _, y  ^
  121.                 USART_ClearITPendingBit(USART2, USART_IT_RXNE);   
    * M" U% ^; ^8 t1 ~  D
  122.         }$ l' c: \2 U* b* K7 {# T4 m# Y

  123. 7 q, A6 ~  T, u  i2 e
  124.         if(USART_GetITStatus(USART2, USART_IT_ORE) == SET): w, C5 X2 V. L; B
  125.         {  
    5 z+ G$ g, Q7 n7 W, _
  126.                 USART_ClearITPendingBit(USART2, USART_IT_ORE);; v4 S' o% E1 o4 b8 U7 g
  127.                 prvvUARTRxISR();         
    $ f0 C' R3 J0 O
  128.         }
    2 j6 _! b% c" \8 [

  129. . Y9 \6 }  h& q, ?
  130.         //发生完成中断4 g" G. i: V. Y: K% N5 {
  131.         if(USART_GetITStatus(USART2, USART_IT_TC) == SET)3 }; G7 c$ \: ~! W8 L& }3 F/ Q
  132.         {
    8 g; I! b) Y" }
  133.                 prvvUARTTxReadyISR();8 `; E2 w. ~, y' W& T
  134.                 //清除中断标志( e; e) R1 r+ W4 v7 T! y' J* i) U
  135.                 USART_ClearITPendingBit(USART2, USART_IT_TC);$ k8 Y* K. s; W+ X! S
  136.         }
    " T9 P/ V/ I/ ]3 E6 g) c( ~
  137. }1 ?' @! k6 L) \9 j) E3 h9 ^
复制代码
9 ~8 k9 N; f) {  Z2 d
porttimer.c* }  X: B+ b! X: P. _
% K- \5 H6 A' d& [& t$ ~; R: z
  1. 4 P1 W2 G9 z- L! U+ P7 V8 m. b) G
  2. ```c
    2 d/ O* N/ {1 ]2 L6 K- F) B; [% j
  3. /*
    6 K: Q* R$ X- n6 t) {2 E
  4. * FreeModbus Libary: BARE Port
    % @2 }0 [/ w' ?- I7 [
  5. * Copyright (C) 2006 Christian Walter <<a href="mailto:wolti@sil.at">wolti@sil.at</a>>
    3 r& X$ m: T8 S9 |1 w$ W
  6. *
    2 S, `5 |) I; u4 C
  7. * This library is free software; you can redistribute it and/or+ \9 z, i' [2 z; F
  8. * modify it under the terms of the GNU Lesser General Public- x* e: I" V( \- _8 t4 m
  9. * License as published by the Free Software Foundation; either+ _/ m8 G" h- h. [& n  w1 ]
  10. * version 2.1 of the License, or (at your option) any later version.7 e2 _9 F1 g( u6 }3 n: E5 ]
  11. *
    ! E/ c, }" E! O7 o0 E# X
  12. * This library is distributed in the hope that it will be useful,6 C) }- L' x2 P/ @. w8 ^
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of& u$ z1 _" W: J9 D& t! o# A/ ^
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    1 {6 Z* a; j8 `0 a4 O
  15. * Lesser General Public License for more details.
    % q) Z9 r* q' W6 [! a! q$ P) ?
  16. *
    9 r+ h5 K% n8 a1 _/ \( \* D6 u
  17. * You should have received a copy of the GNU Lesser General Public9 X/ F% X$ Z2 o, U
  18. * License along with this library; if not, write to the Free Software$ Z, d0 _% G- T, Y5 |* t
  19. * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
    * f# y) b4 B9 O& v, u$ g
  20. *! S. u* y% Z( e) i
  21. * File: $Id: porttimer.c,v 1.1 2006/08/22 21:35:13 wolti Exp $/ |, M! c! T4 N% b5 i
  22. */: t! t) v% u7 E/ `8 P& p
  23. $ D. y* N4 N: {
  24. /* ----------------------- Platform includes --------------------------------*/
    * D% z/ X; ]! Z! m8 L( J# B, f$ b
  25. #include "port.h"
    + i' J: ]0 F1 L; r- O2 X
  26. #include "modbus.h"
    * o' X9 z2 Q/ d' C  Z
  27. /* ----------------------- Modbus includes ----------------------------------*/+ K9 A% a: M0 l! I2 W, u" g
  28. #include "mb.h"
    . A+ V: v  E: D$ G/ f5 x
  29. #include "mbport.h"
    ( k5 c! s6 j( _: }# m* E

  30. 6 D) t- }/ ]) Z4 A7 n9 n
  31. /* ----------------------- static functions ---------------------------------*/
    . Q2 s- ^" W. _+ n
  32. static void prvvTIMERExpiredISR( void );2 r/ n% Q" m$ c

  33. ; W5 [- ?5 T9 j% z, u* l
  34. /* ----------------------- Start implementation -----------------------------*/. P' _: b% V5 ~9 Z( _& J
  35. BOOL- m0 q# D+ E9 b3 d) }
  36. xMBPortTimersInit( USHORT usTim1Timerout50us )2 m! K4 I6 J3 O  f" u# T* c$ J
  37. {
    4 Q$ c" L9 I0 z  i4 h; P: k9 T9 W
  38.         modbus_timer_init(usTim1Timerout50us);
    " f1 B1 W6 A- f: d( d. h9 O7 x

  39. ; L* d  w9 v* x$ {0 A$ ]8 o9 i* i/ i
  40.         return TRUE;9 |- g4 D. o5 b8 k. R  S
  41. }- ~8 W. i+ i0 ?3 X' L0 V! i
  42. 0 i5 C2 S6 ?) [3 c6 f0 y; b% M! x

  43. 9 v( _3 i: x: D) N2 r% X/ M5 }
  44. void' z6 M& N% F: x2 [5 U% r# c! |
  45. vMBPortTimersEnable(  )% U/ J5 B/ R; o' \- T
  46. {
    ' v: K+ w2 B$ V( L
  47.     /* Enable the timer with the timeout passed to xMBPortTimersInit( ) */& _% u, D& C, l5 o
  48.         TIM_ClearITPendingBit(TIM3, TIM_IT_Update);
    5 I! O' h# j" D8 f
  49.         TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE);* z: d6 @3 q" f: ^* n  S9 H5 O
  50.         TIM_SetCounter(TIM3,0x0000); ' h' {6 a$ d- D
  51.         TIM_Cmd(TIM3, ENABLE);
    ' @& k: K4 k# R
  52. }5 f# r! U( q9 ], `

  53. 6 y& U* L2 o' j: c9 n( w
  54. void% t/ w% W+ ^( d4 s8 x4 J) v' s
  55. vMBPortTimersDisable(  )
    ( X/ d) I4 ^  v/ r8 p
  56. {
    / V! n3 S8 q. {, l; R6 ~, Q
  57.     /* Disable any pending timers. */! ?7 [& U* V$ r$ g: ~
  58.   TIM_ClearITPendingBit(TIM3, TIM_IT_Update);
    + Y0 W# q! Q9 _
  59.   TIM_ITConfig(TIM3, TIM_IT_Update, DISABLE);7 |& k- M1 k2 B1 f
  60.   TIM_SetCounter(TIM3,0x0000); $ I; j. g: s  R6 q2 |2 Z/ f; X" t
  61.   TIM_Cmd(TIM3, DISABLE);( j8 w' `8 Y# G. v
  62. }
    2 \* j* ?9 Q1 S# Y7 p

  63. & f' L# G% d! n! c- ]) W
  64. /* Create an ISR which is called whenever the timer has expired. This function
    + n* {2 |, @7 r1 H, @
  65. * must then call pxMBPortCBTimerExpired( ) to notify the protocol stack that
    4 N+ e/ x. L' k- y) E1 ?
  66. * the timer has expired.
    ' O, p& U5 m+ w0 C+ {3 h" n% l
  67. */
    . ?' Z2 e, {, S6 S
  68. static void prvvTIMERExpiredISR( void )
    ; [$ Q8 ?+ Z* f- ~
  69. {0 l' s: c- S5 U& y0 v7 [( O) F
  70.     ( void )pxMBPortCBTimerExpired(  );
    # x: O, b# S" t& O+ ?
  71. }
    # ]- ^( N3 [% \# Y
  72. 2 i! d5 c+ @5 M& a2 M# y
  73. void TIM3_IRQHandler(void)
    - I- S+ s/ c. |) B! `6 A  s
  74. {
    ' d& n" s0 k8 Y+ R1 m
  75.         if(TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET)
    ) U; R% z* f; a; @5 D$ L
  76.         {
    ' Y3 Q4 B- g" V  a$ y1 A8 Y. g/ H6 j/ @
  77.                 prvvTIMERExpiredISR();* s9 e) r- o/ R
  78.                 TIM_ClearITPendingBit(TIM3, TIM_IT_Update);
      a7 T* f  V6 F* @: i
  79.         }' E# w" O' G! |. u
  80. }
复制代码

% c5 e1 v/ `# _! C$ c8 t5 z然后主函数中调用
# }$ F/ i6 X, L$ L9 B2 h4 S* u) Q  y: v9 r/ \, {
  1. ' n  l% x+ E2 a7 x  r
  2. int main(void)+ t8 {7 `% s/ F8 x1 G
  3. {               
    % m$ A% d$ }* ~8 I* A
  4.         delay_init();                     //延时函数初始化          3 q# @1 O! T+ w1 d
  5.         NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
    9 c( c8 S/ ~) D
  6.         uart_init(115200);5 [8 W+ n( D8 P8 {8 l
  7.         eMBInit(MB_RTU, 0x01, 0x01, 9600, MB_PAR_NONE);
    / H, @$ o. ]" m) m4 [7 a
  8.         eMBEnable();  0 [+ e; q: a  B# r( @% [
  9.          while(1)- t) ?2 M( C& u, z9 R
  10.         {
    6 F4 v5 k/ C& H+ I$ b
  11.                 (void)eMBPoll();1 x3 V! E1 f5 H9 Z, s- w" O
  12.                 delay_ms(5);5 D8 _% l; c+ q( T- U9 [+ B, A
  13.                 " [. G# L" v6 h8 S: J. c
  14.         }         6 m* B8 J6 R) F. s4 h3 A; Q
  15. }
复制代码

8 \* g& \2 h; ?, ~其次还要实现读线圈、写线圈、读离散输入、写保持寄存器、读保持寄存器、读输入寄存器等功能,如下:9 J, t: x7 ~  K' v7 c
3 P% p# J9 E8 C6 [! r6 r8 E6 ^
  1. #define REG_INPUT_START       0x0001        //输入寄存器起始地址
    3 T5 q8 k$ B3 d. j8 D
  2. #define REG_INPUT_NREGS       8                        //输入寄存器数量) [, j  T+ K/ T) M

  3. 3 S7 F1 U- T2 s2 }4 X4 J
  4. #define REG_HOLDING_START     0x0001        //保持寄存器起始地址: _+ U; K0 z6 L5 [
  5. #define REG_HOLDING_NREGS     8                        //保持寄存器数量
    / H( C' u: |' u" R1 p* z1 r

  6. + W! W$ Q# A! M1 f
  7. #define REG_COILS_START       0x0001        //线圈起始地址8 O5 \' f- r& @( y5 C0 D7 C
  8. #define REG_COILS_SIZE        16                        //线圈数量+ [5 a+ A) R& [; r; ]; s

  9. 4 ]5 L" [* N: S
  10. #define REG_DISCRETE_START    0x0001        //开关寄存器其实地址; |& u" y2 q2 o, ?: y5 x$ O* u
  11. #define REG_DISCRETE_SIZE     16                        //开关寄存器数量( G' F9 b% q' b9 h/ v, o
  12. //输入寄存器内容2 e, I9 k$ R. G7 C) z1 r2 ?
  13. uint16_t usRegInputBuf[REG_INPUT_NREGS] = {0x1000,0x1001,0x1002,0x1003,0x1004,0x1005,0x1006,0x1007};& ?  I; b' |0 a/ u! ]( _
  14. //保持寄存器内容                  I- }! j3 ^- q  t; W
  15. uint16_t usRegHoldingBuf[REG_HOLDING_NREGS] = {0x2000,0x2001,0x2002,0x2003,0x2004,0x2005,0x2006,0x2007};                                       
    : ?* r  x. W/ I; ^3 b! D5 R
  16. //线圈状态3 {% r; q/ D3 ^4 u! [& I( \( M/ z
  17. uint8_t ucRegCoilsBuf[REG_COILS_SIZE] = {0x01,0x01,0x00,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00};
    6 S" D; h& \9 h/ ^' b# l' C2 W* h8 i
  18. //离散寄存器内容
    " \1 @& M( \7 w  T5 c
  19. uint8_t ucRegDiscreteBuf[REG_DISCRETE_SIZE] = {0x01,0x01,0x00,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x01}; 0 M6 t2 D7 s7 |6 g$ f* v

  20. ; [$ w: O0 n0 k* ~$ R% o& [7 l
  21. /****************************************************************************
    ; D! p0 k$ b) n/ k( s$ j" Y& L4 Z) H. d
  22. * 名          称:eMBRegInputCB + L" O; ?. v3 h8 E0 P
  23. * 功    能:读取输入寄存器,对应功能码是 04 eMBFuncReadInputRegister2 I7 d$ w4 q- X
  24. * 入口参数:pucRegBuffer: 数据缓存区,用于响应主机   
    6 p% f: d8 W6 y8 @
  25. *                                                usAddress: 寄存器地址
    0 q+ n9 _. A: S) [
  26. *                                                usNRegs: 要读取的寄存器个数
    $ U3 W( n- Z' C0 G7 |. C
  27. * 出口参数:
    * q+ t; X4 D4 C
  28. * 注          意:上位机发来的 帧格式是: SlaveAddr(1 Byte)+FuncCode(1 Byte)
    $ Z8 g6 L1 S* P6 U: N
  29. *                                                                +StartAddrHiByte(1 Byte)+StartAddrLoByte(1 Byte)% l3 e4 q. I& f+ h: E
  30. *                                                                +LenAddrHiByte(1 Byte)+LenAddrLoByte(1 Byte)+
    " `7 L3 u1 o- x4 C
  31. *                                                                +CRCAddrHiByte(1 Byte)+CRCAddrLoByte(1 Byte)
    0 A2 p. C, P& M9 Q$ e
  32. *                                                        3 区
      n2 P% f9 b$ M# m1 V/ P
  33. ****************************************************************************/( s' [1 u5 B! h: x+ b1 b1 f" h
  34. eMBErrorCode
    6 ?8 e3 ?$ ?- `8 F9 G2 Z
  35. eMBRegInputCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNRegs )
      C) p7 Z2 g$ p- t: z
  36. {; D# L3 y; x+ ?% F7 l8 v
  37.     eMBErrorCode    eStatus = MB_ENOERR;, m' |: {$ a/ K" U* K- W2 o1 J
  38.     int             iRegIndex;
    - n, A$ V5 z( ^; M  Q

  39. 1 h$ d7 U- \1 w6 `9 ]( Q3 T9 B
  40.     if( ( usAddress >= REG_INPUT_START )1 F( a) ?) z' @: R
  41.         && ( usAddress + usNRegs <= REG_INPUT_START + REG_INPUT_NREGS ) ). e0 c: I2 h- I4 `+ [
  42.     {
    - @5 @3 n/ c/ `& s6 `! Q  a; w% s
  43.         iRegIndex = ( int )( usAddress - REG_INPUT_START );0 `0 d  Y9 W! H7 t- Y  ~
  44.         while( usNRegs > 0 )# `5 u: y" V& I" z
  45.         {" Q( R6 V- ?  ~' T
  46.             *pucRegBuffer++ = ( UCHAR )( usRegInputBuf[iRegIndex] >> 8 );
    5 j9 E) {- R0 L) Y: h+ m
  47.             *pucRegBuffer++ = ( UCHAR )( usRegInputBuf[iRegIndex] & 0xFF );
    3 E6 Z* B; U4 x8 ~6 P
  48.             iRegIndex++;
    : }. k1 m: X, z. ?, G9 Y( z
  49.             usNRegs--;6 O7 P2 I0 b9 R6 A8 i$ x
  50.         }. _5 S' @+ _  }; F! Q9 e
  51.     }
    8 K; ^$ {' f; v
  52.     else
    ) ]) u  S0 n7 H) `. Z- ?
  53.     {
    ; }: L5 b8 [7 c6 o2 A+ o
  54.         eStatus = MB_ENOREG;3 w9 k  x0 I0 W0 g  s! E
  55.     }
      \* K2 l" g. U3 E/ l
  56. 9 x7 G% h# E* f
  57.     return eStatus;
    ) e+ h& H7 K2 S( R* |! P
  58. }3 D: `8 P5 G, F4 P1 t
  59. 9 v, x" P' {/ ], i. h0 A5 A3 \$ V
  60. /****************************************************************************
    0 s7 ?: M6 N. C; Q
  61. * 名          称:eMBRegHoldingCB 1 X/ C( Y% D8 V5 |/ u$ M8 S. s/ S2 H
  62. * 功    能:对应功能码有:06 写保持寄存器 eMBFuncWriteHoldingRegister
    / Q" _( w. O/ U
  63. *                                                                                                        16 写多个保持寄存器 eMBFuncWriteMultipleHoldingRegister% d3 k+ j0 i' Z
  64. *                                                                                                        03 读保持寄存器 eMBFuncReadHoldingRegister
    3 A  y" y1 [: Y1 b
  65. *                                                                                                        23 读写多个保持寄存器 eMBFuncReadWriteMultipleHoldingRegister
    2 |0 g2 ~9 ]5 n& |% l, [
  66. * 入口参数:pucRegBuffer: 数据缓存区,用于响应主机   . ~/ X  [  k, b
  67. *                                                usAddress: 寄存器地址. D# q3 J7 r! o
  68. *                                                usNRegs: 要读写的寄存器个数
    5 ]/ r5 K0 W6 o1 @* ^
  69. *                                                eMode: 功能码( H& T* L4 g: \$ _# G* g0 l
  70. * 出口参数:( R/ Z+ H' e! j' d9 z6 y/ W5 y* B
  71. * 注          意:4 区
    7 F9 ^2 s) |$ _, |! I9 S" D
  72. ****************************************************************************/+ k+ e, R6 W+ p5 d, S
  73. eMBErrorCode
    6 [& @2 S0 n, ^2 f8 W
  74. eMBRegHoldingCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNRegs, eMBRegisterMode eMode )) x* f6 O) x& I# I2 M0 n$ U
  75. {
    8 W/ B9 M! j# @9 ~9 J7 X0 z; U
  76.         eMBErrorCode    eStatus = MB_ENOERR;
    $ Y1 C% F2 g) h3 A# F, q" {+ y  N
  77.         int             iRegIndex;, C( ~# u/ c* X1 Q7 I2 a5 ?! s

  78. ; p$ r1 s, I# _8 L2 Z
  79. 5 P! ]/ z& T+ U, H4 {: J
  80.         if((usAddress >= REG_HOLDING_START)&&\
    # A" ~* l" ~" Z& @7 T* j
  81.                 ((usAddress+usNRegs) <= (REG_HOLDING_START + REG_HOLDING_NREGS))). G8 j! [6 E5 X
  82.         {
    ! O. Z2 r0 h4 V% O) H
  83.                 iRegIndex = (int)(usAddress - REG_HOLDING_START);6 ~5 N2 f. S# i. ?5 j& V
  84.                 switch(eMode)
    6 A6 ^" T. {; J6 P) @
  85.                 {                                       
    3 f/ ~1 E- x7 q& H9 y6 t3 u: }
  86.                         case MB_REG_READ://读 MB_REG_READ = 0
    # L' p+ x& V8 f& Z, O0 c
  87.                                 while(usNRegs > 0). j3 b+ P( k% ?0 x
  88.                                 {
    / h  @: P$ b$ K6 h2 F
  89.                                         *pucRegBuffer++ = (u8)(usRegHoldingBuf[iRegIndex] >> 8);            
    " L" K  u; W& B" F* A0 o
  90.                                         *pucRegBuffer++ = (u8)(usRegHoldingBuf[iRegIndex] & 0xFF); 6 j- W( {  |, l! d# A$ ~
  91.                                         iRegIndex++;2 J3 X+ d4 a- l& a. L; e2 E
  92.                                         usNRegs--;                                       
    9 _; y& D) }/ f6 k/ }9 Z/ \
  93.                                 }                            7 H- T4 x* }: C& x. s
  94.                         break;& D0 A! ?% A% u, B2 e
  95.                         case MB_REG_WRITE://写 MB_REG_WRITE = 0
    ) n0 o+ C2 k8 I. D( w8 W' J0 O
  96.                                 while(usNRegs > 0)
    5 S6 h. r# v3 H& V. U* w  n
  97.                                 {         
    6 V2 z" p) O) m& G
  98.                                         usRegHoldingBuf[iRegIndex] = *pucRegBuffer++ << 8;
    % F! ~" Q  q( b. j
  99.                                         usRegHoldingBuf[iRegIndex] |= *pucRegBuffer++;
    4 q* o2 ~/ Z8 l/ N0 v$ |1 \$ ^4 m
  100.                                         iRegIndex++;
    ) \8 B3 Q% A- C
  101.                                         usNRegs--;
    8 R& t9 \% ]7 O% d* s8 ], W
  102.                                 }5 ^; ?9 \& m4 F" j
  103.                         break;                                
    4 F' j5 m; l1 M* b. e
  104.                 }
    2 \; ]# R! q! i) Y8 f
  105.         }5 F1 k  b3 f7 l# @* a) G; h
  106.         else//错误
    - N$ ~8 L5 E1 E" V! i) C
  107.         {
    ( m8 l6 ?& b% m3 Q0 \
  108.                 eStatus = MB_ENOREG;
    $ p+ N6 K3 e# n. v) r: A
  109.         }        
    ' C$ x7 b  g+ d( y1 s
  110.         ' f" ~; F1 q. d- _# p0 ]7 m, _; r
  111.         return eStatus;4 z. _& u5 i2 K9 |# d( s  N
  112. }$ u1 j8 S9 w1 e/ y7 \9 G- I* J

  113. ) K. a4 ^6 M. T: M% ~
  114. /****************************************************************************% i( _1 l' f& f' c
  115. * 名          称:eMBRegCoilsCB
    5 _; y- D3 {5 {$ o7 t% Q& ]/ k
  116. * 功    能:对应功能码有:01 读线圈 eMBFuncReadCoils/ ~: Q* S7 [" \, C5 Q3 ~
  117. *                                                  05 写线圈 eMBFuncWriteCoil
    5 t8 z7 P- |. a' j% a0 k) ?
  118. *                                                  15 写多个线圈 eMBFuncWriteMultipleCoils* Y* y5 W) I7 f2 L
  119. * 入口参数:pucRegBuffer: 数据缓存区,用于响应主机   ) z6 x3 w$ L$ t0 d* I
  120. *                                                usAddress: 线圈地址( s# d$ R$ j, r+ g3 {9 `, V4 n) J' ^
  121. *                                                usNCoils: 要读写的线圈个数
    - O- n" z/ x" P& @# S
  122. *                                                eMode: 功能码! x( k' K$ W. h9 i4 O6 H  \
  123. * 出口参数:
    0 t, [5 H2 T' z/ x$ K; _9 N7 z
  124. * 注          意:如继电器
    0 R. }$ B7 ?, _7 ?# p
  125. *                                                0 区
    $ J" G9 s0 P& m& x' {
  126. ****************************************************************************/% c" o) b5 R6 ~
  127. eMBErrorCode& u2 `4 G$ C* h" q
  128. eMBRegCoilsCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNCoils, eMBRegisterMode eMode )
    # u% S3 {" ?  G
  129. {
    7 k/ v9 @; a$ u* w) h. |
  130.         eMBErrorCode    eStatus = MB_ENOERR;2 Z* h3 K, y7 Y6 P# C" L. t8 v
  131.         int             iRegIndex;
    , w! D, H+ n$ ~2 o0 F) i, m
  132.         u8 i;$ ?: F0 k7 `/ ?7 l/ T; t$ L
  133.         USHORT readNumber=usNCoils;
    4 Y4 }3 n# S4 d: q6 o  t' u+ \
  134.         USHORT coilValue=0x0000;: s2 h$ |& M$ U8 X
  135.         if((usAddress >= REG_COILS_START)&&\. R6 e* H3 O3 f6 _) L! c
  136.         ((usAddress+usNCoils) <= (REG_COILS_START + REG_COILS_SIZE)))
    6 M! n8 T, k0 n0 S
  137.         {
    2 g; [8 `7 v2 U8 ]$ d
  138.                 iRegIndex = (int)(usAddress + usNCoils-REG_COILS_START);3 j; O* ]. J: a3 h; A+ D
  139.                 switch(eMode)
    0 }9 P7 [8 t4 L
  140.                 {                                       $ J6 R: W6 U4 J0 M
  141.                         case MB_REG_READ://读 MB_REG_READ = 0) S; V5 u/ h/ m  J# T# B
  142.                                 for(i=0;i<usNCoils;i++)! U% `, [/ F' d( y2 R7 A
  143.                                 {8 q+ }& e) `/ u$ t
  144.                                         readNumber--;$ V9 X4 p0 j. @8 y* b( Y
  145.                                         iRegIndex--;
    - k  Y& t0 H+ D% F) `
  146.                                         coilValue|=ucRegCoilsBuf[iRegIndex]<<readNumber;
    2 w+ B9 N- d- |) e2 v7 q5 X
  147.                                 }
    : E" ~. r6 }5 f7 K) H: T3 H" _/ T
  148.                                 if(usNCoils<=8)
    7 v$ i3 x" q+ `7 i" z( U" Q
  149.                                 {* }6 r7 l% _/ g) N- g2 T6 B, Z
  150.                                         * pucRegBuffer=coilValue;
    / O; X7 w  b$ ]* `# |* |
  151.                                 }7 b; {& ^% m% L. C2 g6 y7 S
  152.                                 else
    ; R# J. F# G& ~) u+ X
  153.                                 {
    2 B+ J7 |0 q4 T' [6 n; l+ M* t1 [
  154.                                         * pucRegBuffer++ = (coilValue)&0x00ff;5 j0 Q* x9 e0 j/ [
  155.                                         * pucRegBuffer++ = (coilValue>>8)&0x00ff;
    4 P2 H& T7 Y; l+ g8 _9 X& c4 c
  156.                                 }
    1 P6 {; t2 c. D! U8 H
  157.                         break;                           
    , ^! }- M( E# s4 }- q9 A
  158.                         case MB_REG_WRITE://写 MB_REG_WRITE = 14 Y1 ^- H( S+ z6 g6 U
  159.                                 while(usNCoils > 0)8 z) J0 s$ Y* j: M! z
  160.                                 {         
    8 J/ Y* W7 z. c9 z: j( O
  161.                                         //                         usRegHoldingBuf[iRegIndex] = *pucRegBuffer++ << 8;% p) n2 ]" ^% l1 O! d
  162.                                         //           usRegHoldingBuf[iRegIndex] |= *pucRegBuffer++;
    0 `+ |! E4 y- q! a0 F  R
  163.                                                 iRegIndex++;
    : y- S2 _' N6 B7 K+ d
  164.                                                 usNCoils--;% Z7 @" Y% U2 w+ u# J8 v
  165.                                 }
    3 ~, ~- ^: L# `( v0 ^
  166.                         break;1 Q' R8 Y2 I7 E  M$ ^& Q! ~8 N
  167.                 }
    : R& V/ E% z5 T# L$ F
  168.         }
    + e! p4 t: i  P: }
  169.         else//错误
    " S# _  M/ T% h% `+ r1 p
  170.         {0 s9 F7 @, F" j1 M" l. n
  171.                 eStatus = MB_ENOREG;2 Z8 O0 d% `) K/ |( u
  172.         }          s  o8 p; |- r* V9 o
  173. 0 ~5 \; o! L, H0 G- q' M
  174.         return eStatus;
    1 B" J! ]0 h5 V
  175. }" k7 b3 k$ R0 r# e3 o
  176. /****************************************************************************6 ~) T. P4 f/ B% H
  177. * 名          称:eMBRegDiscreteCB # B1 |9 V/ F7 z8 b
  178. * 功    能:读取离散寄存器,对应功能码有:02 读离散寄存器 eMBFuncReadDiscreteInputs
    : I: N6 z6 R) d
  179. * 入口参数:pucRegBuffer: 数据缓存区,用于响应主机   
      R6 Q% Z2 k! c( w( y6 v( ~
  180. *                                                usAddress: 寄存器地址+ F+ v3 q0 P! n7 K
  181. *                                                usNDiscrete: 要读取的寄存器个数1 O+ o  O' N3 P5 ?2 H
  182. * 出口参数:
    ) O/ A9 ]. c1 w1 O" c9 g
  183. * 注          意:1 区
    - N) g; p7 E% o# l3 Y
  184. ****************************************************************************/
    " s* ]! t2 [! y% e
  185. eMBErrorCode) y" |5 l) M& t9 R1 u, b
  186. eMBRegDiscreteCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNDiscrete )9 {* Y7 u) a" |& l# a3 I+ \
  187. {
    8 R  k- G0 U3 k; G6 r+ b
  188.         eMBErrorCode    eStatus = MB_ENOERR;
    / t7 X1 ~9 m( v7 n
  189.         int             iRegIndex;
    , [, }* R5 M  j: p8 ?$ I) r' b
  190.         u8 i;
    # m7 [3 s8 P' q
  191.         USHORT readNumber=usNDiscrete;
    3 O) j& _5 g5 M/ Q" P- E$ _2 j
  192.         USHORT coilValue=0x0000;1 \& B# |8 F( {. I$ Q
  193.         iRegIndex = (int)(usAddress + usNDiscrete-REG_DISCRETE_START);* Q  [2 m7 Q& M3 z" @
  194.         if((usAddress >= REG_DISCRETE_START)&&\0 P- [6 a8 c  o$ M8 n: l9 @
  195.         ((usAddress+usNDiscrete) <= (REG_DISCRETE_START + REG_DISCRETE_SIZE))), M, X  V0 h! [: e) Y  J7 R/ O4 t" i
  196.         {
    # c9 L5 U! Y* h! _; ?4 ~/ o: @
  197.                 for(i=0;i<usNDiscrete;i++)+ w3 b5 C5 |0 x
  198.                 {1 I* ]8 t( Z, S" B+ i* p
  199.                         readNumber--;# f0 g' R& G5 o2 X4 D6 `
  200.                         iRegIndex--;
      Z5 E2 I0 r6 L% ^
  201.                         coilValue|=ucRegDiscreteBuf[iRegIndex]<<readNumber;4 S0 Z8 B$ N: B! p8 O
  202.                 }
    & B0 g) `3 J5 g) s9 r
  203.                 if(usNDiscrete<=8)
    ; f/ ]/ c$ K1 x
  204.                 {7 |# F" ?( W+ \% |: a
  205.                         * pucRegBuffer=coilValue;
    : z% s7 M4 m, H( N
  206.                 }) M4 i9 _8 i  K8 N  t" V+ ~
  207.                 else' c$ P" T% s, J. C/ C% L+ `
  208.                 {  g: `4 E5 ?) ?; n7 p3 d* K
  209.                         * pucRegBuffer++ = (coilValue)&0x00ff;
    ' M( f, ^3 t1 W' e
  210.                         * pucRegBuffer++ = (coilValue>>8)&0x00ff;
    ( ?# O: ~, |5 [  j  O' [
  211.                 }
    # _* V# S7 n3 ~  g! {! S) M
  212.         }0 b0 m( |0 n/ c, N5 L
  213.         else$ {/ A+ l8 ?8 _; j) D
  214.         {8 l7 a$ F3 l+ y3 Y* G
  215.                 eStatus = MB_ENOREG;$ w0 Y9 T: d7 q
  216.         }7 @6 A+ [/ N7 n
  217.     return eStatus;
    & P! a1 R; @, ^: f) F
  218. }
      L  {9 H4 S# W% r

  219. / B) ^2 N! c, c5 e: w
  220. 8 y. L/ J5 C- s8 {! g

  221. 1 i* v, ~" j$ U9 c' ?

  222. 4 m( f% I. G, P' W" l+ D! a
复制代码

0 G7 f- w+ m6 W5 ^% F% ]8 l- z. r: i3 n, q

( x- N% S( \4 l* a" x. L
收藏 评论0 发布时间:2022-4-23 15:41

举报

0个回答

所属标签

相似分享

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版