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

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

[复制链接]
STMCU小助手 发布时间:2022-4-23 16:17
首先我们下载FreeModbus源码,然后放到自己的工程中,新建一个MODBUS_TCP和PORT_TCP文件夹,然后将相关文件复制到里面,如下图所示:/ `% D5 J, G. \1 q2 y
20200323102539294.png
. e" |. d% j% E* g# g4 B1 }2 V- m) a& y% e0 E" N
然后修改porttcp中的代码:
, m; }8 e8 y8 t; R$ p- o首先定义一个数组用于接收数据:
  1. static UCHAR    aucTCPBuf[MB_TCP_BUF_SIZE];           //接收缓冲区
复制代码
0 U7 a5 x. V/ E
然后在xMBTCPPortInit中初始化socket连接,然后监听端口。
* E8 {' }. c& N) j$ K$ J* O  j
  1. BOOL5 S+ O  M9 P1 [5 o; v0 x  ~
  2. xMBTCPPortInit( USHORT usTCPPort )) `) I7 p( l5 l4 h8 e
  3. {# h; K+ l! P5 \' c* P
  4.     BOOL bOkay = FALSE;
    : G; L4 u7 l4 W
  5. % g  R' v0 j7 P2 J7 f5 m$ _, @$ I- ^6 |
  6.     // 侦听端口 Modbus-TCP 端口
    1 b, @1 k, \9 F+ {3 d. A
  7.         socket_init(SOCK_TCP_PORT,Sn_MR_TCP_TCP,local_tcp_port++,Sn_MR_ND_TCP);; c2 q, A0 l) o& n$ ~
  8.         listen_tcp_socket(SOCK_TCP_PORT);
    ; W# p- T1 ^; L3 }3 `) a( v
  9. . R+ ]% U1 {+ o3 W7 \$ S
  10.     bOkay = TRUE;5 `* z0 T; Q9 K4 J! _
  11.     return bOkay;
    - a$ Y  a: @4 Y5 e
  12. }
复制代码
0 k# D; V7 S) r) d/ w
然后在xMBTCPPortSendResponse函数中发送数据
/ r3 q3 A9 n% N  R2 T0 q  X2 L" q5 X+ M; I, ?# v
  1. BOOL4 z' ]- T; L  X3 @) \& F! a1 M
  2. xMBTCPPortSendResponse(const UCHAR * pucMBTCPFrame, USHORT usTCPLength )
    5 u# Q) F- F' E0 \' X
  3. {
    : J) ]$ k. J: m( i
  4.         send_tcp_socket_data(SOCK_TCP_PORT,(UCHAR*)pucMBTCPFrame,usTCPLength);        ' Y* A( P2 G9 S& S2 i
  5.     return TRUE;0 ?* \: \) |% V- i* x6 y; S
  6. }
复制代码

: h  c+ N3 ]% v9 E; R5 l然后在xMBPortTCPPool执行接收和其他操作6 l! V, S/ S6 C+ `8 m3 d

  B0 w8 `/ @8 E7 H) W  x& r1 U+ n
  1. BOOL
    & m3 g0 D! M8 x- b: s& H
  2. xMBPortTCPPool( void )
    9 V$ O. y, I4 p  X4 t- q# M
  3. {  
    7 \" J7 [( D& ?$ n: ~% c
  4.         unsigned short int us_rlen;: `" H$ W2 q4 u- Y0 y
  5.         unsigned char i;/ P6 Q# x; O+ [8 I
  6.         i=get_tcp_socket_state(SOCK_TCP_PORT);
    8 U2 j6 Q* o4 k* Q, a" _6 O

  7. " o: A, M- G( ~( S4 B
  8.         if(i==SOCK_ESTABLISHED_TCP)
    0 C- v3 M0 L& N- p( {# d$ ~6 D  O
  9.         {. f, l+ q# B& v& H6 g, D
  10.                 if(get_tcp_socket_irq(SOCK_TCP_PORT) & Sn_IR_CON_TCP)                //查看中断有没有发生
    ) A' U0 A8 Y! X+ T
  11.                 {
    / t7 g9 b! n+ |- P
  12.                         clear_tcp_socket_irq(SOCK_TCP_PORT, Sn_IR_CON_TCP);         /*清除接收中断标志位*/                                                         5 m( j4 _( z( ?# O: F' l
  13.                 }/ }: v% A! i/ ?0 _
  14.                 us_rlen=get_tcp_rx_buffer_size(SOCK_TCP_PORT);                                 //获取接收到的数据字节                                                   /*定义len为已接收数据的长度*/8 m3 M: q9 {4 D! T* O& }. m, v  _: [
  15.                 if(us_rlen==0)                                                                                                //没有接收到数据
    ' T: O8 `  D$ l% \0 Y/ g
  16.                         return FALSE;                                                                                        //返回: }0 K) [/ [0 Q- q6 ^
  17.                 else: E- W: T& f) F4 j+ x( V
  18.                 {2 d6 Q3 J: z; h5 N, q
  19.                         recv_tcp_socket_data(SOCK_TCP_PORT,aucTCPBuf,us_rlen);         //接收数据                                                                            /*接收来自Server的数据*/5 U. J5 N7 _6 c" b- M8 R+ U+ N
  20.                         printf("receive\r\n");8 Z3 s& Q, _% i+ z# }" ^; w+ i- v
  21.                         usTCPBufLen=us_rlen;( k5 M, r" m" s6 I5 X! U! H# h3 C
  22.                 }% `7 D0 b1 G6 X
  23.                 ( void )xMBPortEventPost( EV_FRAME_RECEIVED );                        //发送已接收到新数据到Modbus-TCP状态机
    2 A( V2 ^4 t1 y; A- |
  24.         }
    9 F0 [0 r: o# ~$ ?! A
  25.         else if(i==SOCK_CLOSED_TCP)                                                                        //如果socket关闭
    + ], G6 W# z% N
  26.         {% Q- e+ f) W* S3 f& ?& v$ e' p9 p
  27.                 socket_init(SOCK_TCP_PORT,Sn_MR_TCP_TCP,local_tcp_port++,Sn_MR_ND_TCP);//重新初始化, |. A0 s  {* e. X$ w/ ]; c
  28.         }8 q+ g- J2 [- `: V$ v' ?, }
  29.         else if(i==SOCK_INIT_TCP)                                                                //如果socket初始化完毕,监听端口
    : a( ?1 [% @5 O6 K
  30.         {
    3 s# n/ X, d% A# p+ ]9 }- I9 l
  31.                 listen_tcp_socket(SOCK_TCP_PORT);
    % o# t3 t2 i. v1 y6 r" M
  32.         }/ c. u) m# M( v0 b
  33.         else if(i==SOCK_CLOSE_WAIT_TCP)                                                        //如果socket等待关闭,关闭socket连接5 [9 p; v0 f8 M, p) a
  34.         {2 F" W% ]. Q1 F, k: B  r  |
  35.                 close_tcp_socket(SOCK_TCP_PORT);
    4 k4 F  U5 h2 q6 f$ f3 K2 ^
  36.         }# h, ~  R. @  U# @

  37. / T2 ^, _: l9 }& l  ]$ A0 A) ]
  38.         return TRUE;
    / D3 L. ^1 w7 M  Y" R: c/ K( Y
  39. }
复制代码
* P0 q/ u5 o5 L( B: |/ _! R
其次还要实现读线圈、写线圈、读离散输入、写保持寄存器、读保持寄存器、读输入寄存器等功能,如下:
- E+ J- K( Z, Y$ k$ Q8 U/ `' M& o
! m4 }1 Y7 \6 q6 u2 z: G( P
  1. #define REG_INPUT_START       0x0001        //输入寄存器起始地址7 E0 D! K& ?5 f
  2. #define REG_INPUT_NREGS       8                        //输入寄存器数量
    , b* e5 Q/ Y9 n! R' \

  3. 1 `3 k- K2 ]8 Q' w/ s$ o$ V& J0 a
  4. #define REG_HOLDING_START     0x0001        //保持寄存器起始地址
    # e- F# l: ]" j( o: t
  5. #define REG_HOLDING_NREGS     8                        //保持寄存器数量( x9 j$ B3 c0 c6 u

  6. 6 q6 {: D2 t# F1 E) L
  7. #define REG_COILS_START       0x0001        //线圈起始地址
    1 r- o3 E- g3 f# P! E
  8. #define REG_COILS_SIZE        16                        //线圈数量) V( D3 j9 ?: v5 c
  9. , d1 I- O9 d& p9 Q* X# s, Y! J6 _; N
  10. #define REG_DISCRETE_START    0x0001        //开关寄存器其实地址6 |- T+ p, {+ c/ A- Z5 D! T* s$ V! D+ f
  11. #define REG_DISCRETE_SIZE     16                        //开关寄存器数量
    : ~6 w$ `, }) f5 y
  12. //输入寄存器内容7 H4 r2 G# E/ c
  13. uint16_t usRegInputBuf[REG_INPUT_NREGS] = {0x1000,0x1001,0x1002,0x1003,0x1004,0x1005,0x1006,0x1007};
    + h: N0 b6 ]/ D- i' f
  14. //保持寄存器内容                - Q8 m! s/ p1 m5 a
  15. uint16_t usRegHoldingBuf[REG_HOLDING_NREGS] = {0x2000,0x2001,0x2002,0x2003,0x2004,0x2005,0x2006,0x2007};                                        : i, Z) Y" ?' t) \# y0 T1 t* r
  16. //线圈状态
    9 c2 K# n( a& f4 N( ^+ A8 o
  17. uint8_t ucRegCoilsBuf[REG_COILS_SIZE] = {0x01,0x01,0x00,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00};/ o# c2 z8 n( n' Q7 j, Q. N- `
  18. //离散寄存器内容1 ~* V# @* r; f$ V4 I- U. ^6 C
  19. uint8_t ucRegDiscreteBuf[REG_DISCRETE_SIZE] = {0x01,0x01,0x00,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x01}; 2 g# z, U. }/ Y' P  ~$ f$ F

  20. & ~4 ~/ r9 R2 r: K  Q, H
  21. /****************************************************************************# d3 T7 U! }0 `& ^" H3 B5 ^- X" \
  22. * 名          称:eMBRegInputCB
    - V" z* R- u3 Y+ ~0 Z7 k9 V8 }! i9 c
  23. * 功    能:读取输入寄存器,对应功能码是 04 eMBFuncReadInputRegister
    + Y" Y- P3 U. _' j* E; `) s
  24. * 入口参数:pucRegBuffer: 数据缓存区,用于响应主机   ( e3 h" U% R' y% n  `5 G- h, p
  25. *                                                usAddress: 寄存器地址8 r/ m/ }4 I  y9 ^- y5 \
  26. *                                                usNRegs: 要读取的寄存器个数! a+ P  u, j9 J8 Q2 I. s  M. d
  27. * 出口参数:
    - U5 M% G) g4 p, \( O1 f+ m" a
  28. * 注          意:上位机发来的 帧格式是: SlaveAddr(1 Byte)+FuncCode(1 Byte)) l7 Z1 c8 G0 U! C; g
  29. *                                                                +StartAddrHiByte(1 Byte)+StartAddrLoByte(1 Byte)' q2 z1 M0 K7 u  q( _6 ]: Z
  30. *                                                                +LenAddrHiByte(1 Byte)+LenAddrLoByte(1 Byte)+6 c( u# k; [: m
  31. *                                                                +CRCAddrHiByte(1 Byte)+CRCAddrLoByte(1 Byte)
    # E! g" |4 M6 @7 S0 b) r2 x. ?
  32. *                                                        3 区$ t; W1 W: M5 Z0 }
  33. ****************************************************************************/$ y3 |' t, J: j( l
  34. eMBErrorCode
    1 B# M: O) J1 V  M
  35. eMBRegInputCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNRegs )
    : _- ~1 ]- p: X& g; S# o* p! w" w
  36. {2 j1 |! o7 `1 Q2 {; r" ]/ R
  37.     eMBErrorCode    eStatus = MB_ENOERR;$ A. I* h$ x9 I$ c
  38.     int             iRegIndex;
    7 t- k: v: P1 }2 A* p
  39. / Q0 ~& {) b* C1 e' R! Z
  40.     if( ( usAddress >= REG_INPUT_START ), {# l& n9 E  z$ U/ f/ K
  41.         && ( usAddress + usNRegs <= REG_INPUT_START + REG_INPUT_NREGS ) )
    ! b1 R/ U/ _$ L) |
  42.     {
    : ^# Y1 }" T+ D& C3 q
  43.         iRegIndex = ( int )( usAddress - REG_INPUT_START );
    + v% q: ~, S3 f( e
  44.         while( usNRegs > 0 )
    ( L% V. p9 X6 S* @. n
  45.         {
    1 Q/ [. `: a- v- E0 n
  46.             *pucRegBuffer++ = ( UCHAR )( usRegInputBuf[iRegIndex] >> 8 );
    " _- G* q0 |( G3 p2 H" q3 E/ [
  47.             *pucRegBuffer++ = ( UCHAR )( usRegInputBuf[iRegIndex] & 0xFF );
    0 O4 _: e, B& V. s) B/ W
  48.             iRegIndex++;
    ; w$ l- K- B7 A
  49.             usNRegs--;
    + v" F7 s9 M5 f/ n$ S% U) e6 w
  50.         }
    3 G1 \9 P4 j% o8 J* v$ V
  51.     }
    7 t2 x$ W( K! R* Q3 R
  52.     else
    - k! l* X8 `4 w' K1 U' J, y
  53.     {4 h% A" c; T& |! t
  54.         eStatus = MB_ENOREG;
    $ S& A  ~! S2 r* m+ C
  55.     }
    : X& H; G$ M2 M) |3 |+ }) b4 O$ \) \' [

  56. 5 L% F7 }% k! r2 q. H
  57.     return eStatus;
    % j, N! U1 u! Y) V* V
  58. }4 A% M% R; D2 R: H* o$ P
  59. 5 q1 S9 q0 F" z
  60. /****************************************************************************
    # r8 O! d9 W; a1 l, o  F
  61. * 名          称:eMBRegHoldingCB
    $ d2 N& h2 [& H/ w3 K2 p0 |
  62. * 功    能:对应功能码有:06 写保持寄存器 eMBFuncWriteHoldingRegister
    ! R0 `+ i, [* g# D/ x1 {1 ?8 Q
  63. *                                                                                                        16 写多个保持寄存器 eMBFuncWriteMultipleHoldingRegister
    $ x. ^/ f: X% B% w/ A
  64. *                                                                                                        03 读保持寄存器 eMBFuncReadHoldingRegister
    / r3 H8 `" n1 K9 }* P. k
  65. *                                                                                                        23 读写多个保持寄存器 eMBFuncReadWriteMultipleHoldingRegister
    ) d+ {& a" F3 K# G% u1 b
  66. * 入口参数:pucRegBuffer: 数据缓存区,用于响应主机   
    / C& r# g) M, N4 \' O+ K
  67. *                                                usAddress: 寄存器地址
    3 X0 ~4 s$ h3 y* P
  68. *                                                usNRegs: 要读写的寄存器个数
    6 c3 K! D% b3 U0 [5 v1 G
  69. *                                                eMode: 功能码4 m) C4 O) B- r* _' ?. Q
  70. * 出口参数:; K6 L) a0 H8 P1 N( T
  71. * 注          意:4 区4 A% r. G/ E2 e, ^, z- A+ U
  72. ****************************************************************************/
    2 O( [! |% \" [- [
  73. eMBErrorCode
    * h: k$ [0 P+ q; h
  74. eMBRegHoldingCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNRegs, eMBRegisterMode eMode )
    . F7 {. Q8 B" v' G
  75. {
    3 ~2 o; z) E- W
  76.         eMBErrorCode    eStatus = MB_ENOERR;$ g6 I; M  J1 r/ G' Q: E
  77.         int             iRegIndex;5 k" d( T9 [, l7 m6 u4 z! s9 V

  78. 9 p, @- U7 @4 R6 T& A

  79. : @9 I( |) A. t; I5 S
  80.         if((usAddress >= REG_HOLDING_START)&&\
    8 T: A: n3 J2 [8 r  v4 i( l
  81.                 ((usAddress+usNRegs) <= (REG_HOLDING_START + REG_HOLDING_NREGS)))' a- n* F- C) {' \7 ]* o6 Z5 ?* `* f) l2 I
  82.         {
    ) J5 x, R# b$ H# |
  83.                 iRegIndex = (int)(usAddress - REG_HOLDING_START);0 |6 @- @7 A7 r& M. z& W0 q- D/ g& }
  84.                 switch(eMode)' X$ r# f7 R9 A. D1 O6 p
  85.                 {                                       
    - M; ]6 C4 Z  |: F; f
  86.                         case MB_REG_READ://读 MB_REG_READ = 0" L0 G; q* M0 z. o
  87.                                 while(usNRegs > 0)' K0 U2 i- q" I% K- j
  88.                                 {, |2 `% {# a* T
  89.                                         *pucRegBuffer++ = (u8)(usRegHoldingBuf[iRegIndex] >> 8);            % B: i  {7 w1 ?
  90.                                         *pucRegBuffer++ = (u8)(usRegHoldingBuf[iRegIndex] & 0xFF); , v) b. z, m; K' r  w4 D3 P6 d
  91.                                         iRegIndex++;- L, v( B. ?' n* {  F( [  S
  92.                                         usNRegs--;                                        0 @( n( _3 h- e1 a7 s: H
  93.                                 }                           
    % i  t4 g  G3 l6 A5 y7 z
  94.                         break;
    : V& d1 B: S0 q$ r- @- k
  95.                         case MB_REG_WRITE://写 MB_REG_WRITE = 0
    ' k. d, i( s1 D! j9 b
  96.                                 while(usNRegs > 0)0 D8 V2 K# _& @8 d) e
  97.                                 {         
    8 _# w# K8 _& {8 _& \
  98.                                         usRegHoldingBuf[iRegIndex] = *pucRegBuffer++ << 8;
    " J7 `3 q% X9 p' n, F( b* x* H
  99.                                         usRegHoldingBuf[iRegIndex] |= *pucRegBuffer++;
    1 p) h8 R# `6 Q# z& V1 C
  100.                                         iRegIndex++;
    0 [. M1 H, }4 \' G9 n5 S$ T# @
  101.                                         usNRegs--;4 H( M2 u7 C! K) \
  102.                                 }
      N) G3 r+ s, g: e3 S- N
  103.                         break;                                ; }) H& E- D$ ^- E" Q% j+ b. R
  104.                 }/ \8 m& F8 V, W1 s- _$ o6 F2 Y1 Z
  105.         }
    3 R3 g" C- S. S# `* g5 p! T
  106.         else//错误
    / e' }+ A( F7 `0 K- R, B1 X
  107.         {
    ; n+ s1 l, c+ i8 N& X' y$ `
  108.                 eStatus = MB_ENOREG;* L8 K& \+ c* V$ `) q
  109.         }        
    ( {$ w( A! J  M# U7 R
  110.         
    8 c; R6 k6 {; l& W4 C3 u3 {
  111.         return eStatus;
    ( e) c6 U3 }/ q# u& m- B4 h8 Q& y) C
  112. }/ y' r: d8 L* i  Y3 N% D
  113. # A2 M& I; m- q5 A0 v
  114. /****************************************************************************
    - H, p  _3 S* s$ |. Q/ S
  115. * 名          称:eMBRegCoilsCB
    : n0 ~5 Q; E3 N5 P% C. c+ U$ S
  116. * 功    能:对应功能码有:01 读线圈 eMBFuncReadCoils
    ( I. |5 g: X/ ^" V
  117. *                                                  05 写线圈 eMBFuncWriteCoil
    3 z$ _0 N) @7 J1 O+ G) s4 r
  118. *                                                  15 写多个线圈 eMBFuncWriteMultipleCoils# }) y9 r2 W5 x. h/ _9 B" Y' E* h6 ~
  119. * 入口参数:pucRegBuffer: 数据缓存区,用于响应主机   ) x" V, Z2 r# K: M
  120. *                                                usAddress: 线圈地址
    9 u# Z4 `. j: Y
  121. *                                                usNCoils: 要读写的线圈个数6 c" I! Z5 b' p" E' ]
  122. *                                                eMode: 功能码# {! s- L) @9 b, ]. v/ w6 c
  123. * 出口参数:
    / ]; H9 U* b* b6 u2 q: F' C4 R2 |& Z! K
  124. * 注          意:如继电器
    ! }) i8 H: B* h/ S8 Q
  125. *                                                0 区
    7 A9 E* k" u, M5 h% ?2 g3 q
  126. ****************************************************************************/
    : v+ l5 T; G3 _
  127. eMBErrorCode4 g& v# `4 P" T. W
  128. eMBRegCoilsCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNCoils, eMBRegisterMode eMode )
    * ?7 N2 P# R' o2 n) F
  129. {; S: z( {( b( R/ J# W5 g
  130.         eMBErrorCode    eStatus = MB_ENOERR;2 p9 {. H; a- x" X1 ~1 _' U* S
  131.         int             iRegIndex;3 C0 F( F' o4 N
  132.         u8 i;* C8 i- \1 Y/ s+ Y1 q3 x
  133.         USHORT readNumber=usNCoils;
    + l0 G  n7 `; P! r4 z& @4 E  n1 L
  134.         USHORT coilValue=0x0000;: F: j% A. P" w$ W5 `$ C+ \
  135.         if((usAddress >= REG_COILS_START)&&\* e0 r  F- w: ~5 C. i$ m6 \- e  j' A
  136.         ((usAddress+usNCoils) <= (REG_COILS_START + REG_COILS_SIZE)))6 m9 Z* P- p& I
  137.         {
    7 G+ L# c/ [) V8 `, v9 O
  138.                 iRegIndex = (int)(usAddress + usNCoils-REG_COILS_START);9 a. B7 N; d+ N( o  N; s2 D
  139.                 switch(eMode)1 v; O+ B; r  L: Y
  140.                 {                                       
    . C) Y) h2 b' \) q
  141.                         case MB_REG_READ://读 MB_REG_READ = 0" d+ H3 _8 ]3 F- P& q% q4 L# x
  142.                                 for(i=0;i<usNCoils;i++)% i; N$ {3 f# o6 Q. p& C; s
  143.                                 {
    $ W- T: O1 V& Z% X7 `
  144.                                         readNumber--;
    / m# f, _, D9 O4 K( [
  145.                                         iRegIndex--;
    ( S( ]; H4 \1 G/ f! o
  146.                                         coilValue|=ucRegCoilsBuf[iRegIndex]<<readNumber;
    : {9 I6 d! n; \+ {! Q
  147.                                 }5 b, h' `' q/ [9 T- i
  148.                                 if(usNCoils<=8)
    ( h& c, o, [& }: z
  149.                                 {
    - M3 V  n5 z9 b! B" F# F
  150.                                         * pucRegBuffer=coilValue;" V) y2 _8 N, O8 I: j, H# }
  151.                                 }. ?* U& w3 y& b6 c- _
  152.                                 else4 l: ]% F( o; |" L- ?. a0 b
  153.                                 {
    ) |4 z/ j6 Q0 C% u1 X
  154.                                         * pucRegBuffer++ = (coilValue)&0x00ff;
    " C( i9 D+ T# v5 ?
  155.                                         * pucRegBuffer++ = (coilValue>>8)&0x00ff;
    3 I$ M0 D$ c  G! {
  156.                                 }
    8 n8 z; }7 v. k% J. x
  157.                         break;                           
    + [: s* N5 p8 u9 x+ e( F
  158.                         case MB_REG_WRITE://写 MB_REG_WRITE = 1
    6 V' Z% u1 _' J3 g
  159.                                 while(usNCoils > 0)* [  A, d* t6 ^- d, T7 l" [
  160.                                 {         
    ! T: g2 X* W% Q! a9 |8 ]
  161.                                         //                         usRegHoldingBuf[iRegIndex] = *pucRegBuffer++ << 8;
    2 r+ P6 T  U7 U8 O9 I4 i% [
  162.                                         //           usRegHoldingBuf[iRegIndex] |= *pucRegBuffer++;4 _1 b' G' Z: S
  163.                                                 iRegIndex++;& c( G5 _, R/ N5 _$ N5 n5 A
  164.                                                 usNCoils--;
    9 m9 N/ w* o+ }# {
  165.                                 }
    ! N" c+ _9 D) n8 M
  166.                         break;1 n2 Q1 R3 C  ~1 |7 T9 t* b$ l
  167.                 }+ H5 I7 X9 V' x$ i$ V
  168.         }5 i' \' Z# m2 e! K- C& w; J0 R3 ~
  169.         else//错误
    2 x; K# |* ~+ L
  170.         {
    & u1 l+ D$ w2 t( ]6 O
  171.                 eStatus = MB_ENOREG;
      b2 E7 W- o% z. ]7 E2 ^) d
  172.         }        
    ) k1 v+ Q( A* b0 {: |7 i( l
  173. 5 N4 [$ j% A7 I* ?! [* c+ a! {
  174.         return eStatus;7 d" P& P1 n2 _1 d8 B8 S9 G) H, g
  175. }7 M5 p6 c+ `9 ]0 U# j
  176. /****************************************************************************0 C4 l8 |. A5 F  Y" j, o1 h2 }) K
  177. * 名          称:eMBRegDiscreteCB 0 S3 d. M, D' F
  178. * 功    能:读取离散寄存器,对应功能码有:02 读离散寄存器 eMBFuncReadDiscreteInputs4 V9 x0 C9 f  Y3 P5 L5 n* Z% z: P
  179. * 入口参数:pucRegBuffer: 数据缓存区,用于响应主机   , \, v$ [3 c: M
  180. *                                                usAddress: 寄存器地址
    - q6 G" ]. n' }" a! q: |" }1 j
  181. *                                                usNDiscrete: 要读取的寄存器个数
    3 W. M1 S; `9 j3 v8 k
  182. * 出口参数:; D6 Q6 J& }3 l+ ]
  183. * 注          意:1 区' K5 n! S7 h5 I( T( ~$ x9 L# |
  184. ****************************************************************************/
    4 N: c# |' W5 i9 Z3 B" ~
  185. eMBErrorCode
    ) \3 ~4 Q9 f" ]5 g0 G% Z# u
  186. eMBRegDiscreteCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNDiscrete )2 L+ ?- k! [. B' C* W/ a/ p
  187. {
    $ |9 h8 ]4 o- Q$ M( P1 A5 {5 r5 Z
  188.         eMBErrorCode    eStatus = MB_ENOERR;( }& w/ Q) G& s0 a  U) [3 ^, |+ b
  189.         int             iRegIndex;' {. `. M/ H( P8 E$ T" n. j
  190.         u8 i;
    + U" I  A  M, E7 Y- C+ c6 L: ?+ U
  191.         USHORT readNumber=usNDiscrete;! P# ^' U9 E5 q# i
  192.         USHORT coilValue=0x0000;+ f  Y2 o  z$ Y
  193.         iRegIndex = (int)(usAddress + usNDiscrete-REG_DISCRETE_START);
    . a. g, G2 g' U
  194.         if((usAddress >= REG_DISCRETE_START)&&\
    6 e% p9 X+ e! o6 s4 N, M
  195.         ((usAddress+usNDiscrete) <= (REG_DISCRETE_START + REG_DISCRETE_SIZE)))
    4 u" R4 Q, ~# F% x; J: u: w$ J
  196.         {
    4 U( j# c; ^4 b  m- O! t, K
  197.                 for(i=0;i<usNDiscrete;i++)
    ) b4 c7 T  G8 q) |3 X7 y1 m0 F1 q
  198.                 {
    & x! D0 g+ W8 h- j
  199.                         readNumber--;* U4 `% ~! M, o- i
  200.                         iRegIndex--;
    2 R/ T$ i+ ?- t! _! T, H+ u
  201.                         coilValue|=ucRegDiscreteBuf[iRegIndex]<<readNumber;
    * h: g* L9 u! r8 a: g1 ?, q
  202.                 }
    8 ]' I, ]7 g' O4 N  v' \
  203.                 if(usNDiscrete<=8)
    9 w; V3 Q. v. ^- U" G5 S
  204.                 {
    , D) q# X9 r9 d! F% o3 [
  205.                         * pucRegBuffer=coilValue;
    5 s3 b0 v) b( f8 K. p
  206.                 }# }& D2 n# D5 E7 Z) ^7 C
  207.                 else( U+ ?: v: k. n' R- t5 S: n7 m9 {
  208.                 {
    8 W) q5 J7 S: x7 C! A' B# z
  209.                         * pucRegBuffer++ = (coilValue)&0x00ff;5 s; H! P! n+ I6 [6 h: f# H
  210.                         * pucRegBuffer++ = (coilValue>>8)&0x00ff;/ Z3 C4 N5 l# _7 U7 [- `
  211.                 }2 s4 `) x! h. v+ R8 l
  212.         }! n& [5 {8 r' h
  213.         else
    ! s, y2 x" d9 K  X/ Z
  214.         {9 k+ h  j4 Y: k& Z( |) G8 w
  215.                 eStatus = MB_ENOREG;) ^7 w5 y$ }3 r  |0 n! Q4 P
  216.         }9 b& f- e3 [) J# `* v
  217.     return eStatus;2 i  |$ X& U2 Q5 K& C1 M9 ^
  218. }
    5 G) I- g# e. \5 t( ]' d
  219. ! [- X+ N( z4 L6 P& P

  220. ' |: G4 p. _- Z' W, {

  221. - C5 Z  y1 W2 `

  222. ' u9 K, R; Q7 [- T- v# `
复制代码

0 r0 N+ t. X2 }1 ^8 d- |. p
) e8 L+ [: j' W1 S
赞 收藏 1 评论0 发布时间:2022-4-23 16:17

举报

0个回答

所属标签

相似技术帖

官网相关资源

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