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

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

[复制链接]
STMCU小助手 发布时间:2022-4-23 15:41
首先将FreeModbus移植到自己工程中,如下图所示:
5 H4 _  D6 F4 j. K4 K4 h 20200323104757628.png
0 b' J0 t9 l( I* f+ B1 R1 y. H( M8 D% }1 R. P
然后修改portserial.c和porttimer.c文件:# Y: f7 _9 ~0 i) \- S
portserial.c
( Y. m& [' w6 w& O" E, o
+ @% P% s" r" c& q1 J+ s! U
  1. /*. g4 Q+ d  O8 i% y. n. e
  2. * FreeModbus Libary: BARE Port; V# \) Y9 _4 P  h# a* S8 u
  3. * Copyright (C) 2006 Christian Walter
    # H1 ]) C- ]# M# l# i
  4. *4 {* G% `8 m- |1 o: g
  5. * This library is free software; you can redistribute it and/or& s) n- W! k6 L
  6. * modify it under the terms of the GNU Lesser General Public
    + U( |* J+ B5 a% b% u( a
  7. * License as published by the Free Software Foundation; either6 M, a$ `4 I8 g1 F* Z
  8. * version 2.1 of the License, or (at your option) any later version.
    5 q& ]0 O- o' B. K
  9. *
    5 {. r; m3 t  g: W$ d% ]; R2 Z
  10. * This library is distributed in the hope that it will be useful,
    0 d# a3 n' H' M% x3 Z+ D
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
    , j" {4 s/ b' t- U/ z) {2 c
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU; L* y+ k9 t8 R& w0 p
  13. * Lesser General Public License for more details.; M! @0 K, E" p0 _+ ^
  14. *
    , i& @; B0 ^, O9 e
  15. * You should have received a copy of the GNU Lesser General Public
    $ ^4 I8 Q6 C: v- ~
  16. * License along with this library; if not, write to the Free Software
    6 X* Z# b* ?! B* @& M: `
  17. * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
    " ~4 ]' N  `7 `
  18. *
    / I. @% |& }! i: T- F+ a
  19. * File: $Id: portserial.c,v 1.1 2006/08/22 21:35:13 wolti Exp $( }! Y0 d5 M0 V6 D( Y' K' O4 a. ~
  20. */
    9 Q1 f' F% X- t3 D& b% p

  21. $ }8 M; G8 e# v0 U4 U3 D+ f- h# e
  22. #include "port.h"+ {0 _# \( ^- S2 X& J
  23. #include "stm32f10x.h"
    ) K2 Q& E3 h, L7 m
  24. #include "modbus.h") p4 i# y0 h# h2 g8 P$ d" G# h  j
  25. /* ----------------------- Modbus includes ----------------------------------*/
    % y6 Y; j* i- Y& ?- P, c6 f
  26. #include "mb.h": u% s# D9 u7 T
  27. #include "mbport.h"
    3 e  P; R+ k8 `0 ?0 S: P) ?

  28. 5 [; T8 ~0 D, z# r
  29. /* ----------------------- static functions ---------------------------------*/$ T; C& _) V" K2 p0 s: u
  30. static void prvvUARTTxReadyISR( void );
    % r$ C, [% y1 w
  31. static void prvvUARTRxISR( void );) _2 ]+ Z! q' ^$ b3 V2 s
  32. ! v7 [; P- ]1 j/ O7 A7 H
  33. /* ----------------------- Start implementation -----------------------------*/
    8 D5 f' A) U( T  f3 u9 X
  34. void7 Q# _9 _$ ]) L4 _+ X
  35. vMBPortSerialEnable( BOOL xRxEnable, BOOL xTxEnable )! A" }1 P6 D, H& K
  36. {
    ! O* n/ N& [% g$ W
  37.     /* If xRXEnable enable serial receive interrupts. If xTxENable enable, P" P+ C% l% Z' S3 Z
  38.      * transmitter empty interrupts.1 S9 u0 [" K7 M: v
  39.      */' ]- y; m# }4 Z# b9 n# D: ^8 L- D
  40.         if(xRxEnable == TRUE); [( X4 y# U" ~+ X% N4 k
  41.         {
    7 {% u' |: k6 P# e, [6 M# B
  42.                 USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);
    8 s- E0 P; H/ n" w6 L* s7 Q9 N; ~
  43.         }
    2 T) k& ~& p% u+ \* `: }. P
  44.         else' ^( X5 {. W7 y
  45.         {% J3 U$ ^* ^5 B, I8 a
  46.                 USART_ITConfig(USART2, USART_IT_RXNE, DISABLE);3 L; ~6 f# U0 F" B6 I4 Z
  47.         }0 x3 v0 ~& u; _, N) _
  48.         
    ( Z4 [$ t' W, y/ D) F
  49.         if(xTxEnable == TRUE)
    ! q% y  h( S$ @1 S& o9 `* c
  50.         {+ V: R& X1 J' ?' W4 n
  51.                 USART_ITConfig(USART2, USART_IT_TC, ENABLE);2 m/ ?1 ~8 O- g
  52.         }
    * X/ B: y. W4 `  X
  53.         else
      R9 e: v1 y2 e/ m
  54.         {
    5 {; G* ^' W- d% q' r% x0 H
  55.                 USART_ITConfig(USART2, USART_IT_TC, DISABLE);( R& [0 v" X/ l; `# d1 w. \3 K8 @
  56.         }1 c. Z8 v3 `: o
  57. }- y2 E, H- ]( i1 Y2 s( ~" o

  58. 0 r) n( w0 P; u4 V, Z
  59. BOOL" N( k) f) J  h* y2 T) k/ I$ _
  60. xMBPortSerialInit( UCHAR ucPORT, ULONG ulBaudRate, UCHAR ucDataBits, eMBParity eParity )
    + Z; S3 |, h) g1 [, L# M$ Y
  61. {
    8 I, W9 K5 R% [' Y
  62.         modbus_uart_init((uint16_t)ulBaudRate);  1 p  {6 n  t- T! g  `7 P9 }

  63. ! a+ u" m& N' t9 [8 n
  64.         return TRUE;
    & z8 M; h: G+ q0 w: Q1 B
  65. }
    3 p. O" @) r7 K6 R9 Y- U

  66. % \8 s" {/ V' H: a8 f8 ]
  67. BOOL
    * b$ T& u5 X: G8 w/ e. e
  68. xMBPortSerialPutByte( CHAR ucByte )! R+ O: w+ C. @1 u- _% b
  69. {# {  y' x1 Y) Q- P
  70.     /* Put a byte in the UARTs transmit buffer. This function is called; g3 T9 _* _3 m
  71.      * by the protocol stack if pxMBFrameCBTransmitterEmpty( ) has been
    * O- h7 {0 E5 {! e9 e7 P8 e
  72.      * called. */
    . o5 X  Q! v9 _1 s0 }
  73.         
    ; f  a2 ]. T# }& _( B
  74.         USART_SendData(USART2, ucByte);
    3 T# K- p: k4 _6 R# k; r4 O
  75.     return TRUE;& y( F9 {7 Y8 B- P1 u8 ]8 S
  76. }
    - d/ J0 X4 k2 }4 e9 h1 {. r* u
  77. $ @) u& k. B4 J& l  {2 E3 A, Y
  78. BOOL$ q5 X+ j: ^! |% C8 W6 d8 a
  79. xMBPortSerialGetByte( CHAR * pucByte )0 F, x2 H1 W/ _1 g  ~7 N
  80. {3 j* n) B$ a1 a
  81.     /* Return the byte in the UARTs receive buffer. This function is called  U+ r' x! _; m  O$ t( F
  82.      * by the protocol stack after pxMBFrameCBByteReceived( ) has been called.% |- Q$ l* R2 ^4 a* c% _& @
  83.      */
    . }% h0 ^/ m8 {. J" h
  84.   *pucByte = USART_ReceiveData(USART2); ( D$ N. T$ r0 t* e
  85.         return TRUE;
    $ A4 b& ?. _. t% r; U/ L3 S
  86. }/ d% Q! W8 L6 `+ C

  87. 7 @1 I& z2 R( D" P& H! x
  88. /* Create an interrupt handler for the transmit buffer empty interrupt
    8 ?* V5 A& K5 e! u! x
  89. * (or an equivalent) for your target processor. This function should then' w& l2 G, x7 s! q: \; o6 V
  90. * call pxMBFrameCBTransmitterEmpty( ) which tells the protocol stack that
    " w% e- Q3 v5 Y" M
  91. * a new character can be sent. The protocol stack will then call + p. x, B) }+ j4 P" m- `
  92. * xMBPortSerialPutByte( ) to send the character.5 D9 u( p( Y: `) I0 ]& u, O3 e
  93. */
    # ?& T% ~6 X1 {4 O
  94. static void prvvUARTTxReadyISR( void )# S2 L& |0 L3 ?) Y
  95. {
    1 F4 A4 O  S# W- q  l  n& _7 R2 @6 k% m
  96.     pxMBFrameCBTransmitterEmpty(  );
    , B" f' f2 N5 w; W* y
  97. }
      q# A# h$ n  k! r( q* M
  98. 6 `$ Q$ ?, W# Z% z- W+ q5 F. K
  99. /* Create an interrupt handler for the receive interrupt for your target
    % L  M' l( O2 T' Q* c% p" ?- S
  100. * processor. This function should then call pxMBFrameCBByteReceived( ). The7 f& s, W* P' B7 w8 z
  101. * protocol stack will then call xMBPortSerialGetByte( ) to retrieve the
    + C5 J1 }$ \" }. B
  102. * character.* r& a3 I. `; R
  103. */, T. W" |/ T  z) f4 K) \' @
  104. static void prvvUARTRxISR( void ), f# F! K8 o" @; a1 k$ A% k
  105. {
    7 |' d# e+ d9 Q/ w
  106.     pxMBFrameCBByteReceived(  );1 G* Z5 e$ L% B
  107. }5 X, |9 o3 ]0 `% I

  108. , A# a( C- @* h2 |2 m! G" l
  109. /**
    : {# ?/ W; b$ n6 ~6 }
  110.   * @brief  This function handles usart1 Handler.% ^1 m3 a6 A" Q- O. D! B
  111.   * @param  None( B) V5 J' B& i, P8 U: {
  112.   * @retval None' d. H6 N1 P3 \! r* r  p1 v8 X
  113.   */
    % Z; }! ]* I! k2 g8 j
  114. void USART2_IRQHandler(void)
    ( O) o+ L# n0 E( _  _4 T
  115. {; f. ~  u# b) z" r" w/ S
  116.         //发生接收中断( l/ ^4 f8 D4 ?" m) Y
  117.         if(USART_GetITStatus(USART2, USART_IT_RXNE) == SET)
    & p' p' J( T) e, N0 s( k
  118.         {
    0 T3 J1 d8 h3 }* C9 q
  119.                 prvvUARTRxISR();
    1 o+ J5 `6 w* s- _
  120.                 //清除中断标志位    ' a& H* ?% q+ a1 g/ l2 [5 p
  121.                 USART_ClearITPendingBit(USART2, USART_IT_RXNE);   5 S& l+ U7 a7 a5 W* g+ A
  122.         }9 Z2 Z# m6 V9 h* o& B* H2 R

  123. * O) Z; n/ n0 M" G+ F6 T: _0 n
  124.         if(USART_GetITStatus(USART2, USART_IT_ORE) == SET)2 T7 e* \3 {2 ]  @' k2 ]+ y
  125.         {  8 a; l# D" f" i% h: B
  126.                 USART_ClearITPendingBit(USART2, USART_IT_ORE);
    4 @3 r! t1 O4 I! a  r
  127.                 prvvUARTRxISR();           `- c- {& m6 b$ r7 u
  128.         }
    7 W( R9 b: @! g) B: D6 V- B2 j" v
  129. & x" U( j+ E0 f3 ?
  130.         //发生完成中断
    & m3 f2 z1 I! ]6 W
  131.         if(USART_GetITStatus(USART2, USART_IT_TC) == SET)# c( m0 Y7 w0 u( I$ b3 i! @, d
  132.         {4 ^/ V; {4 B8 c; ^5 p  F
  133.                 prvvUARTTxReadyISR();) t# M9 j/ k4 J7 l
  134.                 //清除中断标志+ v* F* ?  F3 h) r! |9 o
  135.                 USART_ClearITPendingBit(USART2, USART_IT_TC);
    % ^: q& y" U* ^5 U4 b! g
  136.         }$ o6 u' z$ k# P9 z6 `" C
  137. }
    - c% K* J( q2 Q2 i/ u
复制代码
7 @) F9 ~" s; T7 y3 p
porttimer.c
+ [6 d# ^( J) F2 z
$ S: N+ X) T7 k$ X" x) h
  1. + F' j5 T$ x0 Z+ e; d2 ^
  2. ```c
    - H6 O' e$ }  d- N4 w, z! M% C' c
  3. /*- U8 I# y( Q5 f' `
  4. * FreeModbus Libary: BARE Port8 T0 n' M% ^+ `1 P
  5. * Copyright (C) 2006 Christian Walter <<a href="mailto:wolti@sil.at">wolti@sil.at</a>>3 o% h* D8 X9 a* i8 d) E
  6. *. O+ u* }8 q4 f" O& w0 R* A) l
  7. * This library is free software; you can redistribute it and/or
    + W' i( ]% W2 s9 E/ j9 D/ e
  8. * modify it under the terms of the GNU Lesser General Public
    , S+ I/ F& w* l, ~
  9. * License as published by the Free Software Foundation; either
    + _5 \; m7 T5 Y# P
  10. * version 2.1 of the License, or (at your option) any later version.) v1 t. a" D6 B: v+ R+ t  T( M7 o7 Q& ^
  11. *' T* u3 k- O  L% v6 _
  12. * This library is distributed in the hope that it will be useful,
    + `$ R8 I: h' Q8 x
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of& m# L9 e% P( T4 h" R
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    ) P' t$ v+ b4 N
  15. * Lesser General Public License for more details.3 ~3 B) ]. d9 X3 P: C) ~
  16. *
    % b3 N; q* f! j' J" T
  17. * You should have received a copy of the GNU Lesser General Public
    % E8 _3 p2 w+ r+ [4 H/ P
  18. * License along with this library; if not, write to the Free Software( C& C- V8 |5 s3 L6 n) F4 u& P& \
  19. * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA1 Z3 K" }  M! A. t
  20. *4 |  C3 q4 u6 `9 R; w4 E* J
  21. * File: $Id: porttimer.c,v 1.1 2006/08/22 21:35:13 wolti Exp $
    8 D  u, X* w( B: f# E0 `
  22. */% s7 ]! {. @$ [" `, |* V1 \' w

  23.   w4 K) s. b# u$ L  x3 C
  24. /* ----------------------- Platform includes --------------------------------*/8 x9 H# e. q. H( W0 _
  25. #include "port.h"
    - f) K3 Z9 @! n/ u9 O
  26. #include "modbus.h"
    ) m0 S( N% @; v/ {; ~8 F5 b
  27. /* ----------------------- Modbus includes ----------------------------------*/5 U( \  m7 ^3 V$ ^6 [, S9 d
  28. #include "mb.h"
    2 ]& o1 l. ^% w! d6 |' `
  29. #include "mbport.h"
    9 J( A/ b0 {( i3 q) }" A
  30. 0 \& _( T- t; g% A1 q, z
  31. /* ----------------------- static functions ---------------------------------*/
    . L% N% L5 T" z  D; l. y/ H, g
  32. static void prvvTIMERExpiredISR( void );+ ?3 J' Y$ ]' D
  33. / Y# z) y6 w/ t
  34. /* ----------------------- Start implementation -----------------------------*/
    - a" j, v) C# A. z% U0 s
  35. BOOL
    ; h0 D/ C1 B5 V
  36. xMBPortTimersInit( USHORT usTim1Timerout50us )/ f# N# N$ P( `1 j7 \+ t, C# g- N
  37. {
    , R: v' ^' t* t& D+ L0 x
  38.         modbus_timer_init(usTim1Timerout50us);
    : E/ ?: m4 I$ L% o% n7 n3 [( u

  39. ( O7 W: U% ?5 T5 F. h8 Q
  40.         return TRUE;
    % ?" `+ T+ h9 [- X0 l, C
  41. }5 P9 t5 c0 m2 q1 E2 y- v2 W& Y2 H

  42. ' [* A6 V8 E/ N

  43. * A2 K5 E, K7 x' f
  44. void: _. B/ L0 q0 \9 U$ j
  45. vMBPortTimersEnable(  )4 w" u4 @: B. s; I2 l# b# W# Y3 ]7 g
  46. {- k3 y' ~( Z2 {% s: D
  47.     /* Enable the timer with the timeout passed to xMBPortTimersInit( ) */, F* z8 ^: E/ H2 J/ |  m7 u+ u6 e
  48.         TIM_ClearITPendingBit(TIM3, TIM_IT_Update);
    + P) U+ Q" x7 B$ n
  49.         TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE);7 J2 L: ~2 C5 v( m6 m$ f
  50.         TIM_SetCounter(TIM3,0x0000); ) C7 T, z5 j2 y6 u7 x; B4 f
  51.         TIM_Cmd(TIM3, ENABLE);& U/ v, K/ V/ d6 G' n0 Z$ Z7 G4 V3 y
  52. }; I' k8 Y1 s/ R9 q+ p/ i

  53. 9 W+ K( T0 x1 V9 x+ B8 B
  54. void
    + C5 o5 H" U3 e; ~
  55. vMBPortTimersDisable(  )
    + X. v& [- R, v! s5 \6 |( I& b' V( t
  56. {. C* `5 c/ r1 s# ]( r
  57.     /* Disable any pending timers. */
    ; m  O: t( G) X
  58.   TIM_ClearITPendingBit(TIM3, TIM_IT_Update);
    4 B4 U3 o6 x3 B" h
  59.   TIM_ITConfig(TIM3, TIM_IT_Update, DISABLE);0 @$ ]8 @; P3 f6 f
  60.   TIM_SetCounter(TIM3,0x0000); 1 A4 x$ a1 q& u" V1 T
  61.   TIM_Cmd(TIM3, DISABLE);
    8 O) M, w. G+ F5 ?; \
  62. }' o/ V& x" x! w8 H7 ^* F7 J
  63. * P: W; P/ K  Q% I8 ^8 ?
  64. /* Create an ISR which is called whenever the timer has expired. This function, w& O4 |; u* e9 w! ~% u
  65. * must then call pxMBPortCBTimerExpired( ) to notify the protocol stack that0 k! ~; }) z  S- K
  66. * the timer has expired.& ]* G2 v$ Y- y1 J% Z, l8 x5 G
  67. */
    $ V1 R0 g- {" N' V' O9 o. q0 l+ U
  68. static void prvvTIMERExpiredISR( void )& M7 \& U2 V! d1 ?9 L9 W' X0 Z& A
  69. {8 G+ l2 t/ a! [, q# A3 ]' s
  70.     ( void )pxMBPortCBTimerExpired(  );
    ) K& w; e3 ]/ O; S
  71. }
      u' q) B; C2 e' V

  72. 4 P1 i( e$ Z3 R% f
  73. void TIM3_IRQHandler(void)
    * R: d7 w% U8 N. q
  74. {
    ' @- k; `( e; D$ [+ c* p
  75.         if(TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET)
    ( S/ G0 _) i  ^# ~0 w
  76.         {" m+ N6 _# w# o$ @# h# T
  77.                 prvvTIMERExpiredISR();2 Y  ]4 e3 w( ]& [
  78.                 TIM_ClearITPendingBit(TIM3, TIM_IT_Update);
    / l& Y+ \$ M- ^4 j# l3 z2 ]
  79.         }
    / O/ E+ `* N* |! Z- o/ a4 R
  80. }
复制代码

) w* [# @% |8 i; R* G( O然后主函数中调用4 U& d5 m4 ]; h6 o) o" U) W1 ]: A* G
( ^, h$ Q4 Q4 P: }+ {5 |
  1. , L. G9 \7 Q5 b" T
  2. int main(void)- V3 B% i2 u8 Z. }# r% q
  3. {                / s8 ]. X; z6 F5 M2 f
  4.         delay_init();                     //延时函数初始化          - q, M; s, B- {" ^9 k5 T- O
  5.         NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级9 s2 d# C% x4 W0 N  X2 l9 b
  6.         uart_init(115200);
    8 l* W% U( _* q7 |+ X
  7.         eMBInit(MB_RTU, 0x01, 0x01, 9600, MB_PAR_NONE);
    4 X7 Z7 M* i  d
  8.         eMBEnable();  
    ' n: J1 J0 K: Z& L' P5 ~
  9.          while(1)# x$ P: K: ^! [; Q- _% [. b7 s
  10.         {
    0 y6 x5 R; u" n- }2 u) r: b
  11.                 (void)eMBPoll();
    ) q3 ~4 r# U, Z: Z4 R
  12.                 delay_ms(5);
    5 a( k  L1 E2 C1 F& d* S
  13.                
    4 r& l1 J/ i- [6 G  j
  14.         }         $ W/ K/ u" ^& e
  15. }
复制代码
  M/ E2 K, ]% ]3 L
其次还要实现读线圈、写线圈、读离散输入、写保持寄存器、读保持寄存器、读输入寄存器等功能,如下:
. P+ v" V: ~6 ?% |+ \; Q" G% J- m6 H2 A3 V6 s8 y( @: B; I1 [' M8 u
  1. #define REG_INPUT_START       0x0001        //输入寄存器起始地址
    9 \$ q! [* y$ `( Z; w! m- w4 s0 i
  2. #define REG_INPUT_NREGS       8                        //输入寄存器数量9 l  I# v. w" w5 f. c' d
  3. 2 G9 K% S/ d- }, H# v' I9 b: O
  4. #define REG_HOLDING_START     0x0001        //保持寄存器起始地址
    7 n" c: R" B0 p
  5. #define REG_HOLDING_NREGS     8                        //保持寄存器数量
    8 l1 Q8 d8 m+ G  P1 V# i
  6. / a& k3 M3 D' ]8 |# E" I
  7. #define REG_COILS_START       0x0001        //线圈起始地址/ y. u" G( q1 L! d$ r
  8. #define REG_COILS_SIZE        16                        //线圈数量9 U' a; t: t  }# Y7 N6 O

  9. * o: h- l6 P( @1 H- G2 P
  10. #define REG_DISCRETE_START    0x0001        //开关寄存器其实地址
    , O8 |% w$ o  O7 N2 x* Z
  11. #define REG_DISCRETE_SIZE     16                        //开关寄存器数量6 V0 s( F& k  @* e2 Q3 x
  12. //输入寄存器内容
    ) e' X0 u0 b* H9 m/ n& _! x0 H
  13. uint16_t usRegInputBuf[REG_INPUT_NREGS] = {0x1000,0x1001,0x1002,0x1003,0x1004,0x1005,0x1006,0x1007};# v& O: P8 y; g! e% n& e) X
  14. //保持寄存器内容                - Q+ l: N7 J- l; h2 A9 q6 r. q
  15. uint16_t usRegHoldingBuf[REG_HOLDING_NREGS] = {0x2000,0x2001,0x2002,0x2003,0x2004,0x2005,0x2006,0x2007};                                        8 Q5 }$ J3 Y/ g5 v+ j
  16. //线圈状态
    8 E: d9 J- }5 `8 ?# X
  17. uint8_t ucRegCoilsBuf[REG_COILS_SIZE] = {0x01,0x01,0x00,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00};. I( b9 e' x* z, k9 j/ h1 y# P
  18. //离散寄存器内容, Y" Y. \, {- S5 i- Q" g" Y
  19. uint8_t ucRegDiscreteBuf[REG_DISCRETE_SIZE] = {0x01,0x01,0x00,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x01};
    + X9 [4 \9 v' T) J
  20. , F8 F0 `- S) R& h, t+ q
  21. /****************************************************************************
    - a- L, w+ J5 z2 _
  22. * 名          称:eMBRegInputCB
    # p0 k+ q& `! Q1 ^
  23. * 功    能:读取输入寄存器,对应功能码是 04 eMBFuncReadInputRegister# m+ p: |7 \' _2 F
  24. * 入口参数:pucRegBuffer: 数据缓存区,用于响应主机   2 O" I( m. }% v# W; Y
  25. *                                                usAddress: 寄存器地址
    7 A# z3 ^: D* E0 N' o0 h
  26. *                                                usNRegs: 要读取的寄存器个数
      f- r1 K6 I! \, ^) E
  27. * 出口参数:1 Q5 A2 c% I; h, x: o2 G) ^! ~
  28. * 注          意:上位机发来的 帧格式是: SlaveAddr(1 Byte)+FuncCode(1 Byte)
    / h" p6 o) r! t3 t- R) I! ^
  29. *                                                                +StartAddrHiByte(1 Byte)+StartAddrLoByte(1 Byte)
    9 {) Y; G; i1 B
  30. *                                                                +LenAddrHiByte(1 Byte)+LenAddrLoByte(1 Byte)+
    5 o4 @1 ^. t8 k8 j
  31. *                                                                +CRCAddrHiByte(1 Byte)+CRCAddrLoByte(1 Byte)# N$ t" r; W! W* i/ Z  h- f
  32. *                                                        3 区1 _% Q7 j; Z2 F+ j2 F% ]3 I0 ?5 M
  33. ****************************************************************************/) A1 ?3 x7 S$ P2 v  g4 h$ P
  34. eMBErrorCode- b& c5 v4 j5 J4 ^5 W
  35. eMBRegInputCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNRegs )% p2 L. m7 `- L: Q0 K2 h
  36. {
    4 F: _2 H/ w; Z) j0 Q( M8 K$ Q
  37.     eMBErrorCode    eStatus = MB_ENOERR;4 L# K) I3 Z+ ~5 }% y. @% L# F3 L
  38.     int             iRegIndex;# Z3 ]: m( B- N4 P5 P# g
  39. : S0 ?+ l. T) G7 M
  40.     if( ( usAddress >= REG_INPUT_START )+ r0 U* @, }$ P+ A5 j$ z
  41.         && ( usAddress + usNRegs <= REG_INPUT_START + REG_INPUT_NREGS ) )" r3 }; c1 L/ i: U% `: O7 e
  42.     {# X, j/ A$ K$ u9 J; w; H" _6 x
  43.         iRegIndex = ( int )( usAddress - REG_INPUT_START );% ^# F5 P8 `6 v' j
  44.         while( usNRegs > 0 )4 T3 y; p4 z; ?4 y3 U
  45.         {
    & d* `, |0 C0 `" ?7 r  e1 @+ F6 e
  46.             *pucRegBuffer++ = ( UCHAR )( usRegInputBuf[iRegIndex] >> 8 );0 T) e9 \1 p3 W# t$ y% N2 w3 J1 d
  47.             *pucRegBuffer++ = ( UCHAR )( usRegInputBuf[iRegIndex] & 0xFF );
    2 D4 o, U) E: G; |0 `3 {1 I* ~
  48.             iRegIndex++;
    8 [% d* w# u$ h2 b2 o
  49.             usNRegs--;; l3 q, i* Q1 K6 U5 ^1 O6 l0 w
  50.         }" v- b% E8 l( p. y
  51.     }
    ( b1 W8 ]1 z  T" |
  52.     else! _; g1 c0 G  y# x) g9 B
  53.     {9 W; k+ N" N  J" B0 [
  54.         eStatus = MB_ENOREG;( l6 ?9 P" S7 K2 {: O6 u
  55.     }
    3 k& e9 f2 H! C# R# P
  56. 3 A2 }$ H# }/ K* \
  57.     return eStatus;
    + E9 P, D8 B3 E- G! [
  58. }
    1 S" L' p) _& ^5 X' a' w' {
  59. & O9 W3 d; g; }
  60. /****************************************************************************' b9 i% X# k+ B: |! g0 R4 z
  61. * 名          称:eMBRegHoldingCB . Q$ f) L! H, _! G/ n4 P
  62. * 功    能:对应功能码有:06 写保持寄存器 eMBFuncWriteHoldingRegister ; u- Y" L( M. t/ L  \
  63. *                                                                                                        16 写多个保持寄存器 eMBFuncWriteMultipleHoldingRegister8 ^) K* d. u# @  C. \
  64. *                                                                                                        03 读保持寄存器 eMBFuncReadHoldingRegister
    4 G0 k( {- g! h6 j  S  T
  65. *                                                                                                        23 读写多个保持寄存器 eMBFuncReadWriteMultipleHoldingRegister
    1 f* T, _7 s% `8 B
  66. * 入口参数:pucRegBuffer: 数据缓存区,用于响应主机   
    ) I2 V- m3 e' ^; _  {
  67. *                                                usAddress: 寄存器地址0 D- I: y3 N  w! Y. V- o
  68. *                                                usNRegs: 要读写的寄存器个数9 @, s6 r) \. Q2 ]1 n
  69. *                                                eMode: 功能码
    . j& h5 J) }% ?; i  q  S5 {/ E
  70. * 出口参数:
    7 P) H$ V# h& b" ~
  71. * 注          意:4 区
    $ b+ T& H# t' C" G! ^6 p
  72. ****************************************************************************/
    9 t; d/ j# ]; |, X! q0 @9 r
  73. eMBErrorCode" [0 O: n/ ?+ S) e2 q1 k3 l
  74. eMBRegHoldingCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNRegs, eMBRegisterMode eMode ); D3 r+ z% j4 n$ E7 h# z7 a
  75. {
    5 \$ A& n1 \  G- [/ C: W8 j5 [
  76.         eMBErrorCode    eStatus = MB_ENOERR;
    5 o5 A' d) k5 W+ H  c5 R
  77.         int             iRegIndex;( `, g$ F) m0 f) ]- ~, l. H

  78. * u- c( t- q! H
  79. 5 m2 M6 w7 V4 \. R7 x& F
  80.         if((usAddress >= REG_HOLDING_START)&&\& w# U1 k7 i- j3 E0 M
  81.                 ((usAddress+usNRegs) <= (REG_HOLDING_START + REG_HOLDING_NREGS)))6 H4 M2 \  ?0 m
  82.         {
    * g) u0 U+ F4 g# Q
  83.                 iRegIndex = (int)(usAddress - REG_HOLDING_START);- I- P+ L, y4 |  y
  84.                 switch(eMode)1 ~  n0 [; |) D' H; ?
  85.                 {                                       + v0 N$ n; I9 U
  86.                         case MB_REG_READ://读 MB_REG_READ = 0# Z$ e) J, V8 v. K* e
  87.                                 while(usNRegs > 0)
    " `7 E( M' W+ \4 L6 _2 o+ m
  88.                                 {
    3 E% {$ j% W8 _8 f# k! c5 o
  89.                                         *pucRegBuffer++ = (u8)(usRegHoldingBuf[iRegIndex] >> 8);            
    8 a  f# h3 B, D: K4 f2 D, Q5 g
  90.                                         *pucRegBuffer++ = (u8)(usRegHoldingBuf[iRegIndex] & 0xFF);
    $ {, G5 _) i# ]" `6 D8 B% Y8 d9 R3 H
  91.                                         iRegIndex++;
    % ?' k( V% K. W2 E. K) \8 {
  92.                                         usNRegs--;                                       
    + N: R+ V* s, z4 w5 }
  93.                                 }                            $ t1 W8 F$ R4 h. V. s' ?* e, c
  94.                         break;. ~8 ~4 b9 X0 h9 H0 q; b: H. a
  95.                         case MB_REG_WRITE://写 MB_REG_WRITE = 0
    - x8 i6 c! M1 x5 d8 B9 M8 c# V! q
  96.                                 while(usNRegs > 0)% V1 a/ x" G4 v" k
  97.                                 {         
    5 O: a% W4 p9 m
  98.                                         usRegHoldingBuf[iRegIndex] = *pucRegBuffer++ << 8;$ Q' r0 {: G: R( D6 Y
  99.                                         usRegHoldingBuf[iRegIndex] |= *pucRegBuffer++;
    ( t# `) w6 x; |/ U& J' _
  100.                                         iRegIndex++;
    9 R3 f2 p5 A: K+ l, ~
  101.                                         usNRegs--;2 ~, r1 O; z+ h6 ]; N
  102.                                 }8 l7 r! b% b( @$ l8 H) \
  103.                         break;                                
    5 P$ K) U5 u* d, z7 m
  104.                 }; ]' d, ?# r7 t6 W9 t
  105.         }
    ! W; v4 g6 u& D3 X, [9 ?
  106.         else//错误
    9 O# S9 i# E: g; i3 s; b+ N
  107.         {# G& v2 X* P0 m# F
  108.                 eStatus = MB_ENOREG;; l6 d; O' W+ T: w. w7 }
  109.         }        
    1 ]8 H+ [+ I' j
  110.         
    + y, Q: e$ I) H9 J
  111.         return eStatus;
    4 u& d4 Y4 H3 R( e, L3 _) B# w) H
  112. }
    - t$ G' s1 ?( e3 n5 t9 S
  113. . y. @, |" h' S0 l' z4 c
  114. /****************************************************************************- h. q. `3 Z2 C$ s9 y
  115. * 名          称:eMBRegCoilsCB
    # k: K# h. e( f4 Z, d* y
  116. * 功    能:对应功能码有:01 读线圈 eMBFuncReadCoils! r9 T1 v# w2 b3 E; U! M3 Y! n
  117. *                                                  05 写线圈 eMBFuncWriteCoil2 F  z6 T! O; b4 c8 x. g
  118. *                                                  15 写多个线圈 eMBFuncWriteMultipleCoils
    2 g% x; Q' h9 z( }
  119. * 入口参数:pucRegBuffer: 数据缓存区,用于响应主机   3 ~$ F3 o5 Y! c/ u8 f" k7 a1 z+ K
  120. *                                                usAddress: 线圈地址) ~3 s. v) C/ p! y( }, }
  121. *                                                usNCoils: 要读写的线圈个数4 H( [; `. S  s3 V5 C4 H! S; t
  122. *                                                eMode: 功能码4 r2 c7 B5 _" K" O$ c! ?
  123. * 出口参数:3 {  v/ G, Q# H
  124. * 注          意:如继电器
    8 S7 D! s2 @4 y. ?2 l9 X
  125. *                                                0 区  S0 T, {) o! Z, E% `
  126. ****************************************************************************/
    ! t$ ^# h; O  Y6 K
  127. eMBErrorCode
    9 U+ k3 b: [  y2 q# ?& e- ?9 H0 t* O
  128. eMBRegCoilsCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNCoils, eMBRegisterMode eMode )
    + \  Z- ^7 N2 x  Z3 r
  129. {
    : X3 s2 U5 z% a. F0 Z4 W8 G
  130.         eMBErrorCode    eStatus = MB_ENOERR;
    + ]9 L, n9 j6 q  m/ z9 {
  131.         int             iRegIndex;+ h, s4 {- N+ t% a  u* }+ o3 p
  132.         u8 i;
    - S- F4 M: O( S+ I$ K
  133.         USHORT readNumber=usNCoils;: L1 y% k, ~5 x% i' q/ U
  134.         USHORT coilValue=0x0000;
    ( \: h8 L$ }9 k4 ]" W
  135.         if((usAddress >= REG_COILS_START)&&\& ]/ P% E& z% }$ s
  136.         ((usAddress+usNCoils) <= (REG_COILS_START + REG_COILS_SIZE)))
    ) W' {, m1 L! @4 H$ |. G! U, Q# A
  137.         {3 _$ D3 h5 R+ q* ^1 g6 G- R
  138.                 iRegIndex = (int)(usAddress + usNCoils-REG_COILS_START);
    + W% y; r- @5 `+ V8 h% A' T5 l
  139.                 switch(eMode)- l% W& s6 E# O1 }! ~
  140.                 {                                       
    5 w. n! ^- K+ |) m. T# b0 y" |7 w5 O6 x
  141.                         case MB_REG_READ://读 MB_REG_READ = 0
    - h6 f8 Q- J! @+ t
  142.                                 for(i=0;i<usNCoils;i++)! P3 l# J- o8 {# i
  143.                                 {
    ( O+ X7 S/ i+ F) {
  144.                                         readNumber--;6 S1 a3 P9 @* j$ \# |  L( C
  145.                                         iRegIndex--;
    . Z4 O* }) Y  ?' B
  146.                                         coilValue|=ucRegCoilsBuf[iRegIndex]<<readNumber;
    1 T2 E6 c5 P- t8 E: Z9 x
  147.                                 }+ e% s2 m! j& Q7 V" g( N8 y' w: d
  148.                                 if(usNCoils<=8)9 [" d" K* R) A% i
  149.                                 {
    5 z0 t& O$ ?: t! r3 S9 k6 A
  150.                                         * pucRegBuffer=coilValue;4 x" j6 Y5 O7 _7 s
  151.                                 }
    # x3 w# Y" y9 a, k' Y, f3 `  i! B
  152.                                 else5 O* w7 h7 ]0 J! u* c% x
  153.                                 {! G2 n( K0 S" ?" D# j6 b
  154.                                         * pucRegBuffer++ = (coilValue)&0x00ff;$ ~7 [, F0 D" L' p. z1 w* j/ v3 `' X
  155.                                         * pucRegBuffer++ = (coilValue>>8)&0x00ff;
    " o* J# o6 }, c
  156.                                 }" Q" H9 b9 U: Z& D4 P* `' l0 Z
  157.                         break;                           
    7 q' _" }: |! b& r! ]5 Q
  158.                         case MB_REG_WRITE://写 MB_REG_WRITE = 1
    9 b1 ?  o* o+ ~5 L6 ?  R0 {+ |
  159.                                 while(usNCoils > 0)
    , S9 ]4 G3 X: y  q! r' _
  160.                                 {         
    % i6 \- I- B, v/ o
  161.                                         //                         usRegHoldingBuf[iRegIndex] = *pucRegBuffer++ << 8;2 W7 D: V4 d5 f& q& f) u6 X
  162.                                         //           usRegHoldingBuf[iRegIndex] |= *pucRegBuffer++;
    2 x; y# K( N- c8 I# b  n
  163.                                                 iRegIndex++;) s5 I9 n3 b# E  N% s/ D$ _" x
  164.                                                 usNCoils--;
    / o1 _$ L. V7 R/ O
  165.                                 }' l0 v! q4 o; K5 ~- M4 c4 Z& f/ h
  166.                         break;7 o+ G* t4 I" k6 n7 W
  167.                 }
    ! L6 j# \5 Z8 j  ^
  168.         }9 h# s! r' u6 V. V5 f: _* m
  169.         else//错误( r0 @2 ?! P. x7 k0 x: ]
  170.         {3 @6 ~' _! ~+ u* ~) y
  171.                 eStatus = MB_ENOREG;
    1 U/ R. c- z, i4 T! i  e5 N- K; z
  172.         }        - N& H/ `+ X( i, Y/ W# S6 q

  173. 9 O' I1 k+ P3 g; n
  174.         return eStatus;
    - a$ o0 h$ j: u: g. O  f5 S& S7 `0 \
  175. }
    3 I  v- M( o- W9 a  \/ m
  176. /****************************************************************************4 n- k& v+ U- _4 b( `
  177. * 名          称:eMBRegDiscreteCB ' i' Z' J+ v' h- [  m/ l0 Y0 ?  b
  178. * 功    能:读取离散寄存器,对应功能码有:02 读离散寄存器 eMBFuncReadDiscreteInputs
    * l7 H3 y/ D3 ]/ O* ?
  179. * 入口参数:pucRegBuffer: 数据缓存区,用于响应主机   
    9 a0 X' D- A5 u- E' H
  180. *                                                usAddress: 寄存器地址
    6 s! _) ^# ^2 |+ O7 p* U( Q
  181. *                                                usNDiscrete: 要读取的寄存器个数
    * D( ?% R& |, p% v+ `0 V
  182. * 出口参数:
    ) P$ t% i" n6 r! f2 m
  183. * 注          意:1 区4 H) W' s9 b8 h6 x/ y8 h
  184. ****************************************************************************/
    2 d% B/ T2 B- V
  185. eMBErrorCode
    0 Z' g+ h: Y% A0 p9 v  P. U
  186. eMBRegDiscreteCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNDiscrete ). ]. O* m, k  p) |4 \) A/ l
  187. {
    4 o: g* @7 v7 m
  188.         eMBErrorCode    eStatus = MB_ENOERR;
    ) j( `: S2 E2 \, H0 ^
  189.         int             iRegIndex;4 t) l% B6 R4 c  W, Q) _8 S
  190.         u8 i;
    2 K# I4 g% ~1 C" f+ c6 i: p$ E
  191.         USHORT readNumber=usNDiscrete;7 D9 K8 S. _4 U
  192.         USHORT coilValue=0x0000;
    9 C7 |' Z+ a/ i. M
  193.         iRegIndex = (int)(usAddress + usNDiscrete-REG_DISCRETE_START);
    7 Y6 T1 @6 h% n8 E
  194.         if((usAddress >= REG_DISCRETE_START)&&\
    ! g4 ]  p+ @. c  k+ J) v/ A& `' w
  195.         ((usAddress+usNDiscrete) <= (REG_DISCRETE_START + REG_DISCRETE_SIZE)))
      _. s! s. A; i6 K1 }3 q  I
  196.         {" h8 ^" M. g) d2 Y# R6 H" d
  197.                 for(i=0;i<usNDiscrete;i++)* j# |4 X; u3 q( g
  198.                 {& c8 |1 l/ B7 \7 D( E3 @  ?, p; p" T1 e
  199.                         readNumber--;) z: ^* V5 s* k7 C4 I
  200.                         iRegIndex--;
    ) v+ P( W% ]# M; D8 \  J' f0 ~; A
  201.                         coilValue|=ucRegDiscreteBuf[iRegIndex]<<readNumber;& ~3 ^" M# A9 b( C& }* V- C
  202.                 }# X  u+ D6 N( e0 N2 y. Y% \
  203.                 if(usNDiscrete<=8), n6 I9 N* p7 P  `! ?  m9 Y/ h* i0 d
  204.                 {
    ' v& d2 L/ Z; \) ]: C
  205.                         * pucRegBuffer=coilValue;
    9 k! M. Q4 |3 p% P% h6 g
  206.                 }
    ; w" a( }: X) T4 Z. {$ n/ _
  207.                 else
    / O7 U- Y7 g- ~) T9 X
  208.                 {( s# G+ [* }' \" y  c
  209.                         * pucRegBuffer++ = (coilValue)&0x00ff;
    ( {0 ~" j2 p2 U! H3 ?) x2 k( T
  210.                         * pucRegBuffer++ = (coilValue>>8)&0x00ff;
    8 c4 f. }1 B' [! Z3 U  U4 ?7 b
  211.                 }; V$ ~+ c/ w9 s  ]8 b0 O7 ~" i
  212.         }+ z+ K0 K6 c' Q/ _0 Q+ z
  213.         else; h- {; e3 R, }/ K* w2 R: m
  214.         {& c3 f0 t, g* n: }( y/ _
  215.                 eStatus = MB_ENOREG;- F7 J8 o. \- h* v
  216.         }
    . @) ^8 ?8 n. n
  217.     return eStatus;
    0 i* |8 {, f7 ^; \* b
  218. }
    + G% w* W- q  p. b: n7 S' h

  219. ) V6 Z1 l' O) s' f8 B% D; s

  220.   g7 e: @% q" b6 o0 M

  221. + g6 V% u; I2 f9 ~& K
  222. : M7 M+ ~  y* [5 o0 r
复制代码
1 F5 t6 Z, A1 q' v' k
4 X: R7 t- ]4 O

7 j$ i3 u3 q4 h1 M. }

点评

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

举报

1个回答

所属标签

相似技术帖

官网相关资源

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