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

【经验分享】STM32驱动w5500移植FreeModbus实现ModbusTCP

[复制链接]
STMCU小助手 发布时间:2022-4-23 16:17
首先我们下载FreeModbus源码,然后放到自己的工程中,新建一个MODBUS_TCP和PORT_TCP文件夹,然后将相关文件复制到里面,如下图所示:
* x; [, j* ~# f( o( J" p" y; N 20200323102539294.png
# q) k" n1 R# e* V' j: N! k: }* V+ c$ V2 J
然后修改porttcp中的代码:# j9 l% O/ Z" ^; c1 |& b
首先定义一个数组用于接收数据:
  1. static UCHAR    aucTCPBuf[MB_TCP_BUF_SIZE];           //接收缓冲区
复制代码

- l7 S! y& a7 Y3 ~8 p  E然后在xMBTCPPortInit中初始化socket连接,然后监听端口。/ j. Q" C3 z) W4 V' k: S  v$ s/ i
9 Y+ r+ ~% B; o0 _! [
  1. BOOL# V. j) U1 r8 e1 z+ ]  X+ W
  2. xMBTCPPortInit( USHORT usTCPPort )
    5 X9 q, i7 G2 Q1 J6 O
  3. {
    1 ?& V, }" I% V1 ^' N! L7 J: r5 L7 U
  4.     BOOL bOkay = FALSE;; {9 u* t3 Z, e' I6 H- y3 `( i& A
  5. % `, z: ?( p. r. I+ x4 @" |
  6.     // 侦听端口 Modbus-TCP 端口
    ! `: r" b  C8 N) J. a( p
  7.         socket_init(SOCK_TCP_PORT,Sn_MR_TCP_TCP,local_tcp_port++,Sn_MR_ND_TCP);
    8 t0 j5 _+ @; k3 A0 H1 p9 A
  8.         listen_tcp_socket(SOCK_TCP_PORT);! N- Q3 n& h8 P# F) J  {% l- c7 V

  9. 4 q0 |$ @! C& x+ i/ P
  10.     bOkay = TRUE;& ?1 k! m0 w% U5 B- ?  O
  11.     return bOkay;! m4 A) s3 r* O# l; U  H
  12. }
复制代码

; T2 c1 y: P' U& j) W  H( @然后在xMBTCPPortSendResponse函数中发送数据
: k0 O) z+ S: H: W% U4 D- Y9 k! P' M+ V! K5 y6 h9 T2 U  p
  1. BOOL
    , _0 s  n9 r, s6 A; l: [5 ]3 ]1 }
  2. xMBTCPPortSendResponse(const UCHAR * pucMBTCPFrame, USHORT usTCPLength )8 C, T2 D, w8 L5 v3 R0 }8 B" c
  3. {: U( I# ?4 C4 e' l
  4.         send_tcp_socket_data(SOCK_TCP_PORT,(UCHAR*)pucMBTCPFrame,usTCPLength);        4 C% w& L; b. |1 \  o6 j+ L3 X7 R% k7 W
  5.     return TRUE;2 f' u& l" I5 y1 p' `
  6. }
复制代码

9 J9 Z& B+ `: |' O- L7 J  o然后在xMBPortTCPPool执行接收和其他操作# z8 c, R; [+ V7 Z: J8 J; \

' D3 T$ Z/ Y' J7 K0 h
  1. BOOL
      @5 }+ H3 Y6 `0 i- s5 F; r
  2. xMBPortTCPPool( void )
    5 {" c" A* H2 A+ I6 k2 p7 S7 l( G# F
  3. {  - r+ {1 H! H  q) W
  4.         unsigned short int us_rlen;* y! {8 v7 P2 f/ M: R6 B( F2 d! O
  5.         unsigned char i;
    + w) \) _5 z/ G: K3 `9 ]
  6.         i=get_tcp_socket_state(SOCK_TCP_PORT);
    2 O1 y& n  A6 n$ D3 E4 m

  7. ) C; M; u0 x# I+ x" n  o( g' p
  8.         if(i==SOCK_ESTABLISHED_TCP)  E/ r* n* V8 ?$ l% t1 ?
  9.         {+ \$ e4 `5 Q4 |9 ?- o. _
  10.                 if(get_tcp_socket_irq(SOCK_TCP_PORT) & Sn_IR_CON_TCP)                //查看中断有没有发生
    - @4 [5 E5 S- F# `; ?" U) V
  11.                 {
    ) J% ^+ x4 S) a$ K5 o# Z
  12.                         clear_tcp_socket_irq(SOCK_TCP_PORT, Sn_IR_CON_TCP);         /*清除接收中断标志位*/                                                         
    1 P- w  k' o! S# E  K
  13.                 }$ t  w" F0 E+ y$ h
  14.                 us_rlen=get_tcp_rx_buffer_size(SOCK_TCP_PORT);                                 //获取接收到的数据字节                                                   /*定义len为已接收数据的长度*/! o6 a% u. H' n$ U  x0 r
  15.                 if(us_rlen==0)                                                                                                //没有接收到数据
    ! Y) M9 j; S! E  v* s$ V
  16.                         return FALSE;                                                                                        //返回  I" A; [( B5 {
  17.                 else
      r( T; V8 V5 b) C6 k) d9 C
  18.                 {
    5 ~7 j  k& F0 ?7 J! m2 ]0 |/ _
  19.                         recv_tcp_socket_data(SOCK_TCP_PORT,aucTCPBuf,us_rlen);         //接收数据                                                                            /*接收来自Server的数据*/% b) p( x& p* E1 b+ {
  20.                         printf("receive\r\n");
    ( S. i& |: l, o  \. [
  21.                         usTCPBufLen=us_rlen;. v  R$ t1 Z( P, O) R5 _' _4 N
  22.                 }* ?4 G) V- n9 P( }4 ?
  23.                 ( void )xMBPortEventPost( EV_FRAME_RECEIVED );                        //发送已接收到新数据到Modbus-TCP状态机; H5 e( e) b& i- F8 o0 }
  24.         }
    / S7 r+ p8 u! U
  25.         else if(i==SOCK_CLOSED_TCP)                                                                        //如果socket关闭8 g; f, w5 i0 e( P  O
  26.         {
    : ~9 k, f; H* I/ e- N
  27.                 socket_init(SOCK_TCP_PORT,Sn_MR_TCP_TCP,local_tcp_port++,Sn_MR_ND_TCP);//重新初始化' a6 J) Z) f9 W0 G& x
  28.         }! s- K3 I% i, t2 q
  29.         else if(i==SOCK_INIT_TCP)                                                                //如果socket初始化完毕,监听端口9 B, S( o6 T6 M8 ]: m% k
  30.         {( J0 s) N% e/ ~0 s, H
  31.                 listen_tcp_socket(SOCK_TCP_PORT);
      }! B% J* c- [$ u, N0 e% r
  32.         }
    5 Y3 M( [. ]) I
  33.         else if(i==SOCK_CLOSE_WAIT_TCP)                                                        //如果socket等待关闭,关闭socket连接
    8 t% @, t! J" b0 j1 ^) i
  34.         {9 @4 U9 P8 u9 `2 ^
  35.                 close_tcp_socket(SOCK_TCP_PORT);- I- M2 P! ?# @" ?, \* L
  36.         }
    ) v6 U* B6 r5 `1 A2 s" `) Z8 R# @0 F

  37. % F; y! s9 q7 |# M! b0 C
  38.         return TRUE;. w% p1 G3 S5 K, C6 A$ s. x
  39. }
复制代码
( P5 G. F: x. K
其次还要实现读线圈、写线圈、读离散输入、写保持寄存器、读保持寄存器、读输入寄存器等功能,如下:
: p. u. T8 T7 S* w) `( s! \6 Y1 d- N; m6 b% v
  1. #define REG_INPUT_START       0x0001        //输入寄存器起始地址
    % N5 D; d, d7 U  ]. S
  2. #define REG_INPUT_NREGS       8                        //输入寄存器数量% j  {& \1 _; H* f
  3. 6 D3 c: I! L3 h
  4. #define REG_HOLDING_START     0x0001        //保持寄存器起始地址
    - n: ?. B: H, ~* J5 }7 |3 Y. e
  5. #define REG_HOLDING_NREGS     8                        //保持寄存器数量  H* n& @- G: q! P: {
  6.   g9 Q: h9 B- b- K& f) `; `6 t
  7. #define REG_COILS_START       0x0001        //线圈起始地址
    . I" W7 g( f) [+ O
  8. #define REG_COILS_SIZE        16                        //线圈数量
    % Q4 B" }, w7 i( N

  9. # o' o+ C3 u* s) _0 ~0 p
  10. #define REG_DISCRETE_START    0x0001        //开关寄存器其实地址, |& g' G3 @3 U) k" j
  11. #define REG_DISCRETE_SIZE     16                        //开关寄存器数量
    4 M" j2 L+ n+ p. Y
  12. //输入寄存器内容
    0 E8 A' H' Z" }. A$ J' p) O3 n& E- ^
  13. uint16_t usRegInputBuf[REG_INPUT_NREGS] = {0x1000,0x1001,0x1002,0x1003,0x1004,0x1005,0x1006,0x1007};
    , t' D2 ~6 u5 ~0 t# @
  14. //保持寄存器内容               
    , {* L1 h0 h6 c* j( F. H
  15. uint16_t usRegHoldingBuf[REG_HOLDING_NREGS] = {0x2000,0x2001,0x2002,0x2003,0x2004,0x2005,0x2006,0x2007};                                       
    0 w% i8 g& p  s  `6 _
  16. //线圈状态5 J4 H- u% q. |
  17. uint8_t ucRegCoilsBuf[REG_COILS_SIZE] = {0x01,0x01,0x00,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00};7 M: j; m0 `* O1 d  Q
  18. //离散寄存器内容
    " h+ d; Y$ o% @2 J' l
  19. uint8_t ucRegDiscreteBuf[REG_DISCRETE_SIZE] = {0x01,0x01,0x00,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x01};
    + M4 |4 e" J" B0 Z/ N! }

  20. 3 t' K/ d# s  C. Y% A5 W
  21. /****************************************************************************$ }; q0 b% n' h
  22. * 名          称:eMBRegInputCB
    0 G+ T; L; o6 O5 |/ W& M) D
  23. * 功    能:读取输入寄存器,对应功能码是 04 eMBFuncReadInputRegister& W+ f1 _" \+ ^( t
  24. * 入口参数:pucRegBuffer: 数据缓存区,用于响应主机   
    , v2 y, D& L% d1 N; A+ {! P
  25. *                                                usAddress: 寄存器地址2 j  l. O, x3 {1 C& J; G
  26. *                                                usNRegs: 要读取的寄存器个数8 ~  j& Z. l9 `: L1 x/ S
  27. * 出口参数:" Q+ E& J' \: R# d4 [* h
  28. * 注          意:上位机发来的 帧格式是: SlaveAddr(1 Byte)+FuncCode(1 Byte)
    & @# N" ^7 T8 l# J
  29. *                                                                +StartAddrHiByte(1 Byte)+StartAddrLoByte(1 Byte)( i) `6 M  t5 x; [3 H0 k
  30. *                                                                +LenAddrHiByte(1 Byte)+LenAddrLoByte(1 Byte)+
    6 O& y' {  O( l# {! S4 S3 Z5 c
  31. *                                                                +CRCAddrHiByte(1 Byte)+CRCAddrLoByte(1 Byte)7 M& L& ^8 f& M+ L8 A! u% a4 V
  32. *                                                        3 区
    8 e! Y  r# ~1 C
  33. ****************************************************************************/" o+ J; B0 k; @
  34. eMBErrorCode! X! M% g: d& C0 @7 ~1 q- B2 m
  35. eMBRegInputCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNRegs )
    . L, M3 h/ [% i. Z
  36. {
    + N4 f- A, |  s8 y, L
  37.     eMBErrorCode    eStatus = MB_ENOERR;/ j7 C' v' g6 l+ Z
  38.     int             iRegIndex;
    * y+ r4 u) W6 H% u

  39. , u; ~0 I; J& Q( z4 U
  40.     if( ( usAddress >= REG_INPUT_START )$ V. m6 a$ _8 f
  41.         && ( usAddress + usNRegs <= REG_INPUT_START + REG_INPUT_NREGS ) )4 X9 c5 c9 ~) r  _) V
  42.     {
      O/ U+ T1 K' K0 |5 {3 B, J
  43.         iRegIndex = ( int )( usAddress - REG_INPUT_START );! W& F* {5 Z/ Q# c1 ]) ^; ^
  44.         while( usNRegs > 0 )& ^8 e. B+ {7 j$ k; B
  45.         {0 d- R, P) Y* e, V
  46.             *pucRegBuffer++ = ( UCHAR )( usRegInputBuf[iRegIndex] >> 8 );
    6 `$ V" v; a# q9 t4 }7 \
  47.             *pucRegBuffer++ = ( UCHAR )( usRegInputBuf[iRegIndex] & 0xFF );
    7 I7 B' O# I& |
  48.             iRegIndex++;4 D: W! I2 A2 x& N4 C7 L
  49.             usNRegs--;) z' l: r* v9 V6 K/ \5 y7 Q6 q
  50.         }! ?! d. m: w- d3 I( z
  51.     }
    4 {/ ^) \) M2 `0 b
  52.     else
    & A# q3 P( S4 j( g6 m
  53.     {7 ~. y) y6 T2 e7 Q3 Q% P
  54.         eStatus = MB_ENOREG;
    3 [5 T2 A- ~) Q5 M% y+ }
  55.     }" `) u& C0 N- n! a/ p5 q

  56. 0 F6 m  W# b+ M' ]) g
  57.     return eStatus;
    9 F! F- ^6 w% }3 h' Y4 u9 ]
  58. }
    4 L+ q$ `  U1 d1 S3 O# Y, K
  59.   d4 z  f. Y" [3 h- p5 m
  60. /****************************************************************************& T4 j  \/ F+ I; g3 }4 L
  61. * 名          称:eMBRegHoldingCB ' D+ Z. i! g5 g9 l
  62. * 功    能:对应功能码有:06 写保持寄存器 eMBFuncWriteHoldingRegister ) H& F, Q1 P9 b1 x0 W
  63. *                                                                                                        16 写多个保持寄存器 eMBFuncWriteMultipleHoldingRegister
    : S6 w) V8 P; U8 @: b' G4 n6 m0 D/ u
  64. *                                                                                                        03 读保持寄存器 eMBFuncReadHoldingRegister/ C* I& q& m! H  J0 D
  65. *                                                                                                        23 读写多个保持寄存器 eMBFuncReadWriteMultipleHoldingRegister
    9 R1 {7 X2 b' _$ ?. x6 `( |6 N$ P
  66. * 入口参数:pucRegBuffer: 数据缓存区,用于响应主机   
    5 N& N2 l% |! ]2 K& g
  67. *                                                usAddress: 寄存器地址
    % \0 Z, \/ O  @7 X3 X( G
  68. *                                                usNRegs: 要读写的寄存器个数
    . A: O  s# S' h! o! x# s
  69. *                                                eMode: 功能码/ n1 _) G- i9 ^: b
  70. * 出口参数:2 ^4 Q. B. }! ?: B. o& i
  71. * 注          意:4 区/ X( _0 o7 k( c" V! q) R
  72. ****************************************************************************/
    * s1 a! d1 ?4 r7 ~/ q
  73. eMBErrorCode
    3 M  q, r& G3 u- m- C
  74. eMBRegHoldingCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNRegs, eMBRegisterMode eMode )' k/ m; I4 T/ L  c+ h/ \3 l
  75. {
    3 Q. j' ?" X1 ]8 q
  76.         eMBErrorCode    eStatus = MB_ENOERR;1 E/ v- d* p8 O% |7 Z; I3 b0 H2 N/ K
  77.         int             iRegIndex;
    % X1 l. c5 U) G9 b' ~" l
  78. ! G6 ?/ J& c: v- |- y! C% x, j+ L
  79. ( F+ B! [1 t! o% w  |/ F$ h. d
  80.         if((usAddress >= REG_HOLDING_START)&&\
    * ~* m* K5 A6 I; m. s' Y
  81.                 ((usAddress+usNRegs) <= (REG_HOLDING_START + REG_HOLDING_NREGS)))2 R9 d# k/ v' Y9 V9 k
  82.         {; r, o2 b1 }2 h7 t+ G4 K
  83.                 iRegIndex = (int)(usAddress - REG_HOLDING_START);
    9 B1 m' d/ c- P$ X
  84.                 switch(eMode)
    + M1 B4 c" _$ n3 v& I
  85.                 {                                       
    ) W0 k9 g+ T4 E# d# l0 f* W
  86.                         case MB_REG_READ://读 MB_REG_READ = 0% n( h2 ^! M2 f" C
  87.                                 while(usNRegs > 0)& r  }# H. j& u$ _5 K) U, f% W
  88.                                 {- R; G2 Q2 |8 ^0 `0 E
  89.                                         *pucRegBuffer++ = (u8)(usRegHoldingBuf[iRegIndex] >> 8);            
    ! E* C* ]5 h" ]1 v1 Y
  90.                                         *pucRegBuffer++ = (u8)(usRegHoldingBuf[iRegIndex] & 0xFF); 3 Q( S( n3 I3 d
  91.                                         iRegIndex++;
    : o" ?3 b- P$ }: G8 K0 n: G  V
  92.                                         usNRegs--;                                        4 I! [% q' T$ Y
  93.                                 }                           
    1 K* [; C# E5 d1 F0 ^
  94.                         break;
    5 b! v+ @% w" @+ @( p6 s
  95.                         case MB_REG_WRITE://写 MB_REG_WRITE = 0
    3 F' }! i  J; E0 C
  96.                                 while(usNRegs > 0)8 h, j( p6 E8 v
  97.                                 {         * }2 N* f! ]  a( q' M& |) g
  98.                                         usRegHoldingBuf[iRegIndex] = *pucRegBuffer++ << 8;
    - g  g% a" Z+ k- ]' F3 T3 N
  99.                                         usRegHoldingBuf[iRegIndex] |= *pucRegBuffer++;% O( M& e$ P: E
  100.                                         iRegIndex++;0 N7 _5 q# _# ]/ P0 v9 C: d
  101.                                         usNRegs--;8 I9 U- f. m( m$ S/ _0 I- ^4 v' f
  102.                                 }0 f& V# S* {5 x7 h9 q6 q. ]
  103.                         break;                                
    2 G8 j1 x  A$ y
  104.                 }
    ; {7 h. C2 {$ N# x( [
  105.         }6 G4 {& @. k4 o' p, I
  106.         else//错误
    + Q8 S* i) x, g
  107.         {
    : s; C- l0 V6 `4 r: h6 G
  108.                 eStatus = MB_ENOREG;
    1 g) ~( k1 \( T( ?  W5 H3 G
  109.         }        4 O9 c, n9 I: N6 b1 @: L
  110.         
    0 B, R8 L9 o# c5 M  o3 b' z, ]
  111.         return eStatus;
    / Z7 O( B0 s  m6 i! l# b* ~
  112. }
    3 n9 v* ^* b5 n1 Z4 c( O$ d* G- K
  113. 2 q% X$ m! i# k% G
  114. /****************************************************************************7 d( r: e# o% P
  115. * 名          称:eMBRegCoilsCB ! T$ q, ?# y$ \3 I+ C
  116. * 功    能:对应功能码有:01 读线圈 eMBFuncReadCoils  [  @( Z( u. K" J
  117. *                                                  05 写线圈 eMBFuncWriteCoil0 O! x1 J- P' H* m9 O9 \+ p
  118. *                                                  15 写多个线圈 eMBFuncWriteMultipleCoils
    % X3 l7 C5 S1 s0 J0 g# `% H5 ~6 N
  119. * 入口参数:pucRegBuffer: 数据缓存区,用于响应主机   
    $ R3 }) V) L' A; G# s$ o; I
  120. *                                                usAddress: 线圈地址
    : v: n6 z# `% k% x9 S8 A, C
  121. *                                                usNCoils: 要读写的线圈个数
      i4 r3 p3 p) g6 A# E
  122. *                                                eMode: 功能码
    3 D7 @6 W/ B/ _4 o7 M: t, [
  123. * 出口参数:
    & |, K- Z1 \% _  [- X
  124. * 注          意:如继电器 8 W+ [5 w$ I8 x8 g: m
  125. *                                                0 区
    ( }- R8 \2 h( w. V
  126. ****************************************************************************/1 s: Y& C! n5 `  K+ E6 F, d
  127. eMBErrorCode3 U' G6 z% L3 U' A$ p$ V; T8 r
  128. eMBRegCoilsCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNCoils, eMBRegisterMode eMode )4 x. X" p( k- G9 f0 S1 A* \
  129. {* M8 _8 v1 F9 q7 a
  130.         eMBErrorCode    eStatus = MB_ENOERR;
    # z  I/ U) e+ [1 r3 `. x. V8 o
  131.         int             iRegIndex;- t# B( X9 b; A0 H1 x, s/ s) ?
  132.         u8 i;
    2 W* f; B1 U8 b9 L# |# ?% {$ H
  133.         USHORT readNumber=usNCoils;8 H5 A* X( V8 H$ a
  134.         USHORT coilValue=0x0000;* o. F/ |7 ^$ P' M9 A( m( A
  135.         if((usAddress >= REG_COILS_START)&&\. B" M) u8 ]; Y0 a
  136.         ((usAddress+usNCoils) <= (REG_COILS_START + REG_COILS_SIZE)))
    2 ~; x% s5 _% z. Q/ m
  137.         {
    5 I7 N- ~- b$ x/ Y% S
  138.                 iRegIndex = (int)(usAddress + usNCoils-REG_COILS_START);' @* `! I: a1 p# q; o: X
  139.                 switch(eMode)
    + S- F5 S4 J  E5 y9 {9 C; I4 i' p
  140.                 {                                       7 O( X1 X& r7 x6 Y" q
  141.                         case MB_REG_READ://读 MB_REG_READ = 0/ ~0 n6 D" W3 `" j' e
  142.                                 for(i=0;i<usNCoils;i++)
    ( t! U; a4 w; e8 E& j: r2 }7 z' o$ B
  143.                                 {
    / y0 v' V0 a. h$ P
  144.                                         readNumber--;% T3 h% J9 |, ]& N8 V  k
  145.                                         iRegIndex--;4 v, x( x1 H$ k1 P4 {& [7 G
  146.                                         coilValue|=ucRegCoilsBuf[iRegIndex]<<readNumber;$ }3 s* l1 b% S! `% O# g6 T
  147.                                 }
    ! Z. g/ X, |+ D$ K
  148.                                 if(usNCoils<=8)
    + }. {& c# C  R% Y& a
  149.                                 {( O, N/ y# ^1 Y# J0 x/ @
  150.                                         * pucRegBuffer=coilValue;
    & C0 p, N. |9 O. Q4 u
  151.                                 }
    " E) C/ \3 }* c4 S" r$ _5 k
  152.                                 else7 @) j3 N' q% e& Y) {
  153.                                 {/ I& t& ]# T  x% s7 F! h3 h
  154.                                         * pucRegBuffer++ = (coilValue)&0x00ff;6 c2 Y* l) z& O) C
  155.                                         * pucRegBuffer++ = (coilValue>>8)&0x00ff;
    4 j! K4 x8 P1 ^! t8 i0 [; q
  156.                                 }9 F+ Q7 i6 Z5 q& _9 }
  157.                         break;                           
    # G" Y! ?) \9 Q0 k) w# m7 O
  158.                         case MB_REG_WRITE://写 MB_REG_WRITE = 1
    7 M0 s3 T5 J7 t- J# |2 x/ G! N
  159.                                 while(usNCoils > 0)
    - f2 w4 t" G, \
  160.                                 {         * V% ~0 y4 B' p3 L& ?2 {1 E% g
  161.                                         //                         usRegHoldingBuf[iRegIndex] = *pucRegBuffer++ << 8;6 O5 V% z3 b: w
  162.                                         //           usRegHoldingBuf[iRegIndex] |= *pucRegBuffer++;
    & s9 Z/ f. ^9 N9 C8 o- L
  163.                                                 iRegIndex++;
    ( z9 O, t8 S5 l% q% H- \! o$ t/ G
  164.                                                 usNCoils--;
    , T4 [9 i0 P/ O! I9 I
  165.                                 }
    " S# \; Z6 N# X. d. ]: x1 y
  166.                         break;% t& i) L- h1 `! E6 ^& x6 d/ r) K
  167.                 }
    8 {1 J- X  P3 |4 B0 m, x
  168.         }4 D1 \, ^7 x- x2 \4 A
  169.         else//错误
    8 ]2 E; F8 w& V/ P6 ^! a- t% d
  170.         {
    0 G; r- x; ]5 N' [
  171.                 eStatus = MB_ENOREG;
    1 [' G( v7 e5 y" ?- c1 F4 U
  172.         }        
    - a: V- L8 g2 V! T. r: A

  173. : W( {3 b: I9 T' |
  174.         return eStatus;
    2 q2 G5 x+ {! M9 `
  175. }$ \6 G. |0 {& o8 t1 t
  176. /****************************************************************************
    ! C* |  {7 x' [3 T$ w$ s
  177. * 名          称:eMBRegDiscreteCB % y+ x  j4 u$ O& q( z# Z' j2 H& D
  178. * 功    能:读取离散寄存器,对应功能码有:02 读离散寄存器 eMBFuncReadDiscreteInputs
    ) C- t$ s3 e* y8 x) ^( E% p! p
  179. * 入口参数:pucRegBuffer: 数据缓存区,用于响应主机   " I5 z, X& k% D0 ]& C
  180. *                                                usAddress: 寄存器地址# T- H) E& q0 O7 V3 U
  181. *                                                usNDiscrete: 要读取的寄存器个数9 {4 n6 x4 o# y
  182. * 出口参数:" l! E$ E) E" y- Q: w
  183. * 注          意:1 区
    , R* k3 e2 b* g9 d! L' |7 I9 j( J
  184. ****************************************************************************/
    7 }/ B% W5 K/ x( d3 Q
  185. eMBErrorCode4 \: H. a2 z/ k; w% W$ ~1 W/ r
  186. eMBRegDiscreteCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNDiscrete )/ {" u$ x8 c# O8 U5 t  o' Z5 E
  187. {1 g) c1 l/ ~2 ^6 b& p
  188.         eMBErrorCode    eStatus = MB_ENOERR;+ \% f* C4 h: T' P
  189.         int             iRegIndex;& _; v9 n) i* Q9 w: O4 P. k
  190.         u8 i;
    4 Y$ ?- @6 }2 c" _& }
  191.         USHORT readNumber=usNDiscrete;7 ?  @. x) z) o( B9 O
  192.         USHORT coilValue=0x0000;2 M" x" b  x& b
  193.         iRegIndex = (int)(usAddress + usNDiscrete-REG_DISCRETE_START);( V6 j( n4 s; n) q
  194.         if((usAddress >= REG_DISCRETE_START)&&\
    6 A" x, U1 }& Z2 Q6 j+ a) G1 R3 B
  195.         ((usAddress+usNDiscrete) <= (REG_DISCRETE_START + REG_DISCRETE_SIZE))), ]1 y3 B7 X- ?/ g# B' I- M
  196.         {
    4 J, V0 O4 [0 m7 \
  197.                 for(i=0;i<usNDiscrete;i++), T  N+ ?! R5 |$ P4 e9 \" e' A) ~4 s
  198.                 {9 T/ F0 z) Q8 i3 m0 R
  199.                         readNumber--;
    ) L6 `$ B# B- r1 j$ e
  200.                         iRegIndex--;
    8 n! R3 \$ t5 M" G3 ]
  201.                         coilValue|=ucRegDiscreteBuf[iRegIndex]<<readNumber;
    0 i8 t! X7 m6 h& ]) o) }7 R+ {
  202.                 }- q2 M& S% y5 N5 r5 s9 U( \3 r+ N# \
  203.                 if(usNDiscrete<=8)$ n' P, z$ q2 z) ^9 v
  204.                 {
    ) l7 |& @  v: ]
  205.                         * pucRegBuffer=coilValue;8 Q4 k; H5 k4 P; ~# S& y
  206.                 }- e* x* w- w; v- w8 B' P
  207.                 else
    $ b5 X" A/ v' `7 Q4 J
  208.                 {* m& ^/ J0 a# e2 T5 a
  209.                         * pucRegBuffer++ = (coilValue)&0x00ff;/ r. d7 E( ?1 }' w3 j
  210.                         * pucRegBuffer++ = (coilValue>>8)&0x00ff;) s( K" k8 @! c& X
  211.                 }7 W4 I5 U" l% L3 X
  212.         }
    . I1 o7 O( S& ^9 y! w
  213.         else6 ]+ p+ \% w. \2 A9 X
  214.         {
    " J5 u2 D# \4 x6 a) h
  215.                 eStatus = MB_ENOREG;3 \' Y; ^4 y# X( U# g
  216.         }
    ; s) i2 Q, M9 L* Q
  217.     return eStatus;% V9 B% x- H9 X
  218. }
    . m7 n. a2 N8 \  H

  219. / Y# m5 y- a% D! ~- N
  220. / b6 ]4 O, S  u1 Y% S4 F) a5 Z, s9 x

  221. ) w2 }' z# N; r( T4 M2 E
  222. . d! j' g% E/ l4 N* b% Y
复制代码

- Z2 [: ~( `& j* Y) }* l7 y: s$ z8 @
收藏 评论0 发布时间:2022-4-23 16:17

举报

0个回答

所属标签

相似分享

官网相关资源

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