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

如何在裸机stm32移植FreeModbus

[复制链接]
攻城狮Melo 发布时间:2023-3-14 16:54
官方下载freemodbus-v1.6.zip源码,然后把源码中的modbus文件夹、demo\BARE\port文件夹导入工程。
4 P& n# U5 M3 C& o! l

. {: U0 t# H$ b1 y: v4 U5 }先是一波无脑导,把文件夹里所有文件导入。
1 h( h) S$ A- g

6 H* o1 n; u4 E  {& c) q3 G* s存储区配置,单片机上定义的起始地址要比实际通信过程中读写的地址+1。: C" y* W+ G6 H$ [; L
  1. #include "mb.h"
    ) I$ O2 J, |: c& ^% e  m
  2. #include "mbport.h"
    , w% M. ]; g- M( x
  3. #include "mbutils.h"; D  V- a* o7 F& b' P, w6 ]( A
  4. //输入寄存器
    " }! R0 s: P5 A- P) J
  5. #define REG_INPUT_START 10012 v8 r6 ~( q  i! u# b
  6. #define REG_INPUT_NREGS 2
    . Y0 O' O0 F( ^0 ]* d

  7. & r* O& P* D' {4 Q2 D
  8. static USHORT   usRegInputStart = REG_INPUT_START;. b$ \! H! E5 D' E6 }; \) h+ ]* k1 F! T
  9. static USHORT   usRegInputBuf[REG_INPUT_NREGS];4 o- _! g3 S, Y9 h2 p0 Q
  10. ' b! X/ @7 n) B3 ?' w
  11. //保持寄存器
    7 p& A( X* m1 a6 Z6 Z
  12. #define REG_HOLDING_START 2001  c' T, V2 E# c8 j
  13. #define REG_HOLDING_NREGS 14 s$ P, E# F5 g
  14. 5 B/ }) X" n0 b  K7 r( Z
  15. static USHORT   usRegHoldingStart = REG_HOLDING_START;
    7 a$ Z: ?% A! m' Q4 x4 w; T5 i! X
  16. static USHORT   usRegHoldingBuf[REG_HOLDING_NREGS];
    . d% X3 ?  w* g" Q

  17. 2 y9 }3 j/ Q9 v* R4 B
  18. //输出线圈点
    $ q& B! U( ?% K+ w/ r8 d! q' s3 B
  19. #define REG_COILS_START 3001# G2 f( C* ^4 o" L9 f1 C
  20. #define REG_COILS_SIZE 4
    / o5 A3 c0 |1 ]1 ?- {2 Y3 G, E

  21. / y- C8 |( X, a" a& V
  22. static USHORT   usRegCoilsStart = REG_COILS_START;
    $ ?! S# z) k# _1 i& J
  23. static UCHAR           ucRegCoilsBuf[REG_COILS_SIZE/8+(REG_COILS_SIZE%8?1:0)];
    # k; T" b3 `2 z4 M
  24. 5 K+ I) {" }! K, p2 A
  25. //离散输入点1 U% }; `+ g' l6 Y4 P
  26. #define REG_DISCRETE_START 4001
    " J+ {& H' y4 L% e3 c2 m
  27. #define REG_DISCRETE_SIZE 8
    $ \$ m/ }! y  Y( v

  28. 7 H8 l" k  a" b$ G
  29. static USHORT   usRegDiscreteStart = REG_DISCRETE_START;
    , |3 Z3 j0 ^  R" j+ a. M
  30. static UCHAR           ucRegDiscreteBuf[REG_DISCRETE_SIZE/8+(REG_DISCRETE_SIZE%8?1:0)];
    0 H8 F  {+ c6 k' Y0 S" l
  31. 3 Y2 i+ ?: B2 L% ^+ c1 X% K
复制代码
9 F) n' w2 q3 J
主程序就是标准的运行三连+IO读写。- D4 |) E5 R' K' W! q) O( m
  1. eStatus = eMBInit( MB_RTU, addr, 0, 9600, MB_PAR_EVEN );8 f- L0 R! U& N5 f1 J- R$ E/ b& Z+ L' |
  2. 9 Y) R" ?' @( t5 @
  3.     /* Enable the Modbus Protocol Stack. */
    + J  `7 r% P  Y
  4.     eStatus = eMBEnable(  );
    : C: G; J) l0 e& g
  5. 6 ~0 ?6 o0 G0 V$ R% ~
  6.     for( ;; )9 G8 r, [/ n* W6 N
  7.     {
    7 ?! X4 v9 I; l! ?0 y) C* C  K
  8.         ( void )eMBPoll(  );8 I" A4 ]: P& U% I, {
  9.         usRegInputBuf[0]=Get_Adc_Average(8,10);
    5 g- \( \3 X" U  Y' f
  10.         usRegInputBuf[1]=Get_Adc_Average(9,10);6 v4 D/ H" r1 _
  11.                         ) }, h' z2 z! t8 P$ [
  12.         ucRegDiscreteBuf[0]=(GPIOB->IDR&0xFFFFFF00)>>8;
    ! G' C1 p9 x# i& m) s4 Q+ b
  13.         GPIOB->ODR=GPIOB->ODR&0xFFFFFF0F;
    & Z* w0 w4 P+ ~( {
  14.         GPIOB->ODR=GPIOB->ODR|ucRegCoilsBuf[0]<<4;# |1 r6 E4 j+ v
  15.     }0 m: x, O1 k8 v" n
复制代码
( ~; I( ?0 k, B' f# z4 u! e  ?
支持的4种读写function扔在主函数后面就行了。
0 J" F7 [1 B$ \" @& H' p: D8 q
  1. /**
    ' p. M" x* M) k% M
  2. * @brief 输入寄存器处理函数,输入寄存器可读,但不可写。  K. s  U) L/ o0 u; f
  3. * @param pucRegBuffer 返回数据指针4 I1 D* u+ D. K; b" M( W, R
  4. * usAddress 寄存器起始地址# M. }* Z  I- ?+ `4 [- _# W9 \( g
  5. * usNRegs 寄存器长度
    : P( [, e  Q; e6 r
  6. * @retval eStatus 寄存器状态
    ) G( ]& Z# B& k& z. S& l
  7. */- F, ^% r5 b3 o# o
  8. eMBErrorCode
    ' A/ b+ [2 j) K! f. _
  9. eMBRegInputCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNRegs )
    + A! `6 Q4 W% @: ~* u
  10. {& b7 M7 X) q" J# h8 d4 B
  11.     eMBErrorCode eStatus = MB_ENOERR;5 A2 x5 n* F: ^
  12.     int16_t iRegIndex;3 k. `$ z( }+ r1 B* x
  13. 1 {/ u6 ^, j* I/ K( [; U6 W5 S
  14.     //查询是否在寄存器范围内
    # P9 Z7 P% ]7 [5 c. R" Q
  15.     //为了避免警告,修改为有符号整数5 c; r$ D9 e4 b
  16.     if( ( (int16_t)usAddress >= REG_INPUT_START ) \7 f; m7 `" ?: }1 X
  17.             && ( usAddress + usNRegs <= REG_INPUT_START + REG_INPUT_NREGS ) )
    # P: m* @8 p/ V- o; A6 E+ y3 Q2 Q
  18.     {
    ) ^, w- t7 _0 k6 @$ I* w
  19.         //获得操作偏移量,本次操作起始地址-输入寄存器的初始地址: D5 }  l  z  N6 s$ ^; w; ]
  20.         iRegIndex = ( int16_t )( usAddress - REG_INPUT_START );- }3 ~- }* a( \
  21.         //逐个赋值6 _9 S+ ^& _( |4 q) y
  22.         while( usNRegs > 0 )6 l6 k7 j4 |) a+ n5 C. w/ M
  23.         {$ w1 {! L4 h8 T. t) ^
  24.             //赋值高字节0 T5 \" g- ^% ?0 _( u: ]0 D
  25.             *pucRegBuffer++ = ( uint8_t )( usRegInputBuf[iRegIndex] >> 8 );
    ( f& l; Q! f" m- S: r. k, J
  26.             //赋值低字节9 L1 C) R- E* m  t
  27.             *pucRegBuffer++ = ( uint8_t )( usRegInputBuf[iRegIndex] & 0xFF );
    4 P  h+ O6 Z( l9 j; ]/ {
  28.             //偏移量增加7 Z0 B1 o# @5 X! V) p  w
  29.             iRegIndex++;
    - v  @5 U# g) u. h* H$ |
  30.             //被操作寄存器数量递减% r% H% w, n8 A$ H
  31.             usNRegs--;
    . |1 A3 k2 L1 P% K& d- H; v6 j
  32.         }! m* E% E' f/ \9 u
  33.     }
    ' Y1 d) [- Q, J  l
  34.     else: J. R' e8 Z7 T4 d, Q
  35.     {
    # P& U3 _4 |7 o9 S( E$ e7 o
  36.         //返回错误状态,无寄存器
    , Z2 D0 A- A1 N$ y) F- h6 H% D
  37.         eStatus = MB_ENOREG;
    ' g( G! b0 g% E* [7 ]: l
  38.     }
    : n. c2 O& R1 O* {4 B5 l8 w
  39. - p8 N) [  v! I3 e5 C
  40.     return eStatus;
    ! Y2 x& P5 }. T0 w9 ^% |
  41. }( l  m1 W  _! F  w' k# R' z8 H' \
  42.   u- N: R3 k, @5 h, \! v
  43. /**: I, |4 e4 q( U/ v
  44. * @brief 保持寄存器处理函数,保持寄存器可读,可读可写
    8 V& I( Z% f# t$ C, I, F
  45. * @param pucRegBuffer 读操作时--返回数据指针,写操作时--输入数据指针
    * \8 s, Q; r' U' U
  46. * usAddress 寄存器起始地址
    4 H3 m4 R+ T4 M' ]% J* E  q& f5 z
  47. * usNRegs 寄存器长度
    , x( r8 U( T, W* S4 `
  48. * eMode 操作方式,读或者写% b3 x1 @. ?' R. D- ^5 I
  49. * @retval eStatus 寄存器状态
    0 f: ]& `7 M1 M. U
  50. */
    : e& p) Z( N0 f0 Q, }& ~- l
  51. eMBErrorCode; C5 l- r* A2 H
  52. eMBRegHoldingCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNRegs,) B1 N- Z  k. F' x6 K
  53.                  eMBRegisterMode eMode )
    3 L! c& K6 X& L9 p* K2 r
  54. {- e$ r  G) O( x! N" f) E* `
  55.     //错误状态9 D2 R6 h, A( p. l+ [/ Z8 V
  56.     eMBErrorCode eStatus = MB_ENOERR;+ \- x% }* U* s/ s" W
  57.     //偏移量1 o: w  c* X, N5 h+ g( t
  58.     int16_t iRegIndex;
    . f: M& N/ Z- U1 g6 W! H$ [
  59. " ~$ h  u- ^9 A$ G8 S. w2 s2 @) `; ^9 `7 Z
  60.     //判断寄存器是不是在范围内, [! ^# ~2 q/ c* i
  61.     if( ( (int16_t)usAddress >= REG_HOLDING_START ) \/ P- }1 ~$ w  F# y6 ]0 x9 N+ d( c
  62.             && ( usAddress + usNRegs <= REG_HOLDING_START + REG_HOLDING_NREGS ) )
    ' [5 i* S8 q. j" j0 d3 p
  63.     {; X- |8 }+ |# P
  64.         //计算偏移量
    ) L; X- h4 L0 B8 b
  65.         iRegIndex = ( int16_t )( usAddress - REG_HOLDING_START );, ]# I6 p# F* g* ^$ h

  66. 3 J( D* x8 j* ?  Y; I+ t- P
  67.         switch ( eMode )8 ~; p+ k* k" L2 C
  68.         {- c$ q7 @% p/ G
  69.         //读处理函数1 t% n3 a  X" g, \1 Q! k
  70.         case MB_REG_READ:9 B5 ~2 U4 Q+ K) W; S* Y% p3 P& X. J
  71.             while( usNRegs > 0 )/ {% j+ I7 W5 V3 I* x/ I: k/ R
  72.             {
    / w. k( |. X( @5 P6 ]) Y/ s
  73.                 *pucRegBuffer++ = ( uint8_t )( usRegHoldingBuf[iRegIndex] >> 8 );+ O7 a: q3 L$ A/ L7 ?# H
  74.                 *pucRegBuffer++ = ( uint8_t )( usRegHoldingBuf[iRegIndex] & 0xFF );+ Z5 X7 [. s+ O0 ]2 X
  75.                 iRegIndex++;
    : F- Z2 e0 D7 N( Z# y. @
  76.                 usNRegs--;
    " P% }. k; D: O  A1 N8 _
  77.             }3 M# O" Y# h7 v0 d2 j- w. e
  78.             break;, x4 }! ]: K6 U1 J7 `1 N) \
  79. . `; ?8 d' E& v, M
  80.         //写处理函数
    / I) D; @# K! ?/ n
  81.         case MB_REG_WRITE:
    6 {. g2 ^8 C- S/ W5 q5 d8 @8 d
  82.             while( usNRegs > 0 )
    3 B- a; F; J8 w: V: t* z& L. O
  83.             {$ ]" Q& Q/ t" D& K3 a
  84.                 usRegHoldingBuf[iRegIndex] = *pucRegBuffer++ << 8;2 C/ w! ^' {' D, Y' O2 B+ ^4 m
  85.                 usRegHoldingBuf[iRegIndex] |= *pucRegBuffer++;
    ; `9 F9 M" f; D6 L! ~, q; q- D
  86.                 iRegIndex++;
    9 V) @9 n9 j1 Q0 h* w! {5 ^" O
  87.                 usNRegs--;5 c; ]% O0 G" O, ^; w
  88.             }
    5 D3 E) j( U) {4 }7 B$ N" Y
  89.             break;
    . V% ], J( s/ y# d2 E
  90.         }
    , Y  O( a  E, v0 w2 E
  91.     }
    / T! ]( u/ V; L, [# v
  92.     else
    2 w8 Q* W5 |/ S) K6 Z8 o
  93.     {1 z) ^3 J' V: y: `% O3 G8 r
  94.         //返回错误状态( t) `/ V* p4 f% L
  95.         eStatus = MB_ENOREG;4 ~/ l9 m8 e* \( ], j
  96.     }
    ( o& ?  e  R4 _4 F6 A. L

  97. - k1 E& I/ w. G9 m- E9 b" G/ O! a
  98.     return eStatus;
    7 ?/ k* h5 B5 ]" E1 P! [6 S: i
  99. }! I' u" A9 H; o3 ~. i
  100. ; C) q" s3 ~# [
  101. . h/ O9 X; E. t$ |
  102.   d" Y; k& O+ X! {& j( G
  103. : D0 P& ?. {: T# d+ ]: }: z2 v3 u
  104. /**
    0 Y, G8 }: m  Z
  105. * @brief 线圈寄存器处理函数,线圈寄存器可读,可读可写
    , |6 q. ~* L$ S- e
  106. * @param pucRegBuffer 读操作---返回数据指针,写操作--返回数据指针
    ( h1 k# N) T) h# h3 l, g
  107. * usAddress 寄存器起始地址
    + E& @" ^5 d" d+ j  A: M8 S
  108. * usNRegs 寄存器长度
    / b) @" y$ P: B: L
  109. * eMode 操作方式,读或者写
    , Q2 S& r& l. _3 A
  110. * @retval eStatus 寄存器状态
      F7 g) M' k, @9 Q% @, [4 }
  111. */
    , w) {9 Q/ d, o7 o5 z( d( U# D
  112. eMBErrorCode
    # k9 B- N8 \: S( O
  113. eMBRegCoilsCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNCoils,! @, T9 E, |5 z; m! _) a
  114.                eMBRegisterMode eMode )
      U6 _$ P0 o& f1 ^9 G
  115. {
    2 x- T/ p+ [" s* h4 ^1 D
  116.     //错误状态
    4 l+ P' \: |* L* l
  117.     eMBErrorCode eStatus = MB_ENOERR;* R# D$ v8 i' C* p. Q1 D( V7 X: o
  118.     //寄存器个数
    5 p% ^. g1 T" t
  119.     int16_t iNCoils = ( int16_t )usNCoils;: Z6 B3 Q, O0 J" I3 t2 Q
  120.     //寄存器偏移量1 y. f- T. C; J) s. r
  121.     int16_t usBitOffset;  d  x/ G9 E" l( l) c6 l& L
  122.   {: x' K% o( e
  123.     //检查寄存器是否在指定范围内) ~, u9 ~; m, r, }
  124.     if( ( (int16_t)usAddress >= REG_COILS_START ) &&
    * v2 L. Y- r( F4 v2 O% P
  125.             ( usAddress + usNCoils <= REG_COILS_START + REG_COILS_SIZE ) )* U7 q' N6 ^$ ?2 H9 |
  126.     {5 C5 y7 k) a$ r6 d
  127.         //计算寄存器偏移量4 ^0 O* _0 j1 ]/ D7 h1 T+ C2 ]
  128.         usBitOffset = ( int16_t )( usAddress - REG_COILS_START );& l8 t$ @! ?6 d. Y7 f) |5 X7 V8 Q
  129.         switch ( eMode )
      X* ^0 m1 y8 m- H" m2 O  t
  130.         {* B7 H% m$ O% K# i
  131.         //读操作
    + O; q2 @/ v: |$ L1 X
  132.         case MB_REG_READ:: c& u1 |5 U1 X  ^3 T2 T# b
  133.             while( iNCoils > 0 )6 k9 a2 P; h9 E2 S# I3 ~
  134.             {
    * `4 A0 {2 B8 n3 [
  135.                 *pucRegBuffer++ = xMBUtilGetBits( ucRegCoilsBuf, usBitOffset,- {2 q( z% d3 p
  136.                                                   ( uint8_t )( iNCoils > 8 ? 8 : iNCoils ) );
    / _4 n2 G+ T; Q8 ^4 M$ l8 h
  137.                 iNCoils -= 8;) U* Q" z- `- r/ w7 l2 @* a- r! D
  138.                 usBitOffset += 8;
    / c. B+ \& h' o( B
  139.             }
    ' K/ Q, i* [) @) _) B6 a2 V1 @
  140.             break;
    ( |2 z  k9 R8 Q& D1 N# I# X. |

  141. & l5 {3 d; d: y! d& Q5 f8 Z, a( S9 E
  142.         //写操作
    $ H' u+ R# [5 G# T, i# A- K
  143.         case MB_REG_WRITE:& C7 x  s  m2 D7 `- i( B
  144.             while( iNCoils > 0 )0 F1 R9 w6 K  [
  145.             {' u' y0 q: C, D' P* x
  146.                 xMBUtilSetBits( ucRegCoilsBuf, usBitOffset,
    ; j! r: \6 m  i2 O2 o0 }7 P% b
  147.                                 ( uint8_t )( iNCoils > 8 ? 8 : iNCoils ),
    5 i* S8 K/ a' `! q. K$ z( @
  148.                                 *pucRegBuffer++ );9 O" N, |# c7 D0 _$ r
  149.                 iNCoils -= 8;8 l& t: Q$ c( W+ T- m- U
  150.                 usBitOffset += 8;
    $ \% C) q& N* j6 u
  151.             }( d/ ~" \, J% j, G5 a4 c
  152.             break;
    % A# s6 u: J3 i/ Q6 L$ V4 L, n# k
  153.         }
    2 u( Y/ Q, V5 h6 g5 W. T4 ]

  154. % i; O9 S& c+ [& I1 L# [: X
  155.     }
    / U& H7 s" X: L9 S) P
  156.     else* |8 w' ]% P5 g1 H. @" E! m: i& d
  157.     {
    $ U! v1 y- C/ g/ W. K# |9 N, L
  158.         eStatus = MB_ENOREG;
    : s% G  }3 M6 }* b
  159.     }7 @7 p7 x8 j& ]+ E4 a' C% e
  160.     return eStatus;
    ( W( z3 D! c; E& _% R4 H- {
  161. }
    8 [$ f" ?2 K: b0 u+ {

  162. + H& T; e3 l. `) ~9 D9 d6 F
  163. 2 x2 v5 P# u0 f) b9 N) A  Q. x! F

  164. 0 b& o% x. @& `" R# q

  165. * K& i; u! Z" a; v
  166. /**/ h( W% g  C  e
  167. * @brief 开关输入寄存器处理函数,开关输入寄存器,可读7 w9 i  h9 E! E6 n9 L3 I4 S9 d1 i
  168. * @param pucRegBuffer 读操作---返回数据指针,写操作--返回数据指针
    $ E; @% i* |/ Y; e
  169. * usAddress 寄存器起始地址' I1 ~4 d: d8 S9 I% ~' @
  170. * usNRegs 寄存器长度& E- m: H4 d% S& w! J2 X4 R
  171. * eMode 操作方式,读或者写
    8 D! D2 M; `9 ^" @& w
  172. * @retval eStatus 寄存器状态
    # J9 M% t3 U" I2 L9 V6 {
  173. */7 q8 g$ X3 z% B" P! v- q
  174. eMBErrorCode
    & z# B; w  W2 K
  175. eMBRegDiscreteCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNDiscrete )) B4 j  V- [9 p) B/ j4 M  U0 M
  176. {/ _: j7 D  p6 e9 h
  177.     //错误状态! F$ o. w% \. e
  178.     eMBErrorCode eStatus = MB_ENOERR;
    " H0 W0 ^" u5 @7 F, e& x" ~
  179.     //操作寄存器个数
    6 }9 K! q+ z& Y. z# B
  180.     int16_t iNDiscrete = ( int16_t )usNDiscrete;, k$ ~+ d. X0 g( A. f' [- l: }
  181.     //偏移量1 R5 d" m1 B8 j4 D* s& g! w
  182.     uint16_t usBitOffset;
    # L9 `$ \: ]7 K& `$ `

  183. 9 f4 j8 W9 a( q/ l' ^1 d0 [. Y
  184.     //判断寄存器时候再指定范围内
    " m4 G+ N6 W, j9 ~# K
  185.     if( ( (int16_t)usAddress >= REG_DISCRETE_START ) &&
    + y' D3 }; F. V$ e; U; {, ~
  186.             ( usAddress + usNDiscrete <= REG_DISCRETE_START + REG_DISCRETE_SIZE ) )9 [. {0 Y, h2 _0 n: }" ]" b
  187.     {
    1 [0 s' Q; D; z& l2 U3 }3 ]
  188.         //获得偏移量  Y7 o& b4 C$ C3 A
  189.         usBitOffset = ( uint16_t )( usAddress - REG_DISCRETE_START );" i5 c0 l$ ^+ S% k# m1 i+ g
  190. % l2 ^5 y8 P8 j/ S, I
  191.         while( iNDiscrete > 0 )% c( s: T1 t, q- I/ w
  192.         {
    4 ]$ {: i1 h4 Z/ Q& y& k( v
  193.             *pucRegBuffer++ = xMBUtilGetBits( ucRegDiscreteBuf, usBitOffset,5 X. F' y+ S" ^- f- `6 y' H' G
  194.                                               ( uint8_t)( iNDiscrete > 8 ? 8 : iNDiscrete ) );$ j1 `2 J: q3 G6 _0 b5 G) m$ l
  195.             iNDiscrete -= 8;
    , B9 v0 C( S9 v
  196.             usBitOffset += 8;2 D- v4 Y# Y7 F" ^! a! R# d
  197.         }4 S3 L2 c# E- O* O

  198. + R  l8 M( h. B: u
  199.     }
    ; w. J' m6 j" x
  200.     else9 o) `) u, C) `2 W! @0 Q/ K
  201.     {
    3 L0 ~, r; P3 u
  202.         eStatus = MB_ENOREG;/ ]4 m1 `9 `# r$ r
  203.     }
    0 d& `; {0 y0 v' @% B+ q! ~
  204.     return eStatus;
    0 l. t- @4 `9 o2 I3 ?6 y! g: _$ q% l2 E
  205. }5 H( t+ Y' c$ s- g
  206. $ j7 b, y! s5 w* g( S* T

  207. % |7 [5 z$ y1 v8 g# i$ m
复制代码

; K" \4 g: m) y  i% o1 Aporttimer.c是和定时器相关的实现接口,计算好预分频与装载值之后,可以直接调用原子例程。  v2 l( C/ U# }) B
  1. /*
    ' o% P  o) X4 Y, r
  2. * FreeModbus Libary: BARE Port& X' L1 i9 s$ B8 |$ r# E3 T+ C' \! A
  3. * Copyright (C) 2006 Christian Walter <wolti@sil.at>
      l2 U1 a& N9 }& f
  4. *  Y& F" b) k. ]2 v, s( Y: a+ ]9 N
  5. * This library is free software; you can redistribute it and/or( _8 T9 l/ c! g4 s" x
  6. * modify it under the terms of the GNU Lesser General Public0 H7 F" T3 z/ @
  7. * License as published by the Free Software Foundation; either3 B/ B3 ^" u2 [+ s3 \
  8. * version 2.1 of the License, or (at your option) any later version.9 F. l# b8 X* M. ]  j
  9. *
    : t' U! K. [0 e8 ]7 R( Y. `
  10. * This library is distributed in the hope that it will be useful,* u3 M% |6 j, ?3 N' w( v* l
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
    : W. m- |2 c$ v
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU( e. D. D) F6 @
  13. * Lesser General Public License for more details.
    % ?& y& T0 E1 l* U6 M/ p7 M
  14. *
      i# y  R, S6 X
  15. * You should have received a copy of the GNU Lesser General Public: Z6 a4 r* W0 i& k  z7 w- `# ~8 _
  16. * License along with this library; if not, write to the Free Software
    0 E( @, T# m' k. Q3 k, a
  17. * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
    ' L. p, p+ ~7 t  `
  18. *
    % u6 m+ h# E4 @% b6 y! B
  19. * File: $Id$- M5 k; r  d3 D& p
  20. */
    9 x- t9 N# |: ?! @- m- p
  21. + j7 h/ U# u" R5 h: A
  22. #include "port.h"
    8 F4 s- F" Z  ^. X$ k; ~
  23. / P1 t" O. `, j: P9 [0 s( G
  24. /* ----------------------- Modbus includes ----------------------------------*/% U0 o5 X3 C) u* F6 Q2 k' ^  t. h
  25. #include "mb.h"4 v# u' ]  {/ V8 g9 \- Z8 E
  26. #include "mbport.h"+ `- q, T  b! \' |1 A

  27. 6 a3 m! T* U$ {7 C
  28. #include "rs485.h"
    / u2 r) X2 c& V. e
  29. 1 S9 i! v+ h1 i2 u4 J/ s7 O; O0 f3 N
  30. /* ----------------------- static functions ---------------------------------*/
    / g8 ^) ^" J8 a6 s! y) {
  31. static void prvvUARTTxReadyISR( void );
    $ r  J# ^8 y$ u. F$ [' K
  32. static void prvvUARTRxISR( void );1 d/ ~) _* h) {! r9 e2 J) x

  33. 0 X4 E4 e: w9 I* L" `# w" A
  34. /* ----------------------- Start implementation -----------------------------*/0 U2 i- h% d4 O$ Z5 v5 I
  35. void# W% d" n: R) U8 N, j2 x' `: g
  36. vMBPortSerialEnable( BOOL xRxEnable, BOOL xTxEnable )# b/ W" p7 p4 u. m" H6 \$ S
  37. {
    + c- r4 M4 h; h$ K+ `& e
  38.     /* If xRXEnable enable serial receive interrupts. If xTxENable enable
    2 Y2 B: t) u; M
  39.      * transmitter empty interrupts., l- R7 z2 r5 U: g. m/ v
  40.      */
    . w5 A# b1 T3 G! {
  41.     if(xRxEnable)
    & G* [. [8 t7 G1 i
  42.     {, v2 ]3 `+ B. S4 J  B) Z7 s
  43.         //使能接收和接收中断" x( Y7 X2 I9 D4 A
  44.         USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);
    ( d8 T; Y( b+ @( ]% u5 ?# y
  45.         //MAX485操作 低电平为接收模式2 O% l$ f5 C: B; ?- p) `# O4 n
  46.         //GPIO_ResetBits(GPIOD,GPIO_Pin_8);& @& p! L* c2 `( o3 P0 \4 Z- C
  47.         RS485_TX_EN=0;6 C3 E" _; S; [+ `" f, @
  48.     }
    9 w; Y  O1 ~& g8 z* v% S0 b9 c5 T  d
  49.     else
    & T1 }9 h( q  ]$ ~1 \
  50.     {! b6 Y/ ^3 z7 D0 O
  51.         USART_ITConfig(USART2, USART_IT_RXNE, DISABLE);  w; t5 N$ a& z5 Z# N) g' J- \. I
  52.         //MAX485操作 高电平为发送模式
    4 d& @3 P5 y. {9 `# C/ m
  53.         //GPIO_SetBits(GPIOD,GPIO_Pin_8);
    ' |) S; W. A0 Y- ]
  54.         RS485_TX_EN=1;1 O# R; c7 `! u- B8 h! \* M) c
  55.     }' H5 [) [( w% h

  56. 0 }3 X/ v# H9 u- T  l- |$ e
  57.     if(xTxEnable)
    , f2 ]& W0 \- Y2 ]' U
  58.     {
    : X7 J) @/ f) h% A  E# p
  59.         //使能发送完成中断" G1 P- {' c8 e8 [
  60.         USART_ITConfig(USART2, USART_IT_TC, ENABLE);
    - a0 T3 }0 j, L0 t
  61.     }2 j3 g5 j3 Z9 X# T; w
  62.     else3 ]8 b) }! k/ d! r) N8 Y: F
  63.     {
    2 W  y$ w" E5 L0 K; o0 s
  64.         //禁止发送完成中断
    4 F1 M% g2 c$ `" I) G
  65.         USART_ITConfig(USART2, USART_IT_TC, DISABLE);8 r* E9 m) x; U  y
  66.     }
    3 {, j# I3 T; f$ k! [( T0 ]1 }# b

  67. ' X' ^9 N) O- m

  68. # P* q" I$ U( K9 {/ O$ c# a
  69. }7 c. ^4 F9 ?2 R. v
  70. 6 z6 z9 Q: s0 @9 ~; j
  71. BOOL6 L2 i$ t. ~' @1 L3 R0 m. Y0 G
  72. xMBPortSerialInit( UCHAR ucPORT, ULONG ulBaudRate, UCHAR ucDataBits, eMBParity eParity )
    3 w# L. T* a7 \' h
  73. {9 r/ Y) q: j# d' d8 N' D
  74.     RS485_Init(9600);        //初始化RS485
    # R0 _( U2 s, J
  75.     return TRUE;/ E! |* {: v4 R1 _# J  o9 w
  76.     //return FALSE;2 H9 _/ n% I! Z" W/ C% U
  77. }
    6 R9 X1 b4 h4 q$ g% F$ ~# Y' A" w/ b
  78. / s6 Z8 f6 j' ^* I
  79. BOOL# {. h/ R& P; T. l( ^  \% ]9 D
  80. xMBPortSerialPutByte( CHAR ucByte )2 L7 C: k& k% J8 e$ U- ?5 ~9 |
  81. {4 r+ k' a- Z8 E8 a" c  @
  82.     /* Put a byte in the UARTs transmit buffer. This function is called7 b) G9 h' l' C- U
  83.      * by the protocol stack if pxMBFrameCBTransmitterEmpty( ) has been
    " |' w) \! |6 N9 X# D2 @
  84.      * called. */
    " p% {2 s$ ?9 }6 D5 \
  85.     //发送数据
    " M7 A* z! r9 ]. s* [- Y
  86.     USART_SendData(USART2, ucByte);$ j, r# Z$ P! o# \
  87.     return TRUE;7 P/ p! i  X& i1 F1 l+ r
  88. }* i* d6 O2 F) G6 R! a
  89. " G2 w' v* }) E9 ]$ h8 g
  90. 1 U+ o" V# @* T4 G
  91. BOOL
    0 [/ ~1 c" _' q7 A& X5 h" U
  92. xMBPortSerialGetByte( CHAR * pucByte ). [& g  R# U+ n+ ~
  93. {. e: u. f: a: }
  94.     /* Return the byte in the UARTs receive buffer. This function is called; x0 a5 o  a* u2 e: p* D9 D2 |3 j* j5 @
  95.      * by the protocol stack after pxMBFrameCBByteReceived( ) has been called.1 ]3 W/ i) T7 E* m! \# m6 P
  96.      */
    7 Q3 A5 R! }+ Q: w" T0 b, Y) c! [
  97.     //接收数据' ]' n: n; Q% t$ t
  98.     *pucByte = USART_ReceiveData(USART2);
    2 f1 _# d9 n5 ?2 n7 I, \5 ~
  99.     return TRUE;' S4 ^" F5 L& O! [* c$ y
  100. - k# y! k, a3 I5 c$ U& j# I" b/ ?
  101. }
    * e  `  `! q& o; g, F9 C

  102. ; Q# k0 O2 B. _; P# e
  103. /* Create an interrupt handler for the transmit buffer empty interrupt
    ( ?. k3 T" q& I6 S" h
  104. * (or an equivalent) for your target processor. This function should then1 Z1 Y0 _2 Z# @% z+ M6 ]
  105. * call pxMBFrameCBTransmitterEmpty( ) which tells the protocol stack that
    1 V7 N) A( Z+ S  S0 E
  106. * a new character can be sent. The protocol stack will then call( Q- m$ R. p" B$ M. E
  107. * xMBPortSerialPutByte( ) to send the character.3 ~) H% }; g+ f# _3 d
  108. */2 b: D5 h( F6 `! F; `" d' z8 y5 r2 m
  109. static void prvvUARTTxReadyISR( void )2 j+ o6 q( ~5 V
  110. {! r( I) E9 n; t& V6 S0 h; K
  111.     pxMBFrameCBTransmitterEmpty(  );4 O4 J  f% z  a9 z5 L$ f
  112. }' z0 V1 Y3 Y' D, J# H
  113. 1 z( n6 j3 {% m1 a( E! h
  114. /* Create an interrupt handler for the receive interrupt for your target
    ; b0 S7 R& X, |: H7 \; A
  115. * processor. This function should then call pxMBFrameCBByteReceived( ). The
    . r. l- ~( l4 j  h; p
  116. * protocol stack will then call xMBPortSerialGetByte( ) to retrieve the# u; q7 @- I' a
  117. * character.) |( Q' f) t4 K
  118. */8 h6 O/ s( x0 q8 j- T
  119. static void prvvUARTRxISR( void )0 x, A0 x" h, b1 u
  120. {
    # L; F! m! g4 Z! h  E' N5 k
  121.     pxMBFrameCBByteReceived(  );! _) V0 M3 M& Y, ]& A- L5 Z
  122. }1 Y' M9 O, O) k* j+ D* f* T% K

  123. $ K- x/ T- d& l4 J, d! d9 A; S
  124. void USART2_IRQHandler(void)
    + c" o( V, s1 @# E4 E6 t
  125. {) P% a) \$ P: n. u7 b' S
  126.     if(USART_GetITStatus(USART2, USART_IT_RXNE) == SET)4 ]. {3 L; b3 [) f( C! Z0 C
  127.     {3 }" f3 b* J7 {- ^3 R+ v: w, S# Z
  128.         prvvUARTRxISR();
    7 M; s# B' [3 I+ ?" v; l5 `5 d/ J
  129.         //清除中断标志位& ^+ Q# A5 l* J9 [& `* h. f$ n0 i
  130.         USART_ClearITPendingBit(USART2, USART_IT_RXNE);
    , l3 H! y6 E$ `' |# S
  131.     }5 r, s1 x. e# e
  132. & s8 g+ `4 M9 ~# J& k5 c
  133.     //发生完成中断
    8 `& T; a- w& ~( a( K( J
  134.     if(USART_GetITStatus(USART2, USART_IT_TC) == SET)4 f  h$ w* r! K+ W- F: U3 _
  135.     {
    / a' I8 V! |% o
  136.         prvvUARTTxReadyISR();1 _" Q" K& [! n0 s) w
  137.         //清除中断标志5 @$ q1 T6 A. d  q; M$ O! S
  138.         USART_ClearITPendingBit(USART2, USART_IT_TC);
    % X4 R2 ~$ `; R4 z
  139.     }
    $ I/ \: D9 Q! r4 x8 A

  140. % e5 K7 Q' w' A5 _1 G
  141. }" E  ?- x: h% Z0 c" J

  142. % R/ L" O! t* r: u% e
复制代码
3 X) }: H  S( t' X( R
modbus移植过程基本就完成了。
7 \9 R! T/ Q4 _+ \+ S, t————————————————$ n" [) _2 W% J' w4 V) T# s
版权声明:小盼你最萌哒( U+ N' U8 z$ \/ i- k4 K
如有侵权请联系删除1 K# _! g, b' k$ D1 @9 b7 w
) a- Z! y$ F6 V, [: x. V
% w7 V4 g6 b0 H6 S. k# D' g7 B5 i
赞 收藏 评论0 发布时间:2023-3-14 16:54

举报

0个回答

所属标签

相似技术帖

官网相关资源

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