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

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

[复制链接]
STMCU小助手 发布时间:2022-4-23 15:41
首先将FreeModbus移植到自己工程中,如下图所示:9 w- p/ y7 A, Q; k3 H, ~& f6 k
20200323104757628.png
0 g, ^0 `9 x# n" g) h
7 e  P% ^9 i9 _& f然后修改portserial.c和porttimer.c文件:
0 d; W9 O3 }0 b: T3 \: n0 X/ Yportserial.c
& t) S  ^+ E4 Q( Y2 E, y6 ?/ M# [: x" u2 n, X: J# n" W
  1. /*8 B; P3 T* O9 F5 G8 V! l; U
  2. * FreeModbus Libary: BARE Port
    ) d! E$ n# }  F, O8 Q, x* [" [
  3. * Copyright (C) 2006 Christian Walter 6 T- f4 K/ b/ N8 L
  4. *
    / J' E5 n4 ^" z) y( X
  5. * This library is free software; you can redistribute it and/or
    6 f) C! l8 e5 |* C1 B' n8 m& I/ q; m
  6. * modify it under the terms of the GNU Lesser General Public; D, `) z- |3 v4 }, q3 a
  7. * License as published by the Free Software Foundation; either
    ) G! {; n9 J" P0 b$ ]
  8. * version 2.1 of the License, or (at your option) any later version.4 U7 ]! N! M7 j) x$ e( K# G
  9. *+ d* ^- s, P/ I6 Z6 x% w* i% y
  10. * This library is distributed in the hope that it will be useful,
    + _+ _! E: v, O4 {9 e
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of4 ~+ q: p4 m' y7 Q$ n9 V; X6 w$ o' u, |/ U
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    " N6 [1 b' Q" @# X
  13. * Lesser General Public License for more details.
    0 G( E( g4 r( L% [* B
  14. *
    * I+ \; j: y( r) O' m) H
  15. * You should have received a copy of the GNU Lesser General Public( F; }8 u( k* }4 k; _
  16. * License along with this library; if not, write to the Free Software
    - p' \4 K- B1 V. P' _7 A
  17. * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA! T5 M% w, U0 c3 \5 e( L! a; i
  18. *9 M: m; U% ^( r2 s
  19. * File: $Id: portserial.c,v 1.1 2006/08/22 21:35:13 wolti Exp $
    % q) g" T$ F2 y8 e' D7 ]
  20. */* ?1 Z4 v1 Q5 `6 o

  21. & P8 T3 m5 A  v6 a* ~
  22. #include "port.h"
    + z, |  P! X- m$ x& \1 j; L  |" I4 G
  23. #include "stm32f10x.h"
    4 h) R- g, h# n- m3 }6 `# u; q; i
  24. #include "modbus.h"& c* V& H5 P' N
  25. /* ----------------------- Modbus includes ----------------------------------*/
    . C8 o( r7 u3 s1 [
  26. #include "mb.h"  Q$ G2 G) x2 \" t8 S5 q2 {
  27. #include "mbport.h"! V3 e/ Y7 t% h9 i7 I' x
  28. * ?. L, O! K8 o4 B
  29. /* ----------------------- static functions ---------------------------------*/# ~8 o5 j6 i$ m1 U- a, i( Y, Q- a
  30. static void prvvUARTTxReadyISR( void );: F" s0 ~; A, |. V( Y/ X
  31. static void prvvUARTRxISR( void );( w! _' h6 c- g1 F! E$ i/ y% e/ Q" _

  32. % x( g6 {, k6 R% g! G" H
  33. /* ----------------------- Start implementation -----------------------------*/
    & d, W! j- K. ^; m
  34. void: J, a3 i  h( ]8 J! ?
  35. vMBPortSerialEnable( BOOL xRxEnable, BOOL xTxEnable )
      C5 M: |: C0 t  [# b
  36. {$ s& U; [0 B) v2 Y) `% B7 g, X
  37.     /* If xRXEnable enable serial receive interrupts. If xTxENable enable5 u( ~* `* T/ ~: @/ A/ [4 a0 W
  38.      * transmitter empty interrupts.
    - G1 o( |5 K+ ~3 X& i# b4 l
  39.      */
    * f, T" y4 v' L" ?) a& L+ [
  40.         if(xRxEnable == TRUE)
      Q1 Z9 x  O2 F
  41.         {
    . b) g8 j" p) y- z' V0 ~
  42.                 USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);* y% a1 }" J) y) _0 S2 v2 [" h! s
  43.         }/ U$ l6 H& t( U1 O) F, P
  44.         else4 w, D( I/ ]$ L
  45.         {" a7 Q0 `4 y4 K% r5 d+ |
  46.                 USART_ITConfig(USART2, USART_IT_RXNE, DISABLE);
    * D( {4 B0 ]0 @- o% y% S* g$ b
  47.         }
    $ L+ h# Q3 ]+ I9 s% G
  48.         % D( S* P% C/ X
  49.         if(xTxEnable == TRUE)
    6 S* u9 X! q. i7 x
  50.         {
    , {8 M3 }. O" n' ]/ ~' E
  51.                 USART_ITConfig(USART2, USART_IT_TC, ENABLE);4 [9 b9 `; Z/ B: k) W
  52.         }
    2 L( e2 |6 S3 o3 k. ^" G
  53.         else! `" t! E' W, `( s; @' C
  54.         {& ?" `6 S7 d6 v3 p
  55.                 USART_ITConfig(USART2, USART_IT_TC, DISABLE);4 F7 g$ s7 U7 }; a$ J
  56.         }, c3 P! o* T( I/ X1 o
  57. }
    1 W% n1 \: t  U) A2 O) j

  58.   u4 ~" r! u4 |0 ?
  59. BOOL% ?& T$ e3 D7 l: S7 ]1 |/ n
  60. xMBPortSerialInit( UCHAR ucPORT, ULONG ulBaudRate, UCHAR ucDataBits, eMBParity eParity )7 ~3 S$ M1 Q( a3 n+ i) E' Q8 v
  61. {
    4 K: U- p5 D3 i* n
  62.         modbus_uart_init((uint16_t)ulBaudRate);  
      J+ H  q% g- ^% W, \$ W; O
  63. & b3 q9 g2 g" ]9 y8 H
  64.         return TRUE;9 a/ O2 ]4 e- _1 d/ a% y4 U
  65. }& ~8 p7 C2 Z9 [; `6 Q" m
  66. 6 Z% G- }! n' |) s) @
  67. BOOL
    9 {0 {3 D! c8 f8 U/ I
  68. xMBPortSerialPutByte( CHAR ucByte ), C) C; N/ F3 [- t
  69. {
    1 x5 F. U4 t( c: X( P  ^7 x1 h3 Z  r1 {
  70.     /* Put a byte in the UARTs transmit buffer. This function is called
    ) ?) u+ l3 @' [" i$ [' B
  71.      * by the protocol stack if pxMBFrameCBTransmitterEmpty( ) has been
    ' I5 O0 k. u. y3 X' U
  72.      * called. */5 Z' c6 U! ?, v8 ^, o
  73.         
    9 Q& F9 y5 \, l' @# ]9 ?
  74.         USART_SendData(USART2, ucByte);
    ' U  P  A7 U4 O% @8 ~
  75.     return TRUE;+ H9 J0 ~$ n; o' U
  76. }( d! X8 S3 b4 [+ p# X7 b
  77. ( y- k/ w) T: ?4 @
  78. BOOL
    1 e0 A8 k7 c: |; Q
  79. xMBPortSerialGetByte( CHAR * pucByte )( p4 d' y1 f+ f8 [* D
  80. {
    $ k- T8 h0 N" F  z( ]0 U
  81.     /* Return the byte in the UARTs receive buffer. This function is called" ?2 g0 H; \9 F( _( d
  82.      * by the protocol stack after pxMBFrameCBByteReceived( ) has been called.
    & S* z: N; l! X+ S
  83.      */6 v# l3 J* a9 i( {
  84.   *pucByte = USART_ReceiveData(USART2);
    . A/ q$ r: z4 i2 S
  85.         return TRUE;
    1 ^6 x: ^4 M2 Q* v
  86. }
    9 Y8 K* H+ _) S8 r

  87. 1 T& z6 ~: J8 u5 U+ F
  88. /* Create an interrupt handler for the transmit buffer empty interrupt
    : J8 B  q( S" ~1 q
  89. * (or an equivalent) for your target processor. This function should then0 c7 i3 k2 v" g
  90. * call pxMBFrameCBTransmitterEmpty( ) which tells the protocol stack that8 ~2 P. Z" ^5 E
  91. * a new character can be sent. The protocol stack will then call 5 ~- Z% O- |0 d1 w/ w' f: h9 z
  92. * xMBPortSerialPutByte( ) to send the character.* Z) S  C6 C2 N4 P/ o) [
  93. */2 @$ [6 ^  Y1 A% P9 r2 g: T
  94. static void prvvUARTTxReadyISR( void )
    9 w! l' K2 V* C3 K5 f; |5 p8 k+ w! ]
  95. {
    & [# {0 d8 S2 W
  96.     pxMBFrameCBTransmitterEmpty(  );* F* C$ I( x/ `6 \$ S' _
  97. }; M( {6 p1 }+ j

  98. $ t5 L$ _& {2 z+ n  h7 T6 r
  99. /* Create an interrupt handler for the receive interrupt for your target
    6 w! |, o4 D# [% p2 g0 F
  100. * processor. This function should then call pxMBFrameCBByteReceived( ). The% V2 ?1 B3 l9 h- L5 e# y, V- v2 f
  101. * protocol stack will then call xMBPortSerialGetByte( ) to retrieve the  K& V6 B& t& s2 Z  P0 c1 w
  102. * character.9 L1 R! o+ L5 `% u7 r1 H" E3 y; N
  103. */  ^+ P$ d2 V! w' X$ ^( s
  104. static void prvvUARTRxISR( void )- o. Q$ A6 v" o9 ^% ~8 G
  105. {
    " X- }3 P# ^( ?& J
  106.     pxMBFrameCBByteReceived(  );
    # ?1 ~1 t3 k/ W1 t, l: h" Z6 H* u
  107. }) ~! l! A+ J. e+ e/ b- V7 r
  108. - a+ ~. e! m5 M6 m4 H3 O
  109. /**# T% y' i( b3 e3 O% a. t* L+ K  X
  110.   * @brief  This function handles usart1 Handler., r! N% _. h; Z1 t
  111.   * @param  None+ ^* G/ h* W6 I
  112.   * @retval None
    0 N1 L; B3 A3 e( A7 c/ k
  113.   */! v$ L3 _7 x% C( @: h
  114. void USART2_IRQHandler(void)- b2 u/ M6 A& A) r
  115. {
    / s" ^6 [- H$ s& \3 E% [
  116.         //发生接收中断2 R6 l9 X4 W3 i) {, b4 d
  117.         if(USART_GetITStatus(USART2, USART_IT_RXNE) == SET)
    : ]6 L; @7 L4 a
  118.         {
    3 c  |, t' }$ F
  119.                 prvvUARTRxISR();
    3 ?: ]! O0 ]* `$ \8 @
  120.                 //清除中断标志位    7 e- i" q' y# K- q2 J; B
  121.                 USART_ClearITPendingBit(USART2, USART_IT_RXNE);   
    * G' I' E9 r; d6 v3 G: r  J
  122.         }
    ) v& U! ~5 `$ b( e. O' x

  123. 3 m. W6 \5 Z* o# Z0 }. Z* T
  124.         if(USART_GetITStatus(USART2, USART_IT_ORE) == SET)
    ) a5 M" p! S% ?9 i+ d: m
  125.         {  
    8 X  D% }7 {) Q& `4 e9 g1 Y
  126.                 USART_ClearITPendingBit(USART2, USART_IT_ORE);* Z# i. Z' s: d, W  O0 D5 A2 C
  127.                 prvvUARTRxISR();         
    ( u7 q2 A% H$ L% D
  128.         }
    0 ~* S! D; R  ?5 K/ M1 d# p
  129. 0 _, D* q& G6 P+ m
  130.         //发生完成中断0 ?! d& M# x, y; i4 @4 x& v
  131.         if(USART_GetITStatus(USART2, USART_IT_TC) == SET)3 N/ _; ^* ~7 H4 b
  132.         {) A5 K) N- s; d' w  E* c% p3 o
  133.                 prvvUARTTxReadyISR();
    : N; B1 V7 R* `1 {3 G
  134.                 //清除中断标志
    ' P, f4 q7 A, `# o! Y
  135.                 USART_ClearITPendingBit(USART2, USART_IT_TC);$ N" k. b1 j3 D% u2 L
  136.         }6 @8 U6 l2 X; R- k" d
  137. }9 P9 Z+ P: A- z
复制代码

* U4 p! Z8 m# ?$ l# {; Kporttimer.c; ?* p# |* @, p7 E1 a+ j

' h* X  Q+ {3 ~3 p/ p6 @# |

  1. ( _$ m1 g: t' F' |  H
  2. ```c
    ! F, m4 z+ }' `0 V$ w/ M  ^) c; C
  3. /*, ^9 p. ~% b9 E) e- K, o
  4. * FreeModbus Libary: BARE Port0 H/ c! I9 C+ \6 l1 q
  5. * Copyright (C) 2006 Christian Walter <<a href="mailto:wolti@sil.at">wolti@sil.at</a>>* g) S  X) z/ G4 V% A
  6. *" L  v: [0 a* f: U
  7. * This library is free software; you can redistribute it and/or2 j0 d7 e6 q: m  H' Y
  8. * modify it under the terms of the GNU Lesser General Public
    * L" ?$ B9 h+ s  }
  9. * License as published by the Free Software Foundation; either
    / _( D4 S( b/ u; W6 H( o2 M- R
  10. * version 2.1 of the License, or (at your option) any later version.
    " Q# E( d' J" x4 [. ?
  11. *
    $ \( n& G0 t' N9 U( c; _+ Z4 N; B1 s
  12. * This library is distributed in the hope that it will be useful,% P& Q% q# z" j6 W
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of( Z% A) `" z; r" b+ e
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    7 O3 ]# A4 j/ Q; m0 W
  15. * Lesser General Public License for more details.
    ! R3 T: p3 _" i& L, Y0 y
  16. *4 r9 J  g$ z% z8 u
  17. * You should have received a copy of the GNU Lesser General Public7 P6 D; m0 h" E' T
  18. * License along with this library; if not, write to the Free Software( n! ]4 C7 K* B/ @8 f+ W  O1 Z
  19. * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
    1 @% K* `; i. N1 ]9 o/ Z- [
  20. *
    0 b! Q2 G0 _+ |9 W
  21. * File: $Id: porttimer.c,v 1.1 2006/08/22 21:35:13 wolti Exp $
    5 ?1 O# i/ R2 ]2 [$ L
  22. */+ r2 ^9 ?! ]* n$ j$ P
  23. 4 c) \% @/ p& c9 P
  24. /* ----------------------- Platform includes --------------------------------*/
    , C; e- n2 v! A' V
  25. #include "port.h"
    : d/ b4 l( R. m* G$ g" y
  26. #include "modbus.h"
    1 a% u5 l/ c# K, A( Y9 L
  27. /* ----------------------- Modbus includes ----------------------------------*/
    ! R. \0 I1 ]! ~5 g( S' a2 K" C% [
  28. #include "mb.h"
    ; l  k$ H1 V) P. F% D3 i2 M
  29. #include "mbport.h"
    , @  @( L# Q/ _1 p4 k& v0 B
  30. / F7 b7 o" S; b! ]# f/ Y$ M/ Q6 o+ C8 F
  31. /* ----------------------- static functions ---------------------------------*/% v7 i1 d! f( J2 u2 ^9 y
  32. static void prvvTIMERExpiredISR( void );' N6 ~" Z& [. i$ L

  33. # f0 E- t3 @! Y9 [: j
  34. /* ----------------------- Start implementation -----------------------------*/
    5 w# l3 D5 ]  [1 T: [# ?+ L) D
  35. BOOL
    , G# I9 l4 E' v/ o: y
  36. xMBPortTimersInit( USHORT usTim1Timerout50us )/ o3 A  U) x& M: ~/ T
  37. {, I, V; X7 k0 w2 J% @% p
  38.         modbus_timer_init(usTim1Timerout50us);+ R4 g- R) \5 _- Q% s9 a

  39. 9 Y8 Y9 Z; X" [, N/ N5 H
  40.         return TRUE;0 E' V8 [0 _/ S+ n
  41. }
    , J% m( A, ]) k6 X7 o
  42. 0 z  K- t4 z$ p/ g+ b: G$ b6 N

  43. 0 `, g4 D8 U$ y
  44. void
    5 Y; l, ^" o9 Z; t9 U
  45. vMBPortTimersEnable(  )
    * D3 K! T4 M  t/ O
  46. {
    2 I% e  f6 E0 }* Z$ L& V
  47.     /* Enable the timer with the timeout passed to xMBPortTimersInit( ) */
    ! B9 l  w. [. ~) n- k
  48.         TIM_ClearITPendingBit(TIM3, TIM_IT_Update);
    4 A7 J4 A' A3 a+ c5 O; [
  49.         TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE);
    % D2 K( ~# m6 V- p: A/ X
  50.         TIM_SetCounter(TIM3,0x0000);
    ( K5 x5 `+ [( w1 L8 m. x
  51.         TIM_Cmd(TIM3, ENABLE);
    1 v& N% u' w6 v- [
  52. }
    2 E; V! |" w- y* F

  53. $ k+ W9 s; W  n( W- i
  54. void* m4 E, u  l1 H5 T
  55. vMBPortTimersDisable(  )# V% t; `3 O8 b
  56. {
    ' a" s; \  c" T2 `
  57.     /* Disable any pending timers. */
    0 f* j( \1 B9 F  @0 ?8 U* x! r0 S
  58.   TIM_ClearITPendingBit(TIM3, TIM_IT_Update);
    3 [! c( d- ]2 Z
  59.   TIM_ITConfig(TIM3, TIM_IT_Update, DISABLE);
    + N& y3 p4 p4 T( V0 Q% ~
  60.   TIM_SetCounter(TIM3,0x0000);
    . N( k5 k* t% R' T
  61.   TIM_Cmd(TIM3, DISABLE);
    ; D. x7 j7 D: v& ?
  62. }# Z6 _' s" d7 v( J0 g) ?

  63. 2 ^7 m( R4 a( i
  64. /* Create an ISR which is called whenever the timer has expired. This function
    & L- s( j9 N) h+ w( t+ W# E
  65. * must then call pxMBPortCBTimerExpired( ) to notify the protocol stack that9 o. u/ K6 D# _$ A
  66. * the timer has expired.
    " @) J  w* G5 J4 f6 f# t
  67. */+ I, M+ ?) N9 b# T) Y+ M
  68. static void prvvTIMERExpiredISR( void )) t0 ]! A& L8 S5 p
  69. {
    # B& V- X8 ^' I
  70.     ( void )pxMBPortCBTimerExpired(  );5 E! N6 q$ S2 J% |& L! w
  71. }
      d: C( Y9 V+ }! @
  72. 3 v9 O+ `3 @) P. {9 d7 n1 l
  73. void TIM3_IRQHandler(void). T, Z* ?  \. J* g4 P: C! d- J3 K
  74. {
    6 H" P9 N! _+ n3 _
  75.         if(TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET)
    3 e% j- a' y7 N- j  d
  76.         {
    ( c% {& m3 q- o- n# u: ^$ H0 H! W
  77.                 prvvTIMERExpiredISR();
    # @5 d, s  ^# a7 M8 X' m9 |  m5 ^
  78.                 TIM_ClearITPendingBit(TIM3, TIM_IT_Update);" \5 f. e; l* R% t
  79.         }, C7 H; V8 i, x2 i4 J0 x
  80. }
复制代码
' [& A7 k. \+ t/ o1 A
然后主函数中调用
0 P' j" H" r( }) @1 Q- D0 ]  }3 D
  d& F; G  _* u" g! E! i+ e5 f1 I

  1. 7 S) B: o$ L8 O" t3 S
  2. int main(void). P1 p. w# d3 X! u7 Y
  3. {               
    ; T: o4 a: [& E# C7 V, w# |
  4.         delay_init();                     //延时函数初始化          4 t- K, R( q# t
  5.         NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级# s1 C$ ?4 Q/ ~5 a1 [' ^- N* n
  6.         uart_init(115200);
    ' J$ h8 X+ c) M/ r1 k
  7.         eMBInit(MB_RTU, 0x01, 0x01, 9600, MB_PAR_NONE);* b+ P: ]* c: B; V  L, e# h
  8.         eMBEnable();  
    4 K- E* A4 q1 q" _! |; P
  9.          while(1)
    $ P7 ~+ L' C7 D, g0 f
  10.         {
    ( u* V6 l( _3 Z& p4 m3 N3 l$ E
  11.                 (void)eMBPoll();7 |6 C% S( t7 o8 B2 u3 u
  12.                 delay_ms(5);
    1 i$ y) `+ l: @) j9 c& T1 ~; P
  13.                 + H" m, \% l( q$ g) B& S9 s* R. f# A
  14.         }         8 }; c' I3 R- {+ }
  15. }
复制代码

% U6 w1 S' X- o. M1 Y7 x  z3 }9 T; y8 w其次还要实现读线圈、写线圈、读离散输入、写保持寄存器、读保持寄存器、读输入寄存器等功能,如下:: V* X) |7 G" q  |, Z9 Q

; v# V/ a* [! I9 f# ]: \' {/ ]
  1. #define REG_INPUT_START       0x0001        //输入寄存器起始地址3 P, _$ m' E0 t+ c4 Z; c5 i- m, D
  2. #define REG_INPUT_NREGS       8                        //输入寄存器数量
    ' ?4 C( C" e9 \; v  G- q6 r

  3. + g4 ^0 e. N+ j# d! ?- N7 a- `9 w
  4. #define REG_HOLDING_START     0x0001        //保持寄存器起始地址% t+ ?: k+ B* x' q' o
  5. #define REG_HOLDING_NREGS     8                        //保持寄存器数量7 q7 ?! p2 r0 ^7 N- m( E
  6. 5 }: I+ X8 d; _6 c: e2 }0 ]. d
  7. #define REG_COILS_START       0x0001        //线圈起始地址9 u5 b% {; W; v6 {% I! \) ~- I
  8. #define REG_COILS_SIZE        16                        //线圈数量& N  Q/ V3 @+ V. H/ r4 p& `
  9. + S% ]$ k2 I8 p' M9 G9 N
  10. #define REG_DISCRETE_START    0x0001        //开关寄存器其实地址
    2 H1 B$ ^, }6 D
  11. #define REG_DISCRETE_SIZE     16                        //开关寄存器数量
    ) `/ O3 V6 v/ y6 N) n& S! y8 E
  12. //输入寄存器内容
    # M$ }% v& ?# W$ W1 M% T  R
  13. uint16_t usRegInputBuf[REG_INPUT_NREGS] = {0x1000,0x1001,0x1002,0x1003,0x1004,0x1005,0x1006,0x1007};8 }, H. ?& z" X( _, Z5 H
  14. //保持寄存器内容               
    , D4 N) Z' s/ }) w1 _+ ^* G
  15. uint16_t usRegHoldingBuf[REG_HOLDING_NREGS] = {0x2000,0x2001,0x2002,0x2003,0x2004,0x2005,0x2006,0x2007};                                       
    ) K+ \; A. P5 B
  16. //线圈状态
    , w% e3 ~. b* S7 H
  17. uint8_t ucRegCoilsBuf[REG_COILS_SIZE] = {0x01,0x01,0x00,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00};
    ) }% }# _  I0 h, k+ @# o
  18. //离散寄存器内容
    2 O9 T) R- [: D
  19. uint8_t ucRegDiscreteBuf[REG_DISCRETE_SIZE] = {0x01,0x01,0x00,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x01};
    6 A+ c) A8 W7 r& B* Y

  20. ; _0 j0 h1 E, Q! D: `
  21. /****************************************************************************
    0 [# M: `2 B2 o% z$ J
  22. * 名          称:eMBRegInputCB 5 Y( y, s* `4 v$ _: _
  23. * 功    能:读取输入寄存器,对应功能码是 04 eMBFuncReadInputRegister* d! x+ W' N3 L+ _/ b0 F
  24. * 入口参数:pucRegBuffer: 数据缓存区,用于响应主机   3 l' S5 M8 n7 g. J7 p$ _, |
  25. *                                                usAddress: 寄存器地址- ?) l% l0 W# u! D2 I9 {
  26. *                                                usNRegs: 要读取的寄存器个数! a* K3 {) s9 Q3 O" l4 v
  27. * 出口参数:4 |7 u7 b" f# d/ E
  28. * 注          意:上位机发来的 帧格式是: SlaveAddr(1 Byte)+FuncCode(1 Byte)9 Q$ C) g2 v. U  b8 l8 \
  29. *                                                                +StartAddrHiByte(1 Byte)+StartAddrLoByte(1 Byte)% w+ K9 c+ m1 p0 Z4 M5 o
  30. *                                                                +LenAddrHiByte(1 Byte)+LenAddrLoByte(1 Byte)+
    3 H, p1 M- q5 K( U/ j
  31. *                                                                +CRCAddrHiByte(1 Byte)+CRCAddrLoByte(1 Byte)- C) ~7 ]  s2 ~( t& [; x& ~
  32. *                                                        3 区( H& O2 v" P: `; D; {
  33. ****************************************************************************/7 {' x6 ?. n1 D1 u
  34. eMBErrorCode
    ( L& K  Y/ `. }; H4 c% ?
  35. eMBRegInputCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNRegs ). [: _/ p& o6 l, S& z
  36. {
    % l# s) ?0 G9 \$ i& v
  37.     eMBErrorCode    eStatus = MB_ENOERR;: V( P; x3 M$ d% i# X+ A1 `2 K7 ?
  38.     int             iRegIndex;
    0 _% L, _7 B0 {) c, b

  39. , }# |3 S: n! B
  40.     if( ( usAddress >= REG_INPUT_START )7 c4 M* V/ z  c9 X& |
  41.         && ( usAddress + usNRegs <= REG_INPUT_START + REG_INPUT_NREGS ) )8 M9 X2 {% Z3 T
  42.     {. ?: C6 y9 W" \; q& v4 {. B+ F
  43.         iRegIndex = ( int )( usAddress - REG_INPUT_START );  y' {0 Z( T5 a7 G+ x4 i0 M
  44.         while( usNRegs > 0 )
    . j# |7 ^7 w9 D) Y/ U9 ?" ]
  45.         {3 U  v1 h& |' o& O, x
  46.             *pucRegBuffer++ = ( UCHAR )( usRegInputBuf[iRegIndex] >> 8 );
      g4 s/ I- i- M9 y- U
  47.             *pucRegBuffer++ = ( UCHAR )( usRegInputBuf[iRegIndex] & 0xFF );
    - N& K( c% ^! P( T7 ]8 i
  48.             iRegIndex++;
    5 t# c4 G  ~; a' H! R4 u
  49.             usNRegs--;
    0 j: L6 j. d9 t; |* L
  50.         }3 H* a5 [' J( [3 k1 y7 Z
  51.     }
    , k9 G; r6 j1 u
  52.     else
    3 J9 w) c# j1 o  x! N6 U: t% F: g
  53.     {% g9 J' l2 U) o5 L6 T+ ^& S. F
  54.         eStatus = MB_ENOREG;/ Y& F" }4 K9 B0 X
  55.     }
    4 d, _% [! x  a0 V
  56. & Y" @( ]- |, W! W( _  e& P4 l
  57.     return eStatus;
    $ P: j; R! q8 s! [
  58. }
    9 v/ M9 P/ Y) P* e
  59. ' m. x$ R  v  A
  60. /****************************************************************************: [  m, g* y! B+ p: m
  61. * 名          称:eMBRegHoldingCB
    ) {; [, z0 o# |1 W- r
  62. * 功    能:对应功能码有:06 写保持寄存器 eMBFuncWriteHoldingRegister $ _8 s& B6 A0 C3 n& ]' w
  63. *                                                                                                        16 写多个保持寄存器 eMBFuncWriteMultipleHoldingRegister
    ( U4 Y( N" T  \, g+ c
  64. *                                                                                                        03 读保持寄存器 eMBFuncReadHoldingRegister
    2 }; U# \; u' t" l0 z
  65. *                                                                                                        23 读写多个保持寄存器 eMBFuncReadWriteMultipleHoldingRegister% @2 W" }- G6 r2 a) p( ~2 A( h
  66. * 入口参数:pucRegBuffer: 数据缓存区,用于响应主机   
      x" d& C9 y. a2 F
  67. *                                                usAddress: 寄存器地址( X3 O2 c9 ]8 ?
  68. *                                                usNRegs: 要读写的寄存器个数
    ( B4 f. O8 u7 R
  69. *                                                eMode: 功能码
    - \- m' g; o7 l' q  L" m: G) G0 M
  70. * 出口参数:
    5 f: j" z6 R9 v' W, k  g  Z5 x
  71. * 注          意:4 区( P+ i5 p; E- y
  72. ****************************************************************************/& y5 o) C& i" U
  73. eMBErrorCode
    5 N6 K. Q/ L6 H7 p0 t7 L) g' ~
  74. eMBRegHoldingCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNRegs, eMBRegisterMode eMode )1 L2 c, z1 M, S
  75. {
    2 c% r* C2 l5 K0 i% r1 s: ?
  76.         eMBErrorCode    eStatus = MB_ENOERR;, V# b# s) [* t+ U5 m
  77.         int             iRegIndex;
    * m- n0 Q4 h+ B4 @+ g: `5 H
  78. # V, d! y# d: _& F
  79. 9 \  W. K# z) j6 j! G$ G
  80.         if((usAddress >= REG_HOLDING_START)&&\8 _7 m, J0 S, H" ~: V( ^; B
  81.                 ((usAddress+usNRegs) <= (REG_HOLDING_START + REG_HOLDING_NREGS)))& Q9 v/ l) U1 J4 j+ ?
  82.         {
    : |, N/ O5 m- R/ ~+ s$ J: d
  83.                 iRegIndex = (int)(usAddress - REG_HOLDING_START);
    ) o% w' Y) N, B* e# ^0 B$ h1 ]2 ]
  84.                 switch(eMode)
    . a+ M& l7 ^8 u4 E
  85.                 {                                         ~  G! c" u0 h+ Z
  86.                         case MB_REG_READ://读 MB_REG_READ = 0( X% p, r& k  q$ u' |
  87.                                 while(usNRegs > 0)' B& Q% P7 @$ J& b- J8 p
  88.                                 {
    4 b9 a: J* V6 U/ V" L1 w9 N
  89.                                         *pucRegBuffer++ = (u8)(usRegHoldingBuf[iRegIndex] >> 8);            
    / h: v! `& d% l! ?0 I* `8 t
  90.                                         *pucRegBuffer++ = (u8)(usRegHoldingBuf[iRegIndex] & 0xFF);
    ; F) M( z- J- _* h: |/ [& }  @( K
  91.                                         iRegIndex++;$ g" {  P: Q/ N5 t8 _5 ^" W
  92.                                         usNRegs--;                                       
    7 T5 s' F8 [8 j* x/ {+ k
  93.                                 }                            2 U. q: q9 g% y9 P' J! ~
  94.                         break;
      c5 S3 W5 ^: B' p- ?! o) |
  95.                         case MB_REG_WRITE://写 MB_REG_WRITE = 0
    # i+ r' x8 c: m# x! _! q4 G) ?
  96.                                 while(usNRegs > 0)" P1 _8 w$ I  |; N. z
  97.                                 {         
    / ^! b( s% r1 J' [
  98.                                         usRegHoldingBuf[iRegIndex] = *pucRegBuffer++ << 8;3 Z/ T0 P7 \% Y, a# e
  99.                                         usRegHoldingBuf[iRegIndex] |= *pucRegBuffer++;
    " N- P, r0 y4 b: _% E8 t
  100.                                         iRegIndex++;
    6 ~4 A6 L0 a% `8 x+ B" T
  101.                                         usNRegs--;* L3 G' C1 O1 }% ^% o2 G  M3 u
  102.                                 }
    ) I: S" z. E1 z2 k( e. s! U) S  w
  103.                         break;                                3 J. p1 k3 M/ I
  104.                 }- ?1 G7 Y/ D- \- H" ]1 O  W
  105.         }: W" H! }6 Q* p  f- _/ E
  106.         else//错误
    5 g0 L  Z: t7 }, v# P# U
  107.         {3 Q) V  J. V- c/ r! Z7 V
  108.                 eStatus = MB_ENOREG;
    - [& e. C4 E  k
  109.         }        . s! I  }9 @, S
  110.         
    8 K$ ~1 @# {8 }8 W
  111.         return eStatus;
    5 j/ `' M) H4 ~  d2 U% N' j
  112. }
    7 o* T% O6 d1 g- T
  113. ) s* ?. D+ r2 F" \. K
  114. /****************************************************************************
    $ F; E# Z: |/ K* Q" u
  115. * 名          称:eMBRegCoilsCB
    - K9 e5 y4 U6 @8 @* Y7 e1 ]4 Y
  116. * 功    能:对应功能码有:01 读线圈 eMBFuncReadCoils
    # N9 Q9 P0 l) V" L5 Q3 A. l
  117. *                                                  05 写线圈 eMBFuncWriteCoil
    : g( j1 z+ |8 l3 d& q6 e  M3 A
  118. *                                                  15 写多个线圈 eMBFuncWriteMultipleCoils5 }$ ?% T! [+ ^; B- i
  119. * 入口参数:pucRegBuffer: 数据缓存区,用于响应主机   - q: A# M' ~5 q/ ]* |4 t% s8 u
  120. *                                                usAddress: 线圈地址
    8 ]9 ^. e; L* j: H1 y4 s9 y
  121. *                                                usNCoils: 要读写的线圈个数7 n0 V, {' x6 y# M$ V( o
  122. *                                                eMode: 功能码; J; H1 q5 J' s3 [0 b7 M. y
  123. * 出口参数:
    1 b5 R( L, w* ?. T5 Q3 l' v
  124. * 注          意:如继电器 * L/ U8 X' B8 u3 }2 Z+ R) Z
  125. *                                                0 区7 X* I3 K" u3 s" I( Y, M0 V
  126. ****************************************************************************/
    " X, n; v& d4 p- |$ x1 T, j
  127. eMBErrorCode' X$ T9 G& r6 h% Y5 v
  128. eMBRegCoilsCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNCoils, eMBRegisterMode eMode )& |* n! e& [4 m2 ^: U
  129. {" g/ ~, V. a4 W8 Y
  130.         eMBErrorCode    eStatus = MB_ENOERR;; h( l7 o' b1 s* b9 z
  131.         int             iRegIndex;( J" a) H3 k" s/ U- ~) [
  132.         u8 i;
    + k" `1 d- `6 r
  133.         USHORT readNumber=usNCoils;
    # E0 C& P5 ~! r# Z  Q* t
  134.         USHORT coilValue=0x0000;
    % m0 e; I  e! g. T( M" d
  135.         if((usAddress >= REG_COILS_START)&&\+ e% T! H. N8 k8 ]
  136.         ((usAddress+usNCoils) <= (REG_COILS_START + REG_COILS_SIZE)))
    ! [, g4 Q! W. W0 S% ]0 Y  I! C" T2 y
  137.         {4 C8 y! \  S2 n: B! s4 t
  138.                 iRegIndex = (int)(usAddress + usNCoils-REG_COILS_START);
    , N$ _3 g5 a' T: T1 P
  139.                 switch(eMode): G/ Y9 a3 U, }
  140.                 {                                       ) ?8 x% v* b4 l) |) M* y  m2 }% E
  141.                         case MB_REG_READ://读 MB_REG_READ = 0
    / A: c; _8 k( [, @: h+ A) V* R
  142.                                 for(i=0;i<usNCoils;i++)
    # q: }6 J) K! r8 O6 m, L
  143.                                 {8 x& r8 @' n/ c: G: [
  144.                                         readNumber--;# y" z; m# m. Q5 d" K& C1 f
  145.                                         iRegIndex--;6 _9 J  N2 D' Z* i. p
  146.                                         coilValue|=ucRegCoilsBuf[iRegIndex]<<readNumber;4 z8 k3 p0 T7 x) b% G$ ], E
  147.                                 }
    5 ]( w% K5 X3 d) V
  148.                                 if(usNCoils<=8)
    " j5 N5 G/ a+ |
  149.                                 {. G+ v! \0 v& X) E5 j" o, _
  150.                                         * pucRegBuffer=coilValue;
    ; t% H1 ]/ w6 g) r; a; J
  151.                                 }
    ) X" s8 l7 {# ~9 v
  152.                                 else, E! V4 B/ U6 X& b: }9 a
  153.                                 {
    , p( l4 O! e  ]0 C* _
  154.                                         * pucRegBuffer++ = (coilValue)&0x00ff;& G/ z3 r$ a" S3 \8 y4 ]
  155.                                         * pucRegBuffer++ = (coilValue>>8)&0x00ff;( D1 P9 y( R: p3 }& x( {
  156.                                 }
    + S7 G; m0 Z1 b" _. h$ V3 F# D1 ^; x
  157.                         break;                           
    5 t5 N7 D5 ]' i3 X, x
  158.                         case MB_REG_WRITE://写 MB_REG_WRITE = 1
    , I* E, U; q3 L# w; D+ |* h
  159.                                 while(usNCoils > 0)8 L+ c- L/ s) \0 g' s" A  m5 R
  160.                                 {         ! k1 [$ y7 p6 x; c
  161.                                         //                         usRegHoldingBuf[iRegIndex] = *pucRegBuffer++ << 8;+ Z0 ~7 y4 g) l$ O) ^2 p4 B
  162.                                         //           usRegHoldingBuf[iRegIndex] |= *pucRegBuffer++;
    : l" N6 t' e( {9 K
  163.                                                 iRegIndex++;" G) h7 A4 k! k
  164.                                                 usNCoils--;5 ~! J, F# X7 Q. p& O3 L3 f
  165.                                 }
    ' X. U& s% ]$ W$ b. L3 i
  166.                         break;
    / D! q9 H+ w, {1 d8 H- [1 W" U
  167.                 }- ~  W& ?, {3 x1 F& ]9 X8 X  X
  168.         }$ T! f" m0 S: ^
  169.         else//错误
    . V! G: p! f7 r) t1 n4 Y3 {
  170.         {4 A3 F  C& H) o) ^( [! k
  171.                 eStatus = MB_ENOREG;5 [4 ]: L4 j( Q- p' n
  172.         }        ' p, |; G" S1 c9 J4 T1 A3 ~! F5 c

  173. ! t6 m* e) {' h* q8 P
  174.         return eStatus;
    ) H$ d" f+ b$ E2 o) _9 V; }% ^
  175. }
    $ {. U0 F3 D/ D* d" a
  176. /****************************************************************************
    . p; E3 ?9 w" I/ a( D- q) J
  177. * 名          称:eMBRegDiscreteCB 6 r3 _* X* i: \
  178. * 功    能:读取离散寄存器,对应功能码有:02 读离散寄存器 eMBFuncReadDiscreteInputs! e; o: ~( M" C8 E
  179. * 入口参数:pucRegBuffer: 数据缓存区,用于响应主机   
    6 n& Z* V* F$ w: W0 d$ R
  180. *                                                usAddress: 寄存器地址
    1 K/ W6 H& H, u: M4 c* h
  181. *                                                usNDiscrete: 要读取的寄存器个数
    3 ]: D- G1 t2 X8 Y! `
  182. * 出口参数:
    & }; V/ J8 H/ E& u( u  x5 ]9 z# u
  183. * 注          意:1 区9 I  ^7 @; `% k, L& o, D, D8 J
  184. ****************************************************************************/
    , m, ]1 E$ a. d7 ~( V
  185. eMBErrorCode) \3 n) q2 \7 I# f* }. `
  186. eMBRegDiscreteCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNDiscrete )
    ( o  L. z5 B& y
  187. {3 H+ s: e1 {# ?5 M( W- m
  188.         eMBErrorCode    eStatus = MB_ENOERR;" e4 _( J* u3 ?
  189.         int             iRegIndex;. z# J1 P0 w9 i/ W% D0 a
  190.         u8 i;4 |3 \5 a& V6 u9 m+ }
  191.         USHORT readNumber=usNDiscrete;
      O: i& g: Y7 e5 |+ G( Z  U7 m
  192.         USHORT coilValue=0x0000;
    / j. M2 ^& r) B3 {. a
  193.         iRegIndex = (int)(usAddress + usNDiscrete-REG_DISCRETE_START);& M, X; |$ C+ p6 e# Q% V3 s; Y
  194.         if((usAddress >= REG_DISCRETE_START)&&\" d7 r* w+ z& M, p9 g' l
  195.         ((usAddress+usNDiscrete) <= (REG_DISCRETE_START + REG_DISCRETE_SIZE))): M+ O& I6 _  a2 X" s
  196.         {
    / K- g. k/ e8 `/ e* W! P/ W, ]
  197.                 for(i=0;i<usNDiscrete;i++)  ~9 `' }3 Y3 _; q7 q# p
  198.                 {
    $ a- g( y0 G2 V+ y
  199.                         readNumber--;
      r; ]" L4 g. @
  200.                         iRegIndex--;) ]2 B/ J. u7 _. k/ O* }9 x
  201.                         coilValue|=ucRegDiscreteBuf[iRegIndex]<<readNumber;# ]. S$ @& A2 H6 a) W1 \
  202.                 }
    ; R% W! x* Y8 I- W* M! ^$ S
  203.                 if(usNDiscrete<=8)0 y9 F9 X0 S0 ^
  204.                 {  i& K" v9 F  C% o$ O7 v5 e
  205.                         * pucRegBuffer=coilValue;
    # z4 W% r3 P* g  R% e$ r
  206.                 }: l; ]1 }" j9 G& X
  207.                 else1 [, r! ?/ B7 x
  208.                 {' {: g/ U" O" S6 i( O
  209.                         * pucRegBuffer++ = (coilValue)&0x00ff;
    / p% T. w  A8 ?8 I5 u) X
  210.                         * pucRegBuffer++ = (coilValue>>8)&0x00ff;
    : D+ \5 o. L7 N! `
  211.                 }
    $ H% G  {* ]9 z4 [/ e  ]
  212.         }
    - z4 G, W6 J* K0 {: z
  213.         else7 _* A: E1 e3 g, F
  214.         {/ l5 a  f; z/ ^' u, W
  215.                 eStatus = MB_ENOREG;1 N- J* [  i6 u, o0 K1 O
  216.         }
    $ L+ r& i8 u1 E1 O9 y2 g
  217.     return eStatus;
    ' v4 L# b/ a1 y) a/ k3 {% |: U2 H( `5 x
  218. }7 ?# I) `. G+ y* H0 A
  219. % G' {8 }5 M% i& w
  220. 1 B, J0 Y& b. \' P

  221. $ T+ D" o& l+ I

  222. % a) y* i+ w6 {7 P6 u; f3 z
复制代码
" i6 O! S0 V" k! H, ]+ S
' G7 t9 P! Z* K6 Z7 j4 A* o( M$ ?

6 ?: Z1 q6 B2 Q; W8 |4 R4 a
收藏 评论0 发布时间:2022-4-23 15:41

举报

0个回答

所属标签

相似分享

官网相关资源

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