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

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

[复制链接]
STMCU小助手 发布时间:2022-4-23 15:41
首先将FreeModbus移植到自己工程中,如下图所示:
3 o$ R. c9 ^. ~6 M( Y 20200323104757628.png
- h( N& r. k$ h- N% j/ ^
5 A3 c2 ^8 \* {" l4 s* }然后修改portserial.c和porttimer.c文件:
# i9 E6 h1 S. ~4 aportserial.c8 a) b$ q0 v% o( z! s* ?" a/ G! W
% i# N% U# O/ B; ~$ T" C
  1. /*
    # y6 h! F/ A% A: [0 V
  2. * FreeModbus Libary: BARE Port
    & C* _9 o! V/ r$ W; d8 q9 X
  3. * Copyright (C) 2006 Christian Walter 8 Q$ y) k  e- z) _, S
  4. *8 g  J) h3 Q4 C: n. w3 C
  5. * This library is free software; you can redistribute it and/or
    6 z9 k! w- \2 x/ K
  6. * modify it under the terms of the GNU Lesser General Public2 [$ {+ c3 q1 P) _# W& ~/ h5 g, C9 C
  7. * License as published by the Free Software Foundation; either) J( u# z" z2 M2 }1 x5 ~
  8. * version 2.1 of the License, or (at your option) any later version.
    - ?: S3 g: c  x& w7 G. \
  9. *
    7 n9 n: T; d# f
  10. * This library is distributed in the hope that it will be useful,# u% J$ I8 F2 ~8 O% T" X
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of  y$ Z( s' B/ g2 ?7 W
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU0 r% A+ Z! f. g* E! `  ]
  13. * Lesser General Public License for more details.: G2 C1 b0 p) J! J0 J6 G
  14. *
    6 N0 P7 @6 ~/ F. F# G& v
  15. * You should have received a copy of the GNU Lesser General Public
    + c. c$ P% a# X; g( b6 `, v$ f9 W
  16. * License along with this library; if not, write to the Free Software# ]4 _. `% @7 V3 k
  17. * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
    8 q$ O3 S; F( b- F5 X( y/ y
  18. *
    ' J2 b# D: E9 B( k
  19. * File: $Id: portserial.c,v 1.1 2006/08/22 21:35:13 wolti Exp $$ R( X' F+ k4 I# q% D  z) ]/ f
  20. */, p, n, {" t/ l/ P

  21.   y  c" ^4 p3 }
  22. #include "port.h"" G' P4 t' a- t. J; N
  23. #include "stm32f10x.h"1 S7 x1 H2 F/ z1 @* h  j
  24. #include "modbus.h"
    9 s$ i- H! y5 ~, e: x
  25. /* ----------------------- Modbus includes ----------------------------------*/, M* I7 m9 z) O" ?- J* f3 j
  26. #include "mb.h"
    9 d9 F5 C2 ]; c( y
  27. #include "mbport.h"
    ) B. |6 R$ G# C8 p0 h0 p
  28.   ?! u1 Z6 A6 {, }5 _! h$ m
  29. /* ----------------------- static functions ---------------------------------*/2 }5 z& t, @4 [& E% M, z
  30. static void prvvUARTTxReadyISR( void );2 B" M7 \6 U9 q4 l
  31. static void prvvUARTRxISR( void );+ r- W- T6 `% B, @% C
  32. ! a2 s" ~* f% m; a4 z& z
  33. /* ----------------------- Start implementation -----------------------------*/+ z+ t5 v% L+ D1 V0 `9 S; T0 w0 U
  34. void! J% L" C! h5 s1 w3 j
  35. vMBPortSerialEnable( BOOL xRxEnable, BOOL xTxEnable )
    % ?  X. R' z( O2 Z, R+ N9 Z  h
  36. {  u9 I9 g) z' H/ x; u' }" ~3 y
  37.     /* If xRXEnable enable serial receive interrupts. If xTxENable enable& z) B3 T+ m( f% S+ {* g
  38.      * transmitter empty interrupts.5 |# J+ S( C: H# R  i0 C8 a( s
  39.      */9 o: E/ X! Q+ D+ d, Q
  40.         if(xRxEnable == TRUE)9 T9 H5 G1 A$ O) m4 P2 C! b9 Y
  41.         {
    $ k. |# f8 R4 H# s; w
  42.                 USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);: E1 Q, T! ~( L$ M$ }  \
  43.         }: i7 S0 D7 T  Y# Z+ m' R5 c: V
  44.         else
    2 f+ m  H6 H$ B9 W8 _& q) x
  45.         {9 s0 W" d# U9 v/ ~
  46.                 USART_ITConfig(USART2, USART_IT_RXNE, DISABLE);
    0 p5 Y$ l; w+ U- U4 [9 `; Q/ Y
  47.         }/ p& S( m5 X$ T' g
  48.         + j' v* r# W2 ?" J
  49.         if(xTxEnable == TRUE)
    ; p0 ~* x2 D; m- ~9 T$ ?
  50.         {3 @9 `" h- K, ~( z% _
  51.                 USART_ITConfig(USART2, USART_IT_TC, ENABLE);4 e' u  e4 ~9 d5 O  p9 K3 M( u
  52.         }  l4 I$ e8 R. @* |
  53.         else1 D4 l$ h$ i) u6 h9 ~' J
  54.         {* Z) h3 P* _+ R" c: b
  55.                 USART_ITConfig(USART2, USART_IT_TC, DISABLE);  }- ~& o& s1 ^' r7 h
  56.         }) Z1 k5 r! u# Y7 B$ p, j0 h6 ^% `
  57. }
    & @9 \. q$ h( ~5 c( U2 j) s
  58. 4 q1 r2 u( r5 r
  59. BOOL
    9 U/ {- y' Z/ d7 i0 M
  60. xMBPortSerialInit( UCHAR ucPORT, ULONG ulBaudRate, UCHAR ucDataBits, eMBParity eParity )/ N+ E" C+ v3 A+ r
  61. {4 N/ [% O; w- k* T) a7 f
  62.         modbus_uart_init((uint16_t)ulBaudRate);  
    " [; z) u- R- z8 N1 o3 u4 v0 A

  63. # Z! T0 Q. _" y
  64.         return TRUE;
    ' p" S5 D* E5 ~& y& \0 ~
  65. }) g) T* p/ |; e9 I6 G

  66.   u$ Z+ }7 w: k  G3 j& i8 S, |: p* J
  67. BOOL
    / M4 U; K4 M# V& `3 y. @
  68. xMBPortSerialPutByte( CHAR ucByte )# f& Q% X4 G) g. P- ~- Q
  69. {
    9 m% G( ]9 n) _4 N+ g0 H" Y$ |& O
  70.     /* Put a byte in the UARTs transmit buffer. This function is called: e& Y7 u7 \% R/ |0 l4 J
  71.      * by the protocol stack if pxMBFrameCBTransmitterEmpty( ) has been
    1 F7 k2 ]/ A1 Z1 y
  72.      * called. */( p# l* D* `! O/ q  L- U8 Y
  73.         
    ) n% _- f) Q) ?8 P3 J, I* F& G) J$ c
  74.         USART_SendData(USART2, ucByte);
    6 O( |$ Y) D4 v1 H
  75.     return TRUE;7 M" m' h* S% F
  76. }, u+ F* t5 i4 N7 {# p9 R8 q9 Q0 L
  77. + P  Y; M. Z  C, |0 |
  78. BOOL
    * j; d6 b3 e- A2 X8 R! ]% n
  79. xMBPortSerialGetByte( CHAR * pucByte )) i% f7 g% N: j
  80. {
      ]- W  i- u( L7 _7 i, K; i
  81.     /* Return the byte in the UARTs receive buffer. This function is called$ Y/ A# H% C! v# a8 a) p" o
  82.      * by the protocol stack after pxMBFrameCBByteReceived( ) has been called., A# T+ d0 q/ o$ I8 _
  83.      */) t$ r$ L( O2 B6 Y  W
  84.   *pucByte = USART_ReceiveData(USART2); 7 @! \: {# d7 a/ y$ w- c% P
  85.         return TRUE;
    - w8 a1 ?$ u2 S7 l4 Q
  86. }
    ' K! i  a  e$ d$ O9 }; T# p
  87. - ]) T. g( y3 b
  88. /* Create an interrupt handler for the transmit buffer empty interrupt
    " U9 h, l' k+ M5 [' A  H, x. M# b
  89. * (or an equivalent) for your target processor. This function should then
    / [& ]3 a/ _7 \; ~& `. a3 e& V4 {
  90. * call pxMBFrameCBTransmitterEmpty( ) which tells the protocol stack that$ D. Q& U: z1 u# X5 T6 v
  91. * a new character can be sent. The protocol stack will then call
    ( q0 Z) n+ @! U+ o
  92. * xMBPortSerialPutByte( ) to send the character.* z6 l; N4 V7 b3 D
  93. */
    5 S8 I0 H+ @% r' l, f% v9 X7 X
  94. static void prvvUARTTxReadyISR( void )1 J& y- Q& f  w; j! V3 B! f8 p9 |
  95. {1 K7 s# b4 A$ O1 f
  96.     pxMBFrameCBTransmitterEmpty(  );
    9 ?# W+ `) a/ a# `- M+ K
  97. }# m: ^- l) R' K9 W  c, Y

  98. 1 G) k" ^8 v! T+ f. Y! @
  99. /* Create an interrupt handler for the receive interrupt for your target8 m" p- G) F7 K# D2 m8 Z1 l
  100. * processor. This function should then call pxMBFrameCBByteReceived( ). The
    . H4 A- g- {" L. l/ W
  101. * protocol stack will then call xMBPortSerialGetByte( ) to retrieve the- H+ r0 `/ [% H8 C
  102. * character.
    ! D& S6 ^: y5 l" P+ K/ }3 u* G
  103. */4 H( i: k* G6 T) @
  104. static void prvvUARTRxISR( void )
    : `  s2 i$ _# I; ?; {5 B
  105. {+ e! @+ X' g, u8 Y3 L
  106.     pxMBFrameCBByteReceived(  );( D3 T" t* T! A' w
  107. }9 i6 T6 y6 N4 X2 A
  108. ! Y3 e2 p+ e" U( N3 Q
  109. /**- u, _) d; }' K
  110.   * @brief  This function handles usart1 Handler.1 M& ~$ r+ t+ ]7 D9 X9 y
  111.   * @param  None) m3 J( x+ a0 y$ a) X8 y
  112.   * @retval None" M/ @3 F* T$ D* w5 N
  113.   */
    - R& x4 ?& C* `2 i* z# R8 j
  114. void USART2_IRQHandler(void)
    % H2 v& F' j% c) Y4 y. K% O9 z
  115. {
    ' R  D* k/ p! Q; p" A
  116.         //发生接收中断
    . c1 d3 {3 s1 t( S* Y9 I# _7 \
  117.         if(USART_GetITStatus(USART2, USART_IT_RXNE) == SET)
    ( D6 E2 F5 Y1 r9 E3 ]3 Y$ G) T
  118.         {# Y2 d/ w  H! c. t
  119.                 prvvUARTRxISR(); 4 _0 E- s& I9 P
  120.                 //清除中断标志位      ^! j/ w% ^1 x
  121.                 USART_ClearITPendingBit(USART2, USART_IT_RXNE);   
    3 P8 M- g4 W% H9 ]4 o4 V+ |
  122.         }5 r6 _/ K( q  \. w* N

  123. 9 O+ g- \2 c! _9 G
  124.         if(USART_GetITStatus(USART2, USART_IT_ORE) == SET)$ u, t+ C' h) K# M+ m% U
  125.         {  5 f$ u$ b* T: Q
  126.                 USART_ClearITPendingBit(USART2, USART_IT_ORE);6 F" Y- o: B  @+ {6 g! U
  127.                 prvvUARTRxISR();         
    1 A: `- l' {  O$ E
  128.         }
    0 K1 N# Y0 q1 K2 e2 T

  129. 4 u. n4 o4 {( }' \
  130.         //发生完成中断
    : J1 X. z  l+ z" W# L; Z' Z; R9 ~
  131.         if(USART_GetITStatus(USART2, USART_IT_TC) == SET)+ U1 w+ x2 y+ q( B. h. Q( T
  132.         {5 a  v+ a2 G+ L; X# p, q
  133.                 prvvUARTTxReadyISR();! \" y2 b. x" Y( y( l
  134.                 //清除中断标志
    $ |' D+ ~/ n1 t) I& O% d9 A  g
  135.                 USART_ClearITPendingBit(USART2, USART_IT_TC);6 n7 o2 o/ a7 R1 ^' I
  136.         }  H: h. V. ~7 Q" D$ Q
  137. }& t% Y: c6 o3 p6 y* h) U5 y7 [/ h
复制代码

. M& Z( M5 ^5 [7 N+ c/ D+ Eporttimer.c  }, ?1 t5 [7 U3 j1 R
, ~% |9 h: b. S9 V) o8 J1 \
  1. ) S& A+ ^" ^* I3 g" v
  2. ```c* d6 C& f. N0 `% {' u: l
  3. /*  b7 V' X0 o! A' n( \. P
  4. * FreeModbus Libary: BARE Port
    9 v! K/ {) H+ I
  5. * Copyright (C) 2006 Christian Walter <<a href="mailto:wolti@sil.at">wolti@sil.at</a>>7 L, [$ U& n4 h8 f( {
  6. *
    8 M$ X4 n7 c# U; e
  7. * This library is free software; you can redistribute it and/or
    * A6 W! k8 [% F: v" n* s
  8. * modify it under the terms of the GNU Lesser General Public
    $ ?2 E7 l! F$ A) d  e; Q
  9. * License as published by the Free Software Foundation; either
    : E# |0 m" W( f. G* {7 V* g& z
  10. * version 2.1 of the License, or (at your option) any later version.
    ! N) B4 B8 d% Z0 L7 V  n& ~3 q
  11. *9 ?* ~6 v2 q0 x! F
  12. * This library is distributed in the hope that it will be useful,
    9 c: M; s: s" k
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of3 l# ^' z1 G# v+ R
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU- o  Q0 O2 R% U7 Z
  15. * Lesser General Public License for more details.  K; e: a, {3 s5 I0 {' m
  16. *- G4 `+ [+ z: Q; Q, w: b4 R
  17. * You should have received a copy of the GNU Lesser General Public
    3 ^9 K' H. y8 C! [4 s- h, V, e
  18. * License along with this library; if not, write to the Free Software3 C/ c- l6 d- k; }; @
  19. * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA2 c" u3 R" c3 `
  20. *6 N8 r3 T6 E7 V5 e; M; E5 A5 B
  21. * File: $Id: porttimer.c,v 1.1 2006/08/22 21:35:13 wolti Exp $
    0 F1 P6 k  X, n9 H" L( ?. ~
  22. */; _- E$ y0 S' m- k, Q+ D
  23. 7 n# a4 i+ l* |- ]
  24. /* ----------------------- Platform includes --------------------------------*/; n' u8 ^. @. C- [6 P& M" q+ Y$ J
  25. #include "port.h"- U# s. D% r. X( c- h
  26. #include "modbus.h"% `9 q. F3 t% `. Z
  27. /* ----------------------- Modbus includes ----------------------------------*/
    ! H; F# `; [- Z
  28. #include "mb.h"1 q- c1 Z8 v- A* S- p
  29. #include "mbport.h"! ~) z# \& c( N1 x( E, @
  30. * F9 }9 a3 x& G8 y) {+ {
  31. /* ----------------------- static functions ---------------------------------*/- i' t. A; t1 j
  32. static void prvvTIMERExpiredISR( void );
    9 u- E: H  n  _! v% d6 |7 D

  33. , @6 q9 ]% H. g+ d  R, s% e4 ^
  34. /* ----------------------- Start implementation -----------------------------*/. I# m5 S- a( b
  35. BOOL  i4 [. p% H! X/ |( D$ ]0 K& T
  36. xMBPortTimersInit( USHORT usTim1Timerout50us )
    + f5 h) ~* Y+ l$ y  h+ G  z
  37. {
    9 p' g: Z& i6 x+ U$ D) U+ q8 Y
  38.         modbus_timer_init(usTim1Timerout50us);8 P0 r( a0 |. Z

  39. " K* s5 ^+ Z3 n7 X: F$ R7 I
  40.         return TRUE;+ P8 @: u% ^7 F/ @5 j
  41. }3 r4 q$ d8 ?% ^# V

  42. 5 n% @2 ^0 B6 E7 R3 L
  43. , {5 L8 B1 N$ t3 H4 d# `
  44. void! C, _0 {( ~( ]+ ^/ ~
  45. vMBPortTimersEnable(  ), E/ M& B! [- I% }' V! y1 `
  46. {
    0 x0 f# M7 l# y
  47.     /* Enable the timer with the timeout passed to xMBPortTimersInit( ) */! z& c4 Q: N8 ~+ V. N
  48.         TIM_ClearITPendingBit(TIM3, TIM_IT_Update);3 x  i% B* B$ l
  49.         TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE);
    - v5 W; F/ p/ T0 r6 ^
  50.         TIM_SetCounter(TIM3,0x0000); 1 n4 Z2 o/ j  v8 j
  51.         TIM_Cmd(TIM3, ENABLE);
    : Z- \& e9 `( E- f. F; i! V, L
  52. }
    3 M3 L& [1 M# K3 w

  53. 1 D; k2 v# `# a
  54. void+ _: z* M  x/ d: \
  55. vMBPortTimersDisable(  )
    - B8 Q$ N1 h1 J: [6 f: X9 m4 G
  56. {& n$ \6 [+ u9 k* w  ?/ e
  57.     /* Disable any pending timers. */% x7 m1 K( J/ r) H7 l7 p4 ~. |
  58.   TIM_ClearITPendingBit(TIM3, TIM_IT_Update);! w8 O1 K( d' O) Y, ~8 u0 P
  59.   TIM_ITConfig(TIM3, TIM_IT_Update, DISABLE);
    , M; D/ W5 E" S: l0 q
  60.   TIM_SetCounter(TIM3,0x0000);
    & |5 J  \# F" F- ^. w& `, w  a
  61.   TIM_Cmd(TIM3, DISABLE);
    2 I, x. f+ d" @6 U: C
  62. }. h4 A% W1 l2 \8 L& f2 D

  63. 5 G( \, H# D  G" I  c
  64. /* Create an ISR which is called whenever the timer has expired. This function
    # Z8 M: W2 @4 x; B2 S* S
  65. * must then call pxMBPortCBTimerExpired( ) to notify the protocol stack that
    1 U. U* X8 ]" Y: a! U2 P
  66. * the timer has expired.4 B1 _$ w" `. I, |( p5 ?" B
  67. */
    ; S5 v7 c- C5 w/ w4 Y
  68. static void prvvTIMERExpiredISR( void )0 ~: K9 c0 a. `: [  O
  69. {5 z8 p: ~( c: M
  70.     ( void )pxMBPortCBTimerExpired(  );+ O* q% N, {# n& L# @, ]
  71. }
    1 x: q% `, P1 Z% y1 s
  72. % z. s3 r& h9 T' G5 T& |( `
  73. void TIM3_IRQHandler(void)
    9 y" @9 i( r: l9 @7 i+ @* t
  74. {4 A  V6 ^2 \2 t3 ?( ]+ B
  75.         if(TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET)
    4 z! s/ ]4 f+ j& h. b
  76.         {
    " \5 b) K) U* c" L6 a  y+ W
  77.                 prvvTIMERExpiredISR();
    2 ?2 }. Z. c; `1 i7 t
  78.                 TIM_ClearITPendingBit(TIM3, TIM_IT_Update);! E2 Z+ U* S4 V# @+ p8 E" J* ~4 [
  79.         }
    5 ~( V% |; p5 P- t# X9 j* C/ y* y
  80. }
复制代码

4 |( V; _$ q9 D然后主函数中调用/ m2 \$ q0 x, a5 f/ n
! e5 a+ B1 D9 n! n$ ?; U

  1. 5 e) r7 |( f% h% U) g  p
  2. int main(void)
    2 r  _' ]6 t6 Z; d3 v( ^  A
  3. {               
    7 g7 j( O4 w4 C
  4.         delay_init();                     //延时函数初始化         
    9 r5 z% ^5 J) s+ N; v# a+ C
  5.         NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
    4 ?% Q, h# O  x' G# h& G) N
  6.         uart_init(115200);+ S/ b8 h$ M% V. `
  7.         eMBInit(MB_RTU, 0x01, 0x01, 9600, MB_PAR_NONE);
    4 o9 T" f+ x) F$ f
  8.         eMBEnable();  ( E, h8 j8 q5 T$ U- G
  9.          while(1)  ?  C2 z" y6 u* ]
  10.         {
      r5 e/ [. a: ^; I( M& t1 m! ?
  11.                 (void)eMBPoll();- y' {/ f& }% e9 h
  12.                 delay_ms(5);
    0 I6 `; `. V1 F% d, l
  13.                 0 l( U/ F. A! q7 `# P
  14.         }         
    3 k6 O1 _% N% m1 X2 L1 l
  15. }
复制代码

6 L; ]- f. f5 P, _7 ?4 }其次还要实现读线圈、写线圈、读离散输入、写保持寄存器、读保持寄存器、读输入寄存器等功能,如下:
7 t7 i+ A! ?7 K! L* B6 a% Q0 l
. n1 S0 D. E7 a
  1. #define REG_INPUT_START       0x0001        //输入寄存器起始地址. `0 z8 F/ J0 {, c" h
  2. #define REG_INPUT_NREGS       8                        //输入寄存器数量
    4 O* l5 ^" \/ K3 G* l
  3. ; P$ W7 d7 C9 _$ T( S: r9 K- R# _
  4. #define REG_HOLDING_START     0x0001        //保持寄存器起始地址
    + N2 n. _% X9 d' M4 x# D, x# e
  5. #define REG_HOLDING_NREGS     8                        //保持寄存器数量
    ; w" B* ?' B) F5 q9 P  P
  6. 0 Q  v" H, {# v; d) c7 H, O2 s
  7. #define REG_COILS_START       0x0001        //线圈起始地址7 T5 t9 j8 v, ~2 A
  8. #define REG_COILS_SIZE        16                        //线圈数量6 X6 ]" t4 _3 S8 \

  9. 2 ^& a# T1 p% b) g( L  E% q
  10. #define REG_DISCRETE_START    0x0001        //开关寄存器其实地址1 X! A" W; z8 x
  11. #define REG_DISCRETE_SIZE     16                        //开关寄存器数量- I) Z$ C) n8 Z/ @( Y! B2 h4 F
  12. //输入寄存器内容( V) w& x7 D! W' T
  13. uint16_t usRegInputBuf[REG_INPUT_NREGS] = {0x1000,0x1001,0x1002,0x1003,0x1004,0x1005,0x1006,0x1007};, j) [* L4 P" W
  14. //保持寄存器内容                # Z; e  K! `" [; _8 d0 ^
  15. uint16_t usRegHoldingBuf[REG_HOLDING_NREGS] = {0x2000,0x2001,0x2002,0x2003,0x2004,0x2005,0x2006,0x2007};                                       
    2 B' f; ~( x) U# y0 |
  16. //线圈状态3 V. R3 m+ u. L7 ]3 U1 k+ M; K8 n
  17. uint8_t ucRegCoilsBuf[REG_COILS_SIZE] = {0x01,0x01,0x00,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00};
    9 N# c9 E- q  C% Z
  18. //离散寄存器内容
    9 p5 l, ~0 O6 `2 n7 j. S
  19. uint8_t ucRegDiscreteBuf[REG_DISCRETE_SIZE] = {0x01,0x01,0x00,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x01}; , F; U! m" X( _, A

  20. * ]9 y0 k8 S" ]
  21. /****************************************************************************4 w& K( @1 o) u# Y9 V4 u  U
  22. * 名          称:eMBRegInputCB ) Q$ G2 Z, w5 M2 ]) v
  23. * 功    能:读取输入寄存器,对应功能码是 04 eMBFuncReadInputRegister4 t# ?+ ^( v# z+ s# V: w
  24. * 入口参数:pucRegBuffer: 数据缓存区,用于响应主机   ) W& ~" k1 v$ g" m8 @
  25. *                                                usAddress: 寄存器地址
    / g' g' T# k- \# M9 d
  26. *                                                usNRegs: 要读取的寄存器个数
    - q9 q& `* t  Q$ }$ s. H# G8 z$ Z8 G  j
  27. * 出口参数:( w/ h/ S, {- }! {/ p7 {
  28. * 注          意:上位机发来的 帧格式是: SlaveAddr(1 Byte)+FuncCode(1 Byte)! w0 z) K  O: Z+ A$ q
  29. *                                                                +StartAddrHiByte(1 Byte)+StartAddrLoByte(1 Byte)
    / t9 Q( z7 z1 }& ]( y+ t, J
  30. *                                                                +LenAddrHiByte(1 Byte)+LenAddrLoByte(1 Byte)+
    5 N  r; m6 m5 [7 V
  31. *                                                                +CRCAddrHiByte(1 Byte)+CRCAddrLoByte(1 Byte)
    * Y* \/ H  N, P  E: |. [! W" m0 v
  32. *                                                        3 区
    " x6 m8 [; f; z: \/ v
  33. ****************************************************************************/
    5 Y  k$ K6 [$ D. q1 y, M
  34. eMBErrorCode+ b/ d5 v! t, h8 r' K2 y
  35. eMBRegInputCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNRegs )
    / p& g" l% P1 K* y4 ~5 T
  36. {" s7 b- P. z+ p* N! P. t) u, t' s
  37.     eMBErrorCode    eStatus = MB_ENOERR;
    4 ?" I9 \, `( t/ K% z0 o
  38.     int             iRegIndex;
    0 j: L% y$ I- E+ ~  q2 m  g( `
  39. 9 c6 P. d, F) |) Z" J
  40.     if( ( usAddress >= REG_INPUT_START )
    : c+ T& l) E+ `  c' G6 \
  41.         && ( usAddress + usNRegs <= REG_INPUT_START + REG_INPUT_NREGS ) )1 e) m/ U0 Z7 I5 j& I5 Z0 |
  42.     {
    8 n2 W/ ~4 f; S, ~6 g9 N
  43.         iRegIndex = ( int )( usAddress - REG_INPUT_START );
    4 g% Y, w8 @' ~* T9 y8 b& y8 S* l& I
  44.         while( usNRegs > 0 )
    + @8 G  ]. j7 c( t5 f
  45.         {6 V# p$ P2 s0 c; F( M  h, |. d' M
  46.             *pucRegBuffer++ = ( UCHAR )( usRegInputBuf[iRegIndex] >> 8 );* A0 l- _% g$ @' E+ T  C
  47.             *pucRegBuffer++ = ( UCHAR )( usRegInputBuf[iRegIndex] & 0xFF );
    $ W9 r; C9 @  `
  48.             iRegIndex++;) I3 n7 _+ u1 S6 _8 o1 h* }& L: ?
  49.             usNRegs--;+ t! K" D% \" J: ?+ Y4 X: f2 f
  50.         }
    7 q. _( K' j3 Z% [9 f0 C! G1 B/ ^
  51.     }
    , w! h0 `$ t: h8 i+ U# ?
  52.     else
    0 p1 W% N8 q! G% X4 N+ X5 ?
  53.     {" p! E5 g) q. b: M+ }
  54.         eStatus = MB_ENOREG;
    " d+ q: Y* ?( d/ d$ _5 Z& B
  55.     }
    & I7 `& P3 n0 o$ W( [( O

  56. ; u  s, ?( d2 y$ j4 L
  57.     return eStatus;, X$ S* h$ B: F8 f) t
  58. }
    + I* T2 x- I9 r8 D6 Q/ j

  59. 3 n, Y9 d) r- r& D/ ?7 v5 h
  60. /****************************************************************************" p- M: L  e* ]4 j, @, h
  61. * 名          称:eMBRegHoldingCB
    0 G% q8 a1 a/ o4 J2 j% ?
  62. * 功    能:对应功能码有:06 写保持寄存器 eMBFuncWriteHoldingRegister
    & ]8 ^! }8 h0 v2 g7 g! M  t* K7 [
  63. *                                                                                                        16 写多个保持寄存器 eMBFuncWriteMultipleHoldingRegister
    * K9 v# C9 k2 d) f3 M
  64. *                                                                                                        03 读保持寄存器 eMBFuncReadHoldingRegister% n7 V2 t. U5 r! I
  65. *                                                                                                        23 读写多个保持寄存器 eMBFuncReadWriteMultipleHoldingRegister
    . o6 n& O8 R7 w/ {% k2 Q
  66. * 入口参数:pucRegBuffer: 数据缓存区,用于响应主机   
    : [: L1 b& g9 H5 }6 i
  67. *                                                usAddress: 寄存器地址! M2 o4 M0 v% k) y* x1 e2 C4 f
  68. *                                                usNRegs: 要读写的寄存器个数
    6 ]6 `7 K) ]' k# a: _
  69. *                                                eMode: 功能码  H! b% t2 H- V
  70. * 出口参数:
    8 x" E. c- Z- `) a' m
  71. * 注          意:4 区# i; k4 T' w$ `& h
  72. ****************************************************************************/& f5 b3 Q3 A7 E6 ]
  73. eMBErrorCode( a/ G( d! u, Y+ ~/ R- _3 j
  74. eMBRegHoldingCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNRegs, eMBRegisterMode eMode )' O- @8 d* G, ~& D* e. y  ^
  75. {( d  t8 @% J- R1 `' f
  76.         eMBErrorCode    eStatus = MB_ENOERR;, O/ ?' j. P0 V* {7 J: P
  77.         int             iRegIndex;8 @# l3 U' U% O( h3 }% |" m

  78. / c: a) G* w5 }1 p
  79. % N8 v9 n6 {9 C! Z! R" @: |# _
  80.         if((usAddress >= REG_HOLDING_START)&&\
    % \1 }1 B" Z% L2 b  K% W
  81.                 ((usAddress+usNRegs) <= (REG_HOLDING_START + REG_HOLDING_NREGS)))
    8 e$ i$ ~9 p5 S; z* d5 v
  82.         {" Y* ]) h+ z9 U1 C, I' {4 o
  83.                 iRegIndex = (int)(usAddress - REG_HOLDING_START);$ Q- o$ o: i! X: }+ d+ z
  84.                 switch(eMode)$ Y3 L( z5 q5 q( N' d
  85.                 {                                       $ L& W( ]0 t- u
  86.                         case MB_REG_READ://读 MB_REG_READ = 0
      ?* [; ~9 |" c' M1 m4 N' t
  87.                                 while(usNRegs > 0)
    ) ]$ D4 a. G* X
  88.                                 {
    * F0 P6 F/ I) l: ?) j6 D8 X
  89.                                         *pucRegBuffer++ = (u8)(usRegHoldingBuf[iRegIndex] >> 8);            
    " h4 Z9 T3 ?7 k' u; g8 j. @
  90.                                         *pucRegBuffer++ = (u8)(usRegHoldingBuf[iRegIndex] & 0xFF); * E: e0 [9 g# K; j
  91.                                         iRegIndex++;
    . e+ P9 o# K, n5 ]$ Z8 i9 [# i# i
  92.                                         usNRegs--;                                        % t# n2 ?+ Z7 ?6 }; j2 Z) K
  93.                                 }                           
    5 v2 Q. X& f; W8 K. `3 h4 @
  94.                         break;8 x* }# g+ _; Q# U
  95.                         case MB_REG_WRITE://写 MB_REG_WRITE = 0
    6 N# L1 R* n6 b( w& m' M5 x+ c
  96.                                 while(usNRegs > 0)
    6 H# W: Q" R# X) i1 L, b' P. W
  97.                                 {         7 l) |* C# ]2 ]8 o" d2 s' W
  98.                                         usRegHoldingBuf[iRegIndex] = *pucRegBuffer++ << 8;; K( {% I, a( L4 @9 @6 Z6 N
  99.                                         usRegHoldingBuf[iRegIndex] |= *pucRegBuffer++;; k  r1 y; D" C3 o" z7 K& Y
  100.                                         iRegIndex++;
    % [( h9 x; i- t% A0 [( ^, x$ L
  101.                                         usNRegs--;$ X( y4 [# z) y( t
  102.                                 }
    5 E9 V8 E' K/ m6 w7 @' W( l6 L8 f
  103.                         break;                                & ]& ~' ~- e. u1 o# `& a
  104.                 }/ T# f% T2 T+ p
  105.         }* S1 Y' w4 {, l% m* F3 U
  106.         else//错误
    ( y  I. r4 G/ R; h/ f. X* o( _
  107.         {* r( ^* k( {7 z, @7 f0 Q& r
  108.                 eStatus = MB_ENOREG;5 h/ S. r0 g! b) ^! X# i* i
  109.         }        
    * n, Q9 F$ i$ F# H
  110.         
    * X7 E; M! t, l" O# m- e
  111.         return eStatus;/ I: ]3 K6 S/ B7 I$ L
  112. }! p' H2 d2 O* o
  113. ) t$ N3 i! B$ C7 O; q6 P7 `. Y
  114. /****************************************************************************
    ( t  f5 f8 v! J' d3 ]' g9 s/ d
  115. * 名          称:eMBRegCoilsCB 5 [7 ~* m! w( ?, ^
  116. * 功    能:对应功能码有:01 读线圈 eMBFuncReadCoils
    3 o" X9 }1 y2 |& f
  117. *                                                  05 写线圈 eMBFuncWriteCoil2 Z' N" K& k" D( M0 j. J* e
  118. *                                                  15 写多个线圈 eMBFuncWriteMultipleCoils
    ' P% l; ]# X9 X/ r; Z
  119. * 入口参数:pucRegBuffer: 数据缓存区,用于响应主机   
    4 e/ _$ P! Y  c# N$ M( k' t
  120. *                                                usAddress: 线圈地址0 L0 p' e3 f: C0 L
  121. *                                                usNCoils: 要读写的线圈个数6 T  O+ l7 ?1 W5 m) H
  122. *                                                eMode: 功能码
    , V4 s1 U+ {# z1 \/ A* W% L* q3 S
  123. * 出口参数:
    ' u, {6 F( v* Z* _+ r* y0 f! t/ i
  124. * 注          意:如继电器
    ; E- Y3 r& @/ t# ]9 F
  125. *                                                0 区3 _# n$ Q0 ~4 ^) T
  126. ****************************************************************************/
    6 D" Z, v9 q% L* M- e( a
  127. eMBErrorCode
    # [2 E* v  _8 \3 z9 N
  128. eMBRegCoilsCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNCoils, eMBRegisterMode eMode )4 X% K; A; k3 t: ~. B5 ]
  129. {
    # P; b, u$ C( A
  130.         eMBErrorCode    eStatus = MB_ENOERR;( W( c: N. v" l5 |6 X
  131.         int             iRegIndex;. {7 J+ n* |4 F" |9 _; ?
  132.         u8 i;
    9 U2 P4 i3 M/ u8 O- X" D! `
  133.         USHORT readNumber=usNCoils;
    9 _3 D, x8 X# ?3 T& W
  134.         USHORT coilValue=0x0000;
    8 [- U9 f0 Y0 K& ?8 y8 Z1 R
  135.         if((usAddress >= REG_COILS_START)&&\
    " _# |1 @; _+ m3 |3 R
  136.         ((usAddress+usNCoils) <= (REG_COILS_START + REG_COILS_SIZE)))6 d. g' @7 L+ y6 u) ^
  137.         {$ P; _& H- x* E& Y8 c! g
  138.                 iRegIndex = (int)(usAddress + usNCoils-REG_COILS_START);
    $ E8 T' G6 P  u0 P* e2 ]/ N9 C
  139.                 switch(eMode)! H  w* l" ~: u  E5 o4 H; D
  140.                 {                                       
    9 k9 ]8 L' ]- n
  141.                         case MB_REG_READ://读 MB_REG_READ = 0
    " c; _4 {2 r+ E7 u4 a
  142.                                 for(i=0;i<usNCoils;i++)+ R% F, L- u5 n9 Y" `
  143.                                 {
    / K5 d! M9 f# r2 X9 N( h4 P( H! ^
  144.                                         readNumber--;9 I# X& Z4 R" Q6 w
  145.                                         iRegIndex--;, P2 J, j  k( G9 e3 j4 U0 e: r
  146.                                         coilValue|=ucRegCoilsBuf[iRegIndex]<<readNumber;
    % ^/ w% F7 l5 r" z- K# h- ?
  147.                                 }
    / n3 b, M& m1 n! I5 S
  148.                                 if(usNCoils<=8)
    " q4 K- N& i: `
  149.                                 {
    7 d2 H! a; A6 K
  150.                                         * pucRegBuffer=coilValue;
    ) R/ D" ~9 k5 ~  L! y( Y
  151.                                 }9 k9 {2 p% D3 ?( ]  w0 ~- @
  152.                                 else
    / L& e2 J4 W3 k: A  J( W
  153.                                 {7 w; z- B. r# g' h( z
  154.                                         * pucRegBuffer++ = (coilValue)&0x00ff;9 Y, C* K2 `" E, o- ^; D) \% I
  155.                                         * pucRegBuffer++ = (coilValue>>8)&0x00ff;
    ! r& f) Q, a$ c: w! y( R# a9 ?; ^
  156.                                 }! C' K1 w$ D6 q5 G2 ]
  157.                         break;                            * _8 N5 I$ y) I/ R+ j1 M
  158.                         case MB_REG_WRITE://写 MB_REG_WRITE = 1
    9 o) a9 r6 u) C$ g
  159.                                 while(usNCoils > 0)1 A9 K0 `5 E8 H* Z* S" K. l: c
  160.                                 {         
    # M! B; V3 O. Q) U6 B
  161.                                         //                         usRegHoldingBuf[iRegIndex] = *pucRegBuffer++ << 8;
    3 I( f# L8 g' |
  162.                                         //           usRegHoldingBuf[iRegIndex] |= *pucRegBuffer++;. p2 n+ ?$ ]( B) i$ p& G- I0 q
  163.                                                 iRegIndex++;
    $ f8 _) n+ p1 F  u9 K' P+ p" U
  164.                                                 usNCoils--;
    ' q; h1 M5 a% I
  165.                                 }
    0 y8 j4 ^3 q* C8 I
  166.                         break;2 \+ i( s! M) e$ a9 [2 H1 Z1 K* G
  167.                 }+ h/ Q! O1 t+ q1 R3 }
  168.         }
    ) j6 m4 f( W; p, ~# m
  169.         else//错误
    - K4 N3 Y3 c' `1 g3 H. [; F% T
  170.         {
    : ^' W; H% d7 p5 J) O
  171.                 eStatus = MB_ENOREG;4 Z" \% X1 ?: V, j3 Q
  172.         }        
    * P& G: a2 }2 I7 ?) k* v
  173. 5 O; d1 ^3 Q+ R* j
  174.         return eStatus;
    . i& R! ^4 v( P4 I6 l0 g  ^
  175. }# s* t5 r( D+ `( e1 |: C- i4 w; C
  176. /****************************************************************************: l/ E4 {3 o' S. R/ C# @! W7 r
  177. * 名          称:eMBRegDiscreteCB ) B: c  d5 E' x0 \& L
  178. * 功    能:读取离散寄存器,对应功能码有:02 读离散寄存器 eMBFuncReadDiscreteInputs
    : j) B3 p% W. p2 n% h
  179. * 入口参数:pucRegBuffer: 数据缓存区,用于响应主机   4 ^, R' @, [3 ^7 l- z( g
  180. *                                                usAddress: 寄存器地址$ ~) x0 M* D+ O5 R6 _
  181. *                                                usNDiscrete: 要读取的寄存器个数
    - |4 n6 H5 [6 r
  182. * 出口参数:
    * ?# N0 Z; y6 n8 |& A& D/ _8 {
  183. * 注          意:1 区1 s5 d, ]7 p9 V/ L) v, h  i0 T
  184. ****************************************************************************/- z7 |5 J6 U) v3 [
  185. eMBErrorCode- e' m/ J6 \, |. d' _8 r
  186. eMBRegDiscreteCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNDiscrete )
    ( q7 p1 `$ E* v! j2 j8 x- }
  187. {
    . Q, y6 a, [+ x/ E+ q" n3 J
  188.         eMBErrorCode    eStatus = MB_ENOERR;5 V  i; y$ j' t
  189.         int             iRegIndex;8 y$ |/ t' p  f8 {
  190.         u8 i;1 l' d- h2 ~' V- c8 @% y7 `
  191.         USHORT readNumber=usNDiscrete;) B: A, K% u, s' k4 E$ L% k% q
  192.         USHORT coilValue=0x0000;
    / ^# v/ V# `! E' C5 a- h/ k; m7 m
  193.         iRegIndex = (int)(usAddress + usNDiscrete-REG_DISCRETE_START);
    6 x2 j1 m7 D* S: j- r# _% W
  194.         if((usAddress >= REG_DISCRETE_START)&&\
    5 J& U6 q: ]- h
  195.         ((usAddress+usNDiscrete) <= (REG_DISCRETE_START + REG_DISCRETE_SIZE)))  m0 [2 n/ Z) C6 p* X. m$ Z
  196.         {( E2 \/ ~7 u% D% k
  197.                 for(i=0;i<usNDiscrete;i++)* Z+ W8 k7 Y/ I" A1 K4 g
  198.                 {
    ! [" g0 X% n6 D  ?! U
  199.                         readNumber--;
    ) _5 v, F. H! y4 v  S! Q* v9 Z
  200.                         iRegIndex--;
    - q/ \5 C6 c; Z2 F' h' o
  201.                         coilValue|=ucRegDiscreteBuf[iRegIndex]<<readNumber;
    / t  Q- a5 d% O! }: ~! b4 |; P
  202.                 }* l  u* D1 W( W/ }9 y) ?5 j
  203.                 if(usNDiscrete<=8)8 v3 O' }$ c4 N' O4 V- v4 ^4 U+ y
  204.                 {' j) V5 _6 S' ]. z
  205.                         * pucRegBuffer=coilValue;/ l# Z9 o+ W7 n( h
  206.                 }- A) o5 k* e$ i- Y- y/ n
  207.                 else
      `/ o, p- V2 R; k6 ]8 {; x
  208.                 {
    9 N7 N  I) c- M) c! f
  209.                         * pucRegBuffer++ = (coilValue)&0x00ff;
    2 V& ^$ [2 v5 a9 f
  210.                         * pucRegBuffer++ = (coilValue>>8)&0x00ff;
    9 ?7 e- ^( [4 A# b
  211.                 }; x; ?: k* e0 Z, e
  212.         }6 \, g* {2 ^8 Q. S! `5 d7 x. C
  213.         else
    4 e, x/ R# @/ C/ o9 v5 @, m$ y# H
  214.         {7 n- P& E* J+ P8 j8 a0 e, J  U
  215.                 eStatus = MB_ENOREG;9 f8 T+ V7 A* Z  [( \" E6 t
  216.         }5 g- R% [' {. Q+ Y6 ]% d
  217.     return eStatus;
    ( W5 W' M. f; @- Y
  218. }: E9 n- P5 u9 f$ X* T( @" g6 _2 c
  219. % B2 ?5 q$ n% C0 Q% }
  220. 4 E7 V8 r, `9 ^/ Y0 b+ I- _

  221. 6 T& \2 a' J5 u) W- c7 L! D
  222. 3 E+ R- V) ]5 ^8 P
复制代码
0 T: A: c, @8 n0 a0 L- \

+ Q1 D) @5 j/ ]8 N% D& C
# @4 c" w9 x7 {* X' S
收藏 评论0 发布时间:2022-4-23 15:41

举报

0个回答

所属标签

相似分享

官网相关资源

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