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

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

[复制链接]
STMCU小助手 发布时间:2022-4-23 15:41
首先将FreeModbus移植到自己工程中,如下图所示:" u; s% e  W4 |* k+ p( u* _
20200323104757628.png
1 y' w9 A, I: Y* k1 k. S4 |. L: W  S/ v7 |( m: [2 I8 u2 e' D
然后修改portserial.c和porttimer.c文件:. Q! |7 u- x2 I: |
portserial.c
; {% e# f3 b% a7 |* O( \" [# E! j9 d9 Q8 x
  1. /*
    # W2 p* C; K# m& P4 t
  2. * FreeModbus Libary: BARE Port7 g) D$ \  ^* w$ s/ h
  3. * Copyright (C) 2006 Christian Walter ' j6 ]2 I: i0 u" n2 I
  4. *
    + [  u" Y9 s/ u5 W: W/ B" Y: ~5 g* p' Y+ k
  5. * This library is free software; you can redistribute it and/or
    1 ~" H$ Q& [. D4 {/ ?  u/ `
  6. * modify it under the terms of the GNU Lesser General Public9 g5 J8 h, T5 \3 ]
  7. * License as published by the Free Software Foundation; either
    1 }( ~8 T3 w+ Q# x
  8. * version 2.1 of the License, or (at your option) any later version./ ~0 F" P+ S. J
  9. *  l6 ^$ O, A0 g+ y( {8 K+ w
  10. * This library is distributed in the hope that it will be useful,0 F3 U! ~& z) e; `  G% g
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of4 J4 t, d0 L/ D! |& j
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    1 b  \6 F, o8 U/ d
  13. * Lesser General Public License for more details.( h/ h  W" i  E8 ]% ~% H- T
  14. *0 @- r% J3 y, a: g. g* Q
  15. * You should have received a copy of the GNU Lesser General Public0 _0 \& M3 O: u& R6 o( @
  16. * License along with this library; if not, write to the Free Software. }1 G; b; Y% w' b( _( s! f
  17. * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA- u( W! z% q' z+ x1 E' y
  18. *1 n1 r( W4 _6 m) r
  19. * File: $Id: portserial.c,v 1.1 2006/08/22 21:35:13 wolti Exp $  t# [+ J) K4 h' B# d3 r
  20. */& u1 K! C' O% }) c+ i

  21. ' v  W8 q/ \) f# e8 G" l& ]3 ^, U
  22. #include "port.h"$ x8 a$ \" u* ~  i  y
  23. #include "stm32f10x.h"
    . Y* C. }, C+ N0 ?. }
  24. #include "modbus.h"
    9 e9 g! a4 H% b8 D$ T) b# J- U" L- o
  25. /* ----------------------- Modbus includes ----------------------------------*/: I( P# ?; X  b: @
  26. #include "mb.h"6 ?+ r( O, }- r
  27. #include "mbport.h"3 k" ?, x: \' _$ m* F6 S1 p
  28. ( b% Q' c- o1 Q
  29. /* ----------------------- static functions ---------------------------------*/1 f3 z4 R- q6 z; L+ T8 @8 ]2 }& l
  30. static void prvvUARTTxReadyISR( void );9 S. \# `8 u# ]  Q4 @- Z
  31. static void prvvUARTRxISR( void );1 z' Q5 `, Y/ e( `- n8 K

  32. - `. o3 U7 I/ ^, K7 l* E
  33. /* ----------------------- Start implementation -----------------------------*/
      _0 I+ @1 p; e- A, j+ B
  34. void
    2 h% n' r* U/ A8 b( `5 U. o+ y
  35. vMBPortSerialEnable( BOOL xRxEnable, BOOL xTxEnable )8 ^# U0 J! @& X. }8 U* D% P: _
  36. {
    + b" J/ X% l( g, z) e
  37.     /* If xRXEnable enable serial receive interrupts. If xTxENable enable
    : s) y4 e. O0 `# j. p* A; X! |, }
  38.      * transmitter empty interrupts.; T- }8 b3 i4 j% c
  39.      */8 ~' R6 O4 e$ u: D- E
  40.         if(xRxEnable == TRUE)& B3 Q: D7 s( u. x5 v
  41.         {
    & W+ J9 K0 q( V- t* N+ x
  42.                 USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);& \2 Q( g1 _5 P  n0 v) C
  43.         }
    . a+ p1 k: @  q
  44.         else5 V1 u) ~9 l* W7 m' B, r- n
  45.         {" ^0 W- b' Y, q& E
  46.                 USART_ITConfig(USART2, USART_IT_RXNE, DISABLE);3 Z8 J& I+ l' l" I, u2 Q' H: @
  47.         }
    . H! P6 `* n. b% i; k! ?
  48.         
    ; G) T! M2 \. {7 S4 |& J
  49.         if(xTxEnable == TRUE)
    8 z& {/ j& r0 s+ I  }. Y
  50.         {" `  }5 t+ g5 H( I  V0 I' o
  51.                 USART_ITConfig(USART2, USART_IT_TC, ENABLE);
    ! y6 R  M6 q3 O
  52.         }& @  D& L. Q( L' g
  53.         else7 }6 B. F2 s5 K9 G7 F6 l* \7 E* T
  54.         {! a6 Y) e- q  V$ r& @
  55.                 USART_ITConfig(USART2, USART_IT_TC, DISABLE);
    + a' U3 |$ t% w7 P  _
  56.         }
    2 U4 }% s0 q9 R1 i
  57. }
    % F$ b; P5 V0 M
  58. * o0 T" j2 l0 ?" A% M
  59. BOOL9 o; u, G4 _% a4 O, Q& V3 ~# D
  60. xMBPortSerialInit( UCHAR ucPORT, ULONG ulBaudRate, UCHAR ucDataBits, eMBParity eParity )% T, x4 H& G2 L6 O
  61. {9 G& q* [' X- L& f0 x: x- [3 X
  62.         modbus_uart_init((uint16_t)ulBaudRate);  4 R/ z' C7 X- L
  63.   V8 g3 L7 c- j2 h! A
  64.         return TRUE;+ o' ~' Y8 H0 E
  65. }' k+ \1 h# s1 }; f4 ]0 W/ U
  66. $ G0 o/ g$ V, l1 l  n* [
  67. BOOL0 T2 V2 v% m9 }) z
  68. xMBPortSerialPutByte( CHAR ucByte )
    & T- m" I' u7 h7 {( ~* V1 M
  69. {
    & I/ w+ o) T4 B$ H
  70.     /* Put a byte in the UARTs transmit buffer. This function is called, O3 }- F* Y% K& X4 N8 l( M& N# I
  71.      * by the protocol stack if pxMBFrameCBTransmitterEmpty( ) has been
    0 N% O, |9 ~  ]4 i8 G) A
  72.      * called. */
    ) X% E5 m. Q1 X7 `
  73.         $ `6 N+ V1 `0 W# h! K9 K
  74.         USART_SendData(USART2, ucByte);
    0 I$ m8 R4 J0 e# u- {
  75.     return TRUE;
    ! `) [/ Y% p. n) }, x
  76. }
    0 L4 ~6 z! r( x& g6 [6 y- l
  77. - m! B' u3 p# s( |+ c
  78. BOOL& x/ _0 c" k! c1 C! j
  79. xMBPortSerialGetByte( CHAR * pucByte )
    - x" M* N! F' b- ?
  80. {
    6 I6 s; w3 J$ w' T4 \
  81.     /* Return the byte in the UARTs receive buffer. This function is called2 _5 l) j- Z- k: M
  82.      * by the protocol stack after pxMBFrameCBByteReceived( ) has been called.
    ; V" ]- ]0 u- `1 s+ g
  83.      */8 D1 a1 `; h% \! w1 p4 p
  84.   *pucByte = USART_ReceiveData(USART2); 0 ^2 b/ e' z8 P) _  o) u
  85.         return TRUE;5 a3 d5 o, K6 f$ w8 \
  86. }; P" f$ V! {1 o
  87. + J* [3 s# m: I' V1 ^
  88. /* Create an interrupt handler for the transmit buffer empty interrupt
    0 A6 K9 R3 S) T1 t0 q
  89. * (or an equivalent) for your target processor. This function should then1 U/ ^, A6 T7 `, G* z5 L
  90. * call pxMBFrameCBTransmitterEmpty( ) which tells the protocol stack that6 a$ G* [0 N# J/ j$ n% E6 \
  91. * a new character can be sent. The protocol stack will then call
    $ t/ J8 g  W8 p
  92. * xMBPortSerialPutByte( ) to send the character.( R2 c- C- M! j1 A
  93. */
    # r0 L& X% u- m- ]1 s/ P5 z& {
  94. static void prvvUARTTxReadyISR( void ); J( s5 w! ]8 p* u- U7 d% `' `. s
  95. {
    ( R( \& \7 I  h$ O. y% n
  96.     pxMBFrameCBTransmitterEmpty(  );
    . Y' F. }( R8 q* R: Q& d1 H
  97. }
    / g$ E1 p  m  V

  98. % c' a! [) e) v+ j0 R
  99. /* Create an interrupt handler for the receive interrupt for your target
    ) n( [& [& B7 D* e7 ?/ Q+ p
  100. * processor. This function should then call pxMBFrameCBByteReceived( ). The
    " B. l3 Z+ v% @! W2 o$ E, h( y
  101. * protocol stack will then call xMBPortSerialGetByte( ) to retrieve the- X; u7 i6 ]' [7 H, i
  102. * character.
      O8 ~9 j+ E( I3 f6 X) I1 _
  103. */
    / H8 B9 X$ O& V  Y3 v! ?# e
  104. static void prvvUARTRxISR( void )! S+ p. ]4 Y: B. G8 S) R( Z& n
  105. {
    4 Q& g: d$ Z9 P1 Q6 |7 H
  106.     pxMBFrameCBByteReceived(  );
    8 t* ?$ S' O* R4 s! M$ f$ H
  107. }
    4 J. _: T$ G( G. c$ F
  108. % Y) X+ D1 @9 y# @% @1 h9 J5 Y
  109. /**
    - k: {6 a6 I, q. T- Z) T* h
  110.   * @brief  This function handles usart1 Handler.* d6 M2 L/ h) Z6 V3 D: z3 c3 I
  111.   * @param  None
    * U8 b$ R4 }' z* i7 [* q! J  v
  112.   * @retval None
    5 i) p9 b' U' @' o% Y- F
  113.   */7 N) ^2 A* G: j& ]% t
  114. void USART2_IRQHandler(void)
    " n; H* l3 T& w  C1 J
  115. {
    9 _. m+ `2 w6 V
  116.         //发生接收中断
    3 Z0 y+ C- e& r, {* d: S
  117.         if(USART_GetITStatus(USART2, USART_IT_RXNE) == SET)8 [# ]! n' @9 q+ [! p% e4 ^1 K( a
  118.         {
    - ^. P+ [4 Y/ t8 N( d# W% U% ^
  119.                 prvvUARTRxISR(); 1 F' ^7 f7 \8 R8 b5 _/ H$ G2 v) f
  120.                 //清除中断标志位   
    5 v6 J- o! a" ~. q2 I0 a
  121.                 USART_ClearITPendingBit(USART2, USART_IT_RXNE);   + P" o( A- t0 ]5 {
  122.         }: n1 ~+ }9 j$ c2 h" p" ^8 A
  123. : K) p: J8 t8 x9 t2 V
  124.         if(USART_GetITStatus(USART2, USART_IT_ORE) == SET)
    , ^7 i* F+ A6 p
  125.         {  
    $ V* F4 J3 [( r& A
  126.                 USART_ClearITPendingBit(USART2, USART_IT_ORE);% g, Z9 G& X: r7 m/ }. {! |
  127.                 prvvUARTRxISR();         
      r% J/ D2 K  ~. v+ Z
  128.         }
    1 g& d/ O  m- L: A  f

  129. 6 d5 Q3 n8 k$ c' {: N! t. x
  130.         //发生完成中断
    * Z4 j& }8 h0 [$ T+ K* S& C- w: a
  131.         if(USART_GetITStatus(USART2, USART_IT_TC) == SET)
    ; E3 c9 |! @/ `2 Y4 [
  132.         {" m/ Q  k& w5 [) y$ ?7 n% W/ d  p
  133.                 prvvUARTTxReadyISR();$ W/ F  k$ ^( g9 W; a% x
  134.                 //清除中断标志# G+ a; p6 E$ C' y
  135.                 USART_ClearITPendingBit(USART2, USART_IT_TC);* \4 }1 T4 O3 x+ b8 L; A0 K
  136.         }& V9 p) y9 V( `* L. j
  137. }, e' L' w6 P* E# x$ v) ^
复制代码
; h! N, N8 \1 S; [" |. V3 J0 ]) V
porttimer.c
# [3 n2 A) L( R8 C
5 O6 A4 D2 l2 X$ v$ U5 z: d; P
  1. & F& t" y( x" b# w7 Q+ i
  2. ```c
    - F2 u! X. C' b2 F
  3. /*
    ( G4 S' K6 R' }1 J
  4. * FreeModbus Libary: BARE Port3 Z# r" [& Q) [/ D" W* G
  5. * Copyright (C) 2006 Christian Walter <<a href="mailto:wolti@sil.at">wolti@sil.at</a>>
    1 T- b# V2 ~! j, ~
  6. *2 b" o. H; m6 Z  U" o5 O2 O
  7. * This library is free software; you can redistribute it and/or  I, ^: Y% |, R7 P6 w4 a& j- }
  8. * modify it under the terms of the GNU Lesser General Public
    * a. u0 ~$ B# I, C
  9. * License as published by the Free Software Foundation; either
    . R& y+ }% I9 p
  10. * version 2.1 of the License, or (at your option) any later version.
    ) n* H8 d$ ]) v" W: d  C5 Z
  11. *
    # |# W* s0 D. x8 _
  12. * This library is distributed in the hope that it will be useful,
    8 F) [* ~  i/ d' j7 T$ z- W
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
    5 l# y, T1 C% M
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    ' }7 U- T. T, |5 E
  15. * Lesser General Public License for more details.7 F5 Y5 ^7 X( c  k$ X# d
  16. *5 d. }9 S6 G4 N  z( Y
  17. * You should have received a copy of the GNU Lesser General Public
    ( Q' R  E" L' q# s7 n0 K5 ^
  18. * License along with this library; if not, write to the Free Software
    8 @& @5 f, i3 U8 _
  19. * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA8 _6 `1 d: R+ R! d* H
  20. *
    ' \1 g5 s# h9 |( _
  21. * File: $Id: porttimer.c,v 1.1 2006/08/22 21:35:13 wolti Exp $
    8 k2 E8 I$ L) _4 ^
  22. */0 D: b4 p6 w* `+ D

  23. : x0 @. Z) \7 o4 K6 u
  24. /* ----------------------- Platform includes --------------------------------*// K" Z+ o7 \4 t) _
  25. #include "port.h"8 P* P0 c& n, y. s
  26. #include "modbus.h"
    + }) Q* @2 u3 q9 c. q
  27. /* ----------------------- Modbus includes ----------------------------------*/
    + E1 P: W; P( X! i  }& a# ]
  28. #include "mb.h"7 b& p5 y3 a! Z; D& ]9 {; y& _
  29. #include "mbport.h") r  x; y$ P; K/ K
  30. ! _. Z8 |5 F5 I1 r; f
  31. /* ----------------------- static functions ---------------------------------*/7 Y4 w' L# |3 j% i
  32. static void prvvTIMERExpiredISR( void );
    2 c! s) M5 w7 p+ b7 W5 ?/ ^, v" l
  33. : {+ w4 @3 l# @: `! Q) E
  34. /* ----------------------- Start implementation -----------------------------*/
    * H$ e0 f' R) g3 o" ]; y  s
  35. BOOL
    4 m# S3 A5 X( e0 N, E
  36. xMBPortTimersInit( USHORT usTim1Timerout50us )2 Z8 F1 g9 V8 s& d9 Q* O  t
  37. {, n. S5 A' q8 K
  38.         modbus_timer_init(usTim1Timerout50us);( q; W* H% _0 d2 Q  E: m9 s

  39. ' t, l& f+ k! L( g3 m# o1 Z- |
  40.         return TRUE;
    - @6 i' r0 r" ~( z3 z* e, L
  41. }
    7 d& O4 W  ]* }4 a* Q0 j
  42. $ I0 {% E- r. ?$ M
  43. . l. L1 [: ]) k6 t
  44. void
    : G4 J4 I! d) p. T/ B6 ~
  45. vMBPortTimersEnable(  )
    - i+ D1 K9 S0 B1 x; l1 F
  46. {
    0 N4 I' w5 S5 {$ A/ N9 i
  47.     /* Enable the timer with the timeout passed to xMBPortTimersInit( ) */
    4 P, A8 y9 S0 ~' K* F$ r2 L; U
  48.         TIM_ClearITPendingBit(TIM3, TIM_IT_Update);
    / S; i9 k4 l1 s9 ?- [2 `5 ^9 f
  49.         TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE);* Y  W% U8 I. q- I' R4 K/ b
  50.         TIM_SetCounter(TIM3,0x0000);
    ) C& K, U" n/ `# y/ o4 p! T
  51.         TIM_Cmd(TIM3, ENABLE);( D0 e# s3 y3 g0 n& @1 z: ^1 t
  52. }
    : `# ^5 s! b+ U  k
  53.   \: u, \) o  G: u5 n8 p' j
  54. void: t0 x' D% ^3 K: g6 H! y
  55. vMBPortTimersDisable(  )
    % L4 i# _( B  ?" I- A
  56. {
    2 p, {$ z1 i$ d+ V3 N1 i
  57.     /* Disable any pending timers. */
    $ M/ @, @1 m( O8 z
  58.   TIM_ClearITPendingBit(TIM3, TIM_IT_Update);
    8 z& Y  E2 X9 w7 _% f
  59.   TIM_ITConfig(TIM3, TIM_IT_Update, DISABLE);
    . ?# N7 J/ I" d
  60.   TIM_SetCounter(TIM3,0x0000);
    , o# C1 a1 y/ {! Y# C$ {
  61.   TIM_Cmd(TIM3, DISABLE);) o$ a1 |2 ^( U* L. P+ E
  62. }
    + Y1 z) |% L" y
  63. . u( C; y. F& R# C: R; x/ u
  64. /* Create an ISR which is called whenever the timer has expired. This function0 s6 N' B2 _7 R- G$ _' Y" L
  65. * must then call pxMBPortCBTimerExpired( ) to notify the protocol stack that# g7 r$ s( W3 }0 S5 b" A1 D
  66. * the timer has expired.
    2 d% X) a$ N0 v1 r$ a2 z
  67. */
    8 k4 v1 ?4 S7 S! f7 Q
  68. static void prvvTIMERExpiredISR( void )
    ) Z+ f/ M' f( Y9 F! |
  69. {
    - x* z+ Z; J! \* Y$ k* Z9 I. t- \  g
  70.     ( void )pxMBPortCBTimerExpired(  );
    6 s) U# s2 E4 J5 Z$ S$ E* J3 k
  71. }( i+ O& x7 `" Z5 m9 I1 @- \4 o
  72. # k# I+ |# I7 q6 q8 a; p
  73. void TIM3_IRQHandler(void)
    * m) i! R7 ?+ s0 G5 h  M& D
  74. {2 e" @0 J1 p5 t1 n" R0 ^
  75.         if(TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET)
    - |( X2 X5 B5 {  u
  76.         {2 F/ o" [! u0 q; a4 E$ P
  77.                 prvvTIMERExpiredISR();7 w6 |% e- C' j% M+ G' m( M! e
  78.                 TIM_ClearITPendingBit(TIM3, TIM_IT_Update);
    * i8 s1 L7 `- H* Q0 ^8 w( U
  79.         }
    2 z& |8 s3 ?2 J' j% z
  80. }
复制代码
% j- u0 i' v1 w6 J6 p3 ~! i; q; |5 @) k
然后主函数中调用% I) P& }. j4 L  X' {+ t7 U
3 a  d' t/ P8 T

  1. : Y: L7 J; L' B0 y! N( u" H
  2. int main(void)
    $ z4 m1 d' @' m$ C
  3. {               
    ) D5 M( z0 w  N3 l3 M  L
  4.         delay_init();                     //延时函数初始化         
    3 T4 \# r# ~# H" ~
  5.         NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
    / {) x* e6 Y$ X9 }& ^* N
  6.         uart_init(115200);
    1 Q4 R3 Y' q/ T3 f
  7.         eMBInit(MB_RTU, 0x01, 0x01, 9600, MB_PAR_NONE);
    ! D% A+ K7 D' w: t, h- A
  8.         eMBEnable();  
    6 M9 B; u; F0 Y% h# p4 p1 O" t
  9.          while(1)
      d1 w$ T6 q* t
  10.         {
    4 \/ J" A2 j% p& d# W! h
  11.                 (void)eMBPoll();
    + x3 {# O3 @4 l& n$ s0 t. _
  12.                 delay_ms(5);
    ; |# ^+ f1 O1 d, ^
  13.                 ) U/ c& [9 n5 i7 _- w9 r$ u6 f
  14.         }         " v, [* N4 Q3 B" a. B
  15. }
复制代码

8 k7 f' ?- p, o9 G其次还要实现读线圈、写线圈、读离散输入、写保持寄存器、读保持寄存器、读输入寄存器等功能,如下:  r; p, p& y# T: K4 C0 \- j

/ k, M& ^9 s5 G! C
  1. #define REG_INPUT_START       0x0001        //输入寄存器起始地址0 g1 D# V, S2 v
  2. #define REG_INPUT_NREGS       8                        //输入寄存器数量
    4 @3 N& {4 x$ b; M- m) J

  3. 4 ~. c0 m( P: Q* t. l6 U
  4. #define REG_HOLDING_START     0x0001        //保持寄存器起始地址
    % [5 f8 @9 c7 q) M* ~' Z/ S% M
  5. #define REG_HOLDING_NREGS     8                        //保持寄存器数量) B# l2 j' S, g8 }3 ^: A( t
  6.   z& n( i* A3 ?, N3 U* w, q# \3 ?: }
  7. #define REG_COILS_START       0x0001        //线圈起始地址( |2 [* d0 j$ U
  8. #define REG_COILS_SIZE        16                        //线圈数量
    4 H1 E4 K" L( V* n2 v
  9. / V/ d) j* J8 P8 a
  10. #define REG_DISCRETE_START    0x0001        //开关寄存器其实地址
    5 l8 V4 h1 g- \$ E( C
  11. #define REG_DISCRETE_SIZE     16                        //开关寄存器数量
    ' V8 @/ i, \- H/ G
  12. //输入寄存器内容
    $ Z7 O$ h% ]5 o$ |4 j" G
  13. uint16_t usRegInputBuf[REG_INPUT_NREGS] = {0x1000,0x1001,0x1002,0x1003,0x1004,0x1005,0x1006,0x1007};! Q( ^3 R2 G9 J; T
  14. //保持寄存器内容               
    $ k+ V5 ?& V3 p, q
  15. uint16_t usRegHoldingBuf[REG_HOLDING_NREGS] = {0x2000,0x2001,0x2002,0x2003,0x2004,0x2005,0x2006,0x2007};                                       
    0 \9 |# l6 h* b! }$ c0 x3 R, N0 l
  16. //线圈状态
    8 a" n4 Q6 {' j/ b1 F
  17. uint8_t ucRegCoilsBuf[REG_COILS_SIZE] = {0x01,0x01,0x00,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00};5 \6 x: Y; X' I
  18. //离散寄存器内容7 T1 Q9 p4 l; _+ v8 j. n6 m0 r
  19. uint8_t ucRegDiscreteBuf[REG_DISCRETE_SIZE] = {0x01,0x01,0x00,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x01}; ' g; y& o( ]8 P, s. j. M
  20. 7 {% B2 m! ~# n- T6 C  M
  21. /****************************************************************************
    9 o3 q3 [8 o* u; A
  22. * 名          称:eMBRegInputCB 6 Q. z; e7 _+ O) Q" L
  23. * 功    能:读取输入寄存器,对应功能码是 04 eMBFuncReadInputRegister
    ) q9 d& Y- K" q  y9 k' G5 c0 E
  24. * 入口参数:pucRegBuffer: 数据缓存区,用于响应主机   
    ( [& w. @" d3 f+ [/ A
  25. *                                                usAddress: 寄存器地址
    6 p2 w0 ]5 u7 B
  26. *                                                usNRegs: 要读取的寄存器个数2 T3 o  `% I, {) _0 |9 E
  27. * 出口参数:
    * E$ p, I" P3 p
  28. * 注          意:上位机发来的 帧格式是: SlaveAddr(1 Byte)+FuncCode(1 Byte)
    % F8 j: Z/ I- s. m
  29. *                                                                +StartAddrHiByte(1 Byte)+StartAddrLoByte(1 Byte)
    + ?  R3 I* g6 V
  30. *                                                                +LenAddrHiByte(1 Byte)+LenAddrLoByte(1 Byte)+( P3 l1 p4 }2 u+ _. q8 |
  31. *                                                                +CRCAddrHiByte(1 Byte)+CRCAddrLoByte(1 Byte)' @( [& l+ s1 F5 v' t: i8 E: q
  32. *                                                        3 区7 ^' F) c8 p& h
  33. ****************************************************************************/
    * W  h; [5 u* J9 n
  34. eMBErrorCode' }; }& M' @/ e4 z6 H! F
  35. eMBRegInputCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNRegs )
    ) A" b; W3 @2 C. |1 \! i# D
  36. {  e# i/ H+ q% x: \0 t. G3 }: |
  37.     eMBErrorCode    eStatus = MB_ENOERR;
    7 ~: d% ]# F9 v' u2 S5 Y: C0 J6 o/ a
  38.     int             iRegIndex;
    8 R8 B, \- {2 }  m# w

  39. , ?1 p) v! z+ z
  40.     if( ( usAddress >= REG_INPUT_START )
    7 Z$ c+ A5 Y, R, j
  41.         && ( usAddress + usNRegs <= REG_INPUT_START + REG_INPUT_NREGS ) ). F+ N7 S4 e4 R5 O: Q! V) ~
  42.     {
    ( V% ^  b8 J  N6 F# [, Y; x
  43.         iRegIndex = ( int )( usAddress - REG_INPUT_START );
    1 G* p' c" \7 ~2 g6 w
  44.         while( usNRegs > 0 )
    1 G0 r: C$ m5 S
  45.         {
    6 |; ]9 s# z# n+ ^3 P5 {; O
  46.             *pucRegBuffer++ = ( UCHAR )( usRegInputBuf[iRegIndex] >> 8 );
    $ Y* g3 s, }! i6 t' j: d5 [
  47.             *pucRegBuffer++ = ( UCHAR )( usRegInputBuf[iRegIndex] & 0xFF );
    ; m) N8 Q0 f) {. f* P2 h4 c
  48.             iRegIndex++;  O2 [* Z) S7 z/ {, y# r
  49.             usNRegs--;9 h" p# _  O2 N& C# R9 Y
  50.         }/ h* N( |  h, ]8 W: Q5 F
  51.     }
    " b( ~( j3 ?: {4 Z/ ]
  52.     else- R: ^5 P8 z1 G* ~
  53.     {
    $ z1 n+ ]8 E  T. x3 q6 @+ v
  54.         eStatus = MB_ENOREG;& L. C, y/ a# O5 n$ v
  55.     }& y% H8 a4 u4 {+ [) T
  56. 2 R$ Y) g# }/ v$ X9 i
  57.     return eStatus;: P2 u. [( z# |/ p* D1 ^
  58. }7 O9 H8 ]+ Y# u7 S* Z  W
  59. . ~, P: C$ J2 l: d7 n. V
  60. /****************************************************************************
    : F! Q7 U9 _. r" k
  61. * 名          称:eMBRegHoldingCB + v9 m3 \, u! J' e! e$ h
  62. * 功    能:对应功能码有:06 写保持寄存器 eMBFuncWriteHoldingRegister * k. K; G5 Q& f" G" X
  63. *                                                                                                        16 写多个保持寄存器 eMBFuncWriteMultipleHoldingRegister& I/ f$ H8 _- k4 r  O. e/ ]
  64. *                                                                                                        03 读保持寄存器 eMBFuncReadHoldingRegister* H: S% c( I- W' }7 D: A
  65. *                                                                                                        23 读写多个保持寄存器 eMBFuncReadWriteMultipleHoldingRegister  `# \- m, e! \5 @
  66. * 入口参数:pucRegBuffer: 数据缓存区,用于响应主机   
    7 M  i1 X1 q/ Z9 @/ i  N3 p$ Q( \# P
  67. *                                                usAddress: 寄存器地址
    ( E, ~, t! U; r! F# ~* ~
  68. *                                                usNRegs: 要读写的寄存器个数3 d/ D3 q+ ^5 Z8 q) N
  69. *                                                eMode: 功能码
    ' _/ t$ n9 A+ ^; t2 L4 G
  70. * 出口参数:
    & [; V* D0 K8 N
  71. * 注          意:4 区' `6 \/ o& i3 |5 \& L  \" \
  72. ****************************************************************************/
    - K- @" J  O5 F. M. o* |
  73. eMBErrorCode+ ?+ M+ V1 L3 ^0 i- W# d1 P+ f
  74. eMBRegHoldingCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNRegs, eMBRegisterMode eMode )
      y2 w- i3 {) N* l, y( `$ z( l2 i
  75. {9 _8 U0 D- y" i0 ~+ k
  76.         eMBErrorCode    eStatus = MB_ENOERR;
    + v: u( J% W' M! b
  77.         int             iRegIndex;
    + \: e% C3 V6 n0 x8 O0 \
  78. . T+ G% [& \; y8 S
  79. # `4 P- a4 {+ K0 r0 Y% v
  80.         if((usAddress >= REG_HOLDING_START)&&\
    ) T# U6 s6 T: T0 k( [
  81.                 ((usAddress+usNRegs) <= (REG_HOLDING_START + REG_HOLDING_NREGS))): |8 ]; a* w' o0 [
  82.         {# K. D! K  a9 f6 H' n
  83.                 iRegIndex = (int)(usAddress - REG_HOLDING_START);% s1 X  f  a0 B+ a3 c4 a
  84.                 switch(eMode)
    / |0 k9 v" O% h
  85.                 {                                       
    4 r. C  R. \, c' h8 `2 N% Y
  86.                         case MB_REG_READ://读 MB_REG_READ = 0
    8 p( t0 Z0 T) L
  87.                                 while(usNRegs > 0)( D) e' u3 p3 o! W( ?; b
  88.                                 {
    3 j% i, _; a6 J- v% w9 h
  89.                                         *pucRegBuffer++ = (u8)(usRegHoldingBuf[iRegIndex] >> 8);            
    ; l' G# B4 o( U; k& h$ l; \0 v
  90.                                         *pucRegBuffer++ = (u8)(usRegHoldingBuf[iRegIndex] & 0xFF);
    ! c, J: {, T$ t6 s9 u
  91.                                         iRegIndex++;
    # k- F  ]+ ~' o% o2 g8 X+ P
  92.                                         usNRegs--;                                        4 n* {. v3 l( u. ^7 h6 {9 B
  93.                                 }                           
    6 m: c$ v  M5 i+ Q
  94.                         break;( i" i* {* M' `
  95.                         case MB_REG_WRITE://写 MB_REG_WRITE = 0
    ) ]( w+ T+ ~) H0 y  d0 Z# m/ r
  96.                                 while(usNRegs > 0)
    ' i, |! L' d) Z. A$ G% E- v2 e+ v
  97.                                 {         * C  }) [" [6 }( i, O) H7 U4 j
  98.                                         usRegHoldingBuf[iRegIndex] = *pucRegBuffer++ << 8;' f5 B& i/ S" U1 S: y6 P- a1 i
  99.                                         usRegHoldingBuf[iRegIndex] |= *pucRegBuffer++;6 w1 x: d. {- Q; N. c
  100.                                         iRegIndex++;
    ' r" U" a: r# D( a. K# i/ f
  101.                                         usNRegs--;
    . S( Z# |0 X3 i& \
  102.                                 }. e# w! K& f9 K5 O
  103.                         break;                                
    1 i- u, `3 ]9 l$ X! w$ W
  104.                 }
    ' ?1 [0 p9 |& E( ?! }
  105.         }& g" W9 d$ Q% c
  106.         else//错误* J7 n* K$ T4 ?9 K- D, }
  107.         {; e: `; C' T' B9 ^2 j& e* |6 a
  108.                 eStatus = MB_ENOREG;' @, v( I6 ~2 a" z# x
  109.         }        % H$ B* m! U& b$ u; a" d: w% Z- T: v
  110.         
    : m$ \4 D5 @" C* C% H
  111.         return eStatus;
    4 ]+ ?& I9 o& c, D/ j8 X
  112. }
    7 k7 X# t: R: G2 t/ Y( l7 R5 f

  113. , y  @& O1 t* V
  114. /****************************************************************************
    ! a8 r% f+ D. a9 _
  115. * 名          称:eMBRegCoilsCB
    - ^) Z  `( @- i$ w$ `! U, m# E
  116. * 功    能:对应功能码有:01 读线圈 eMBFuncReadCoils8 p4 V9 D4 F0 Z& C& s! q' M
  117. *                                                  05 写线圈 eMBFuncWriteCoil* L9 [+ y2 ^4 O4 e$ q# |8 V/ ?, _
  118. *                                                  15 写多个线圈 eMBFuncWriteMultipleCoils" E4 l5 d$ p$ a  a' ^1 y9 S; v( ?- x
  119. * 入口参数:pucRegBuffer: 数据缓存区,用于响应主机   
    ; T5 {' K& p# Y4 m
  120. *                                                usAddress: 线圈地址
    7 ?" Z  a% O6 i5 `. ?
  121. *                                                usNCoils: 要读写的线圈个数* t. X8 e# r" A6 q* ^* D# r) n
  122. *                                                eMode: 功能码# u0 h. ~6 B& L4 w  d
  123. * 出口参数:2 K  I; K! [" D5 b1 k
  124. * 注          意:如继电器 : C6 C! k- Z, ]% c1 J9 n0 c' `
  125. *                                                0 区8 x0 p7 s  v# e- o- X
  126. ****************************************************************************/
    $ e% K+ U1 f& ?+ s( M7 H( o
  127. eMBErrorCode3 o; J' U2 z5 q+ N# D2 D8 V
  128. eMBRegCoilsCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNCoils, eMBRegisterMode eMode )4 j/ _+ Q( I$ e8 N0 c  J
  129. {
    ' V2 E6 c8 O+ e. u- e% b* ~# B
  130.         eMBErrorCode    eStatus = MB_ENOERR;; q8 d. ]+ K2 @( J0 f
  131.         int             iRegIndex;+ y8 \' D/ T& \( V5 o3 n
  132.         u8 i;
    0 c. F4 t' q: X1 z' c- ~. g
  133.         USHORT readNumber=usNCoils;
    2 f  z/ z( G: Q0 o! @
  134.         USHORT coilValue=0x0000;! p- I) g! P# c
  135.         if((usAddress >= REG_COILS_START)&&\
    * k* k& W7 J+ B# E# I
  136.         ((usAddress+usNCoils) <= (REG_COILS_START + REG_COILS_SIZE)))8 \, _, L2 p7 [( {
  137.         {# x& o  e2 W. U; ]% x; W0 }
  138.                 iRegIndex = (int)(usAddress + usNCoils-REG_COILS_START);0 K5 C1 q" A% S+ H! j; H( A, {7 t6 |
  139.                 switch(eMode)" Y1 L! S9 C" A3 M. P
  140.                 {                                       8 O3 r. n9 Y* y6 o3 ~
  141.                         case MB_REG_READ://读 MB_REG_READ = 06 T0 g( _& h1 \/ i5 f
  142.                                 for(i=0;i<usNCoils;i++)) x6 j5 t& C8 T. j# s+ R1 I
  143.                                 {7 Q4 F* x. W' h* O* d$ m2 E) P
  144.                                         readNumber--;
    0 _* r6 ?8 q7 f" v* c
  145.                                         iRegIndex--;
    % Z* C! W2 `2 ~1 T. L  U2 c  Y
  146.                                         coilValue|=ucRegCoilsBuf[iRegIndex]<<readNumber;) U. q, c2 V# H+ H6 o. o' W
  147.                                 }4 p! n; y7 d* G% |! w
  148.                                 if(usNCoils<=8)2 [" n- T" E  Y) J
  149.                                 {
    6 V+ K. O% G) y' P' b, a# b
  150.                                         * pucRegBuffer=coilValue;, W2 b# b3 x- @9 L
  151.                                 }
    ) [' O3 }, F( r9 p- f9 P' h) P
  152.                                 else
    3 N5 A8 W  r  e5 v4 X
  153.                                 {
    2 @& W+ ^- }( a: w5 U% e: P5 f, `, M
  154.                                         * pucRegBuffer++ = (coilValue)&0x00ff;1 n$ H4 F' x, \+ U) ^6 C9 P7 C
  155.                                         * pucRegBuffer++ = (coilValue>>8)&0x00ff;, ?" n/ h/ h) M# J( _
  156.                                 }
    " a. P; T2 s4 r% Q+ d) Q
  157.                         break;                            $ U  a- U  d8 k: [8 c
  158.                         case MB_REG_WRITE://写 MB_REG_WRITE = 1
    8 x/ O7 L9 y( F
  159.                                 while(usNCoils > 0)
    . M7 A) w. F6 ~2 `
  160.                                 {           }- g+ P$ A% h* E) t. a  I7 O
  161.                                         //                         usRegHoldingBuf[iRegIndex] = *pucRegBuffer++ << 8;
    # K% z8 X6 s9 m
  162.                                         //           usRegHoldingBuf[iRegIndex] |= *pucRegBuffer++;
    % b+ g. T$ M. }. x: v4 u
  163.                                                 iRegIndex++;
    ; A$ G9 u# W, M6 J
  164.                                                 usNCoils--;
    / v2 a6 P( P, v# c% \
  165.                                 }$ ~! b$ o9 O" Q5 X' c' b! c
  166.                         break;9 s% |3 l) L# b0 s7 F
  167.                 }9 y  T7 f+ |$ I4 x% t! {' [
  168.         }! x; ^, |) ?  _5 ]
  169.         else//错误) I3 R2 v; j7 Z8 W
  170.         {" {3 z$ L) H# p/ U5 ]5 @
  171.                 eStatus = MB_ENOREG;- q' r% _' D( ?& a* B+ i
  172.         }        
    9 F/ [/ ~1 E& A* B) x' {

  173. % Z2 Z+ J+ J7 r
  174.         return eStatus;
    4 d2 H! e1 ^; u& |2 }* o
  175. }; W6 V% j- o2 T- H/ D9 {
  176. /****************************************************************************: c1 S7 {; J# x7 V) _
  177. * 名          称:eMBRegDiscreteCB 4 _  p5 b  W! r4 f
  178. * 功    能:读取离散寄存器,对应功能码有:02 读离散寄存器 eMBFuncReadDiscreteInputs
    " _" {; v" u* F0 b
  179. * 入口参数:pucRegBuffer: 数据缓存区,用于响应主机   " |4 p# Y: x+ d- O
  180. *                                                usAddress: 寄存器地址
    0 k& T( l$ P1 H1 }5 `5 o: m
  181. *                                                usNDiscrete: 要读取的寄存器个数
    2 `4 U" n- B9 O  k) \, B
  182. * 出口参数:  y, x9 a1 u! m9 |
  183. * 注          意:1 区
    / g" ?6 j) ~% F/ J
  184. ****************************************************************************/8 V2 @! q3 t9 H
  185. eMBErrorCode: k+ s, `7 Q4 B) v, _+ p) j
  186. eMBRegDiscreteCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNDiscrete )1 F$ v! J  z( ]2 ^3 F; Z
  187. {
    & j+ ~: Y/ m' n6 d
  188.         eMBErrorCode    eStatus = MB_ENOERR;
    0 M/ k1 N+ y; L, ^2 ]7 [+ N
  189.         int             iRegIndex;
    5 u6 M* W' G; U" R5 R$ I9 V
  190.         u8 i;
    + U& ^* E2 g$ F. Z- _1 {
  191.         USHORT readNumber=usNDiscrete;. w9 m# N" ^- I
  192.         USHORT coilValue=0x0000;& M1 \6 V  I8 C- U
  193.         iRegIndex = (int)(usAddress + usNDiscrete-REG_DISCRETE_START);4 L9 b# H8 g- ]! G8 P3 s7 o3 R
  194.         if((usAddress >= REG_DISCRETE_START)&&\/ D+ l7 l- ?0 Y/ G
  195.         ((usAddress+usNDiscrete) <= (REG_DISCRETE_START + REG_DISCRETE_SIZE)))
      S2 a  f6 \4 I) R% F, a
  196.         {
    4 q/ j& b5 ?$ Y8 B/ z9 w; H
  197.                 for(i=0;i<usNDiscrete;i++)* K% d% D4 o: p1 J- s
  198.                 {/ S% n5 r; k, L, W* {& {# M
  199.                         readNumber--;
    - y& S" ~; j3 s- n  y( N- C4 I+ R
  200.                         iRegIndex--;+ t( y* s" U0 _& ]
  201.                         coilValue|=ucRegDiscreteBuf[iRegIndex]<<readNumber;
    5 d4 I) {5 x; w/ U6 g5 w! ~
  202.                 }5 `& y: @' h8 K0 [! D: U9 S
  203.                 if(usNDiscrete<=8)
    % H" E! T8 F+ S
  204.                 {4 p/ b  F* }7 e9 Z2 x
  205.                         * pucRegBuffer=coilValue;
    7 h& s5 R! [4 l. Z4 D
  206.                 }
    & h5 X7 X# L. a$ c
  207.                 else
    + s7 h( T0 A0 {  F7 Q7 u
  208.                 {
    ! k' B$ t7 c6 Z/ z+ b
  209.                         * pucRegBuffer++ = (coilValue)&0x00ff;
      R3 i; j' C: Q5 w
  210.                         * pucRegBuffer++ = (coilValue>>8)&0x00ff;. a4 i+ Z( j' u6 x6 a
  211.                 }
    0 v* l4 \; e) a, C. r9 u
  212.         }6 U8 \. L! ?  ], F+ }: i
  213.         else
    / ]/ b, C; B, S
  214.         {
    # @- f; o9 A& b5 E, k8 Q6 E
  215.                 eStatus = MB_ENOREG;
    7 @0 [9 c7 p, Q7 \% S' m
  216.         }1 y3 V- j( H" c" s/ f4 V
  217.     return eStatus;, V( z' m/ g2 w. W% k0 O
  218. }' K0 [7 O4 K( r4 e1 m

  219. , A9 {, j( I" }( e* {. p) O+ F& q8 D
  220. ) y6 E0 O3 }2 J. x

  221. . J, ]9 Q9 O- U9 v8 H% u
  222. 8 ~0 i$ ~  q) E1 _
复制代码
; ]" ^" M. B( R9 M6 P0 @0 a

; }- U  E6 @2 V% O
, a' t4 k) G* K* E+ q

点评

如果跑freertos的话,这套操作同样适用吗?  发表于 2026-1-29 16:34
赞 收藏 评论1 发布时间:2022-4-23 15:41

举报

1个回答

所属标签

相似技术帖

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版