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

如何在裸机stm32移植FreeModbus

[复制链接]
攻城狮Melo 发布时间:2023-3-14 16:54
官方下载freemodbus-v1.6.zip源码,然后把源码中的modbus文件夹、demo\BARE\port文件夹导入工程。
1 k9 v3 x$ E' S
0 P4 y+ z) F3 \8 c. A
先是一波无脑导,把文件夹里所有文件导入。
+ Q1 ?' B! O$ i  e- P

; N5 ?  ~, U8 a' X0 }9 V: w存储区配置,单片机上定义的起始地址要比实际通信过程中读写的地址+1。! C2 {- x# X1 H5 |- M4 O/ s
  1. #include "mb.h"8 D3 `% y* d/ P! Q' }
  2. #include "mbport.h"2 A0 ^) i! V/ r0 F$ n
  3. #include "mbutils.h"* r( O$ O4 E, d9 _; }5 G
  4. //输入寄存器7 v0 b% f/ W4 I+ ]7 L, `5 \
  5. #define REG_INPUT_START 1001
    & C9 l+ u2 @- Y0 [8 W
  6. #define REG_INPUT_NREGS 2
    / Q$ g) g8 [8 m  p! D: |5 j' J% F
  7. 5 r* _6 ~) F8 ^4 h7 _- J6 i
  8. static USHORT   usRegInputStart = REG_INPUT_START;5 t+ W& r! S" P  s' E6 S* {# P
  9. static USHORT   usRegInputBuf[REG_INPUT_NREGS];- Q+ Z( c2 i/ v/ ]

  10. 3 o# X5 N! \' C- B; d
  11. //保持寄存器5 R  X" h7 f2 N, m) X" q3 e% i3 n
  12. #define REG_HOLDING_START 2001
    , `( @6 |* y, l& `  Q6 V( }
  13. #define REG_HOLDING_NREGS 1
    4 k1 O$ e. G0 m! P. P

  14. $ J% o6 J5 F! @5 K/ [& n- j
  15. static USHORT   usRegHoldingStart = REG_HOLDING_START;+ @9 ?$ ^. E; z8 x; l$ p) d
  16. static USHORT   usRegHoldingBuf[REG_HOLDING_NREGS];% D  p9 B8 I/ b) h1 u/ t7 N: }+ X% x
  17. ' z! `0 j6 r/ a8 @. K' ]
  18. //输出线圈点+ U8 O+ }% K$ a" r) n( i2 F
  19. #define REG_COILS_START 3001) y5 H* v) |( o7 Q/ V0 z) H' I9 @
  20. #define REG_COILS_SIZE 40 D! a& j7 N1 e+ T) d" A) j

  21. % D; i: c+ T9 T
  22. static USHORT   usRegCoilsStart = REG_COILS_START;
    * B5 g! o) J' q- @
  23. static UCHAR           ucRegCoilsBuf[REG_COILS_SIZE/8+(REG_COILS_SIZE%8?1:0)];- O& e  u% L! Z
  24. $ I% ?% L( j  q$ W
  25. //离散输入点* M- t" Y8 {  g: |" E3 o
  26. #define REG_DISCRETE_START 4001
    8 k( \: E) [: T
  27. #define REG_DISCRETE_SIZE 8
    2 ~. h3 b8 N2 G! y4 u3 ~* x0 q

  28. : x* _" W( F3 B2 J  J& ]3 |+ i
  29. static USHORT   usRegDiscreteStart = REG_DISCRETE_START;) x+ s6 M' }: r8 O- @- o  v, t; R& T
  30. static UCHAR           ucRegDiscreteBuf[REG_DISCRETE_SIZE/8+(REG_DISCRETE_SIZE%8?1:0)];
    ; J/ y; e9 [* T# G" ^

  31. 3 E4 ]% k( Y& l4 q" \9 q
复制代码

. A) {9 F: p6 l! d主程序就是标准的运行三连+IO读写。; w! X2 \8 U$ a1 n3 Q! F" F7 b
  1. eStatus = eMBInit( MB_RTU, addr, 0, 9600, MB_PAR_EVEN );
    9 T) V+ E2 _" w" ]. s1 @
  2. * h; `' C+ e8 R2 v- |0 v
  3.     /* Enable the Modbus Protocol Stack. */3 k; ^$ h3 T: v& L6 }2 @
  4.     eStatus = eMBEnable(  );
    # e; g% d  G' B7 Q' \9 D3 H
  5. 1 F2 E+ c8 H9 h" `) m- i) M
  6.     for( ;; )/ a, I0 V9 L- A5 T* L
  7.     {
    * p" ?% X1 o: S4 l) K
  8.         ( void )eMBPoll(  );
    3 z" F" k3 U0 E# G2 M$ G5 \+ v) o
  9.         usRegInputBuf[0]=Get_Adc_Average(8,10);
    0 y$ e. c5 h# V. i2 G
  10.         usRegInputBuf[1]=Get_Adc_Average(9,10);
      u! \) d1 H4 a+ l: l
  11.                         8 B8 L8 @' I4 M" \8 h& r
  12.         ucRegDiscreteBuf[0]=(GPIOB->IDR&0xFFFFFF00)>>8;
    1 S; y6 I2 K' ]0 @/ v5 M
  13.         GPIOB->ODR=GPIOB->ODR&0xFFFFFF0F;, |. Y8 a% M) B- D) C0 _3 ?
  14.         GPIOB->ODR=GPIOB->ODR|ucRegCoilsBuf[0]<<4;, n9 Q( `. ?0 W) w) v
  15.     }' z. T) {% M$ B! w: X$ G. F
复制代码

7 Z  D( ?( m* a& b支持的4种读写function扔在主函数后面就行了。1 b8 Z+ I5 p9 D) K7 ^
  1. /**5 x" J' \3 F9 F" H" @1 W
  2. * @brief 输入寄存器处理函数,输入寄存器可读,但不可写。
    ; u: }  d  j, J' n6 F* e/ ?* ?
  3. * @param pucRegBuffer 返回数据指针
      I3 m* V5 w: b7 B- }& ~
  4. * usAddress 寄存器起始地址( w6 D  M% p$ x6 F8 J
  5. * usNRegs 寄存器长度6 D/ W& L# ]1 G: O" S/ B
  6. * @retval eStatus 寄存器状态
    # e5 e2 I0 S0 \* Y- T4 Q5 m% \
  7. */3 C6 W. P% O4 p3 e- R# F; x
  8. eMBErrorCode: }1 \. W) D7 G; G! o* u
  9. eMBRegInputCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNRegs )4 X1 ~) q3 D# u9 l- V1 ^
  10. {2 N& d/ J) \) ~- h# _& x
  11.     eMBErrorCode eStatus = MB_ENOERR;
    $ D$ i" m; o" H% `
  12.     int16_t iRegIndex;
    5 b5 z4 u" J0 K' g7 |" b! l" n
  13. : s5 G& Y% ?0 h+ o$ s; n
  14.     //查询是否在寄存器范围内
    / p  a) ~9 l6 O  H) N& o, w- m
  15.     //为了避免警告,修改为有符号整数, z* d. [& J3 y4 H( a! J
  16.     if( ( (int16_t)usAddress >= REG_INPUT_START ) \* V+ a8 k! E% i5 m* s  M
  17.             && ( usAddress + usNRegs <= REG_INPUT_START + REG_INPUT_NREGS ) )9 i% [7 G4 S* r& z
  18.     {# M( {0 ^( F7 S: v& w3 ^7 [
  19.         //获得操作偏移量,本次操作起始地址-输入寄存器的初始地址8 F7 A( z7 L9 g# X8 b
  20.         iRegIndex = ( int16_t )( usAddress - REG_INPUT_START );
    7 ?$ w2 @# N! t" A
  21.         //逐个赋值" K. T6 [* @0 o' @7 q3 s- `
  22.         while( usNRegs > 0 )0 b# c2 h2 _5 Z+ O" R: c$ j/ a
  23.         {
    , V3 `0 r2 Y( d6 W4 \+ q6 z
  24.             //赋值高字节: Q! K8 i* G" U% f
  25.             *pucRegBuffer++ = ( uint8_t )( usRegInputBuf[iRegIndex] >> 8 );
    0 X: I2 ?8 N, x6 R
  26.             //赋值低字节
      M9 i* l; r8 t0 J, @
  27.             *pucRegBuffer++ = ( uint8_t )( usRegInputBuf[iRegIndex] & 0xFF );% k3 V* w/ l" ?' e: P# G
  28.             //偏移量增加
    : V. U. p8 O) ~) L4 e
  29.             iRegIndex++;
    + V% W1 x, y: D! V" o+ {4 o, A
  30.             //被操作寄存器数量递减
    . c$ S# Z- g0 E3 h
  31.             usNRegs--;0 u. Z. Y/ w! i; g( T' O- M
  32.         }
    5 [' f' k3 a3 @# w4 M, a% v. @: u1 Q
  33.     }* E% S1 F) P: k  I: |$ }. E4 c
  34.     else
    * O$ j8 M1 E1 m+ i4 H1 P8 d% |
  35.     {
    + h' C$ s& h3 x2 G" F5 ~
  36.         //返回错误状态,无寄存器
    & U% w. z0 z2 c1 F* E* c/ w3 j
  37.         eStatus = MB_ENOREG;
    % W( K( h6 K& R, v& F; x/ ^
  38.     }# B% j9 \/ w4 l& @- n7 X' T' W
  39. ; }+ U, _" T, X
  40.     return eStatus;. Z: z! J6 k+ k+ Y) W2 z: P
  41. }9 T& I+ b+ z1 D- d' O4 \+ E
  42. 8 r+ Z7 O3 F( X& B3 l
  43. /**0 u- H, [6 v) o/ Y' o( X7 b3 z% E
  44. * @brief 保持寄存器处理函数,保持寄存器可读,可读可写5 e4 ~1 k0 Z& a! L; Y) S9 |
  45. * @param pucRegBuffer 读操作时--返回数据指针,写操作时--输入数据指针
    # M& X9 `) r& a$ L- A
  46. * usAddress 寄存器起始地址
    + `3 J4 b+ R+ d
  47. * usNRegs 寄存器长度
    $ o( z2 j4 A. O: p/ M
  48. * eMode 操作方式,读或者写: g4 D4 W3 A$ J8 Y
  49. * @retval eStatus 寄存器状态% ~, h6 S0 w. b
  50. */7 i+ V) E  z# S- K& N
  51. eMBErrorCode$ u( p4 d, n; U
  52. eMBRegHoldingCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNRegs,* \/ |' N- [) H* A6 `2 F
  53.                  eMBRegisterMode eMode )
    8 Y& i$ C- L( q4 h) B9 p6 q7 A8 O+ S
  54. {
    2 Z" I, s/ Y4 o3 U
  55.     //错误状态
    & C: n; w% j: s$ h  l1 e
  56.     eMBErrorCode eStatus = MB_ENOERR;
    9 E! U; o" S- o) ^
  57.     //偏移量
    & P* ^" V! H) G7 ~
  58.     int16_t iRegIndex;+ l1 g, D* }, J3 D3 c* x
  59. 2 O3 _! u$ f- S& s3 |
  60.     //判断寄存器是不是在范围内& F" k9 b' H! x) N. [# K6 N
  61.     if( ( (int16_t)usAddress >= REG_HOLDING_START ) \  }' U) N8 g/ e
  62.             && ( usAddress + usNRegs <= REG_HOLDING_START + REG_HOLDING_NREGS ) )
    0 {' p' g6 E, }1 O7 F% E6 d
  63.     {
    / e$ G0 n! U. w& j
  64.         //计算偏移量* m% U5 R2 [0 ]8 f
  65.         iRegIndex = ( int16_t )( usAddress - REG_HOLDING_START );1 |- G9 Q; t0 {) i
  66. : Z1 {6 V, M9 {4 y! P7 s7 y% F
  67.         switch ( eMode )
    5 J. N' y% `5 j  y& r. z' w
  68.         {
    % a9 K' N, ]; D/ `$ {
  69.         //读处理函数8 g: @) \: _& `# a8 V5 b
  70.         case MB_REG_READ:% w9 N2 X6 |/ _* F1 f$ \+ s) D$ x
  71.             while( usNRegs > 0 )
    : q, o7 X+ S9 E, c% l; n; j! k
  72.             {6 v% ~3 j6 J+ [0 R0 t
  73.                 *pucRegBuffer++ = ( uint8_t )( usRegHoldingBuf[iRegIndex] >> 8 );
    . V; o$ N3 E& H! b& m6 K2 x
  74.                 *pucRegBuffer++ = ( uint8_t )( usRegHoldingBuf[iRegIndex] & 0xFF );
    8 O7 y, I. M. {$ |4 P! O' i
  75.                 iRegIndex++;
    ' q7 \! G/ e) Z8 E, D
  76.                 usNRegs--;! u  [$ M3 k' U/ w4 u" v- D
  77.             }
    - [; K6 x6 J5 C! N7 I
  78.             break;
      F% j* g' v. h5 d: r0 j! S
  79. 6 ^/ \+ V5 S! \' H7 u4 f) ^5 `
  80.         //写处理函数+ Y1 |6 S, h+ U: f& a5 _. x% n- j0 F
  81.         case MB_REG_WRITE:0 r6 ~- ]6 I5 F5 ^1 j
  82.             while( usNRegs > 0 )" {" }. g* r4 v& o2 Y
  83.             {
    5 ?1 g+ K. G4 d
  84.                 usRegHoldingBuf[iRegIndex] = *pucRegBuffer++ << 8;$ {5 s! D5 o" z. k: ]" l
  85.                 usRegHoldingBuf[iRegIndex] |= *pucRegBuffer++;  p+ l! k: X3 Y1 I- ^
  86.                 iRegIndex++;
    , y4 w3 }# }2 u- n, A3 c! O! L
  87.                 usNRegs--;
    + r$ F' s5 ?# I  G& U4 v
  88.             }0 ~& B) m, _1 M7 f7 h5 q$ B. {* f
  89.             break;
    / t  i3 D) v5 Q/ b
  90.         }" p2 |( Y6 M0 X" \& F+ i. }. @& ]
  91.     }
    8 [) S+ M4 x9 G" [8 q
  92.     else( Y! I; b- O: @; w" H" S6 L
  93.     {7 w0 T. J/ d9 j/ K  S  j2 ^9 K# A
  94.         //返回错误状态% J; f8 P+ f" x$ O
  95.         eStatus = MB_ENOREG;, b1 c. h/ _& \7 S+ }$ v+ ]
  96.     }! z; h* v3 }5 N9 i$ v  ]
  97. * T% M0 ]/ ?5 e5 |" W  O8 B/ G  }4 e
  98.     return eStatus;
    . t8 p- N0 Y0 `# `
  99. }% P% Q3 v8 ?5 U0 V& |% ~% o  Z  f

  100. ) A- F: y( j, O: j! ^! N
  101. & I. K4 X/ i" ]1 ~# y
  102. ; }' {2 O: F  U2 B

  103. + f* j+ O# C/ P2 f) J8 \
  104. /**
    * T6 Q& R3 Q, \: Q
  105. * @brief 线圈寄存器处理函数,线圈寄存器可读,可读可写! h, Q, m- e" P, l
  106. * @param pucRegBuffer 读操作---返回数据指针,写操作--返回数据指针
    : r1 j2 [& U1 g. t
  107. * usAddress 寄存器起始地址& [$ P: @8 U' J" v: d
  108. * usNRegs 寄存器长度
    * G1 U6 I3 i+ J' `& ~; [
  109. * eMode 操作方式,读或者写$ o' _, N! o6 G
  110. * @retval eStatus 寄存器状态
    - E9 ~4 J6 k) E* [  }
  111. */: s0 |4 v# p7 K& y* @
  112. eMBErrorCode1 E8 @2 z% t( ]
  113. eMBRegCoilsCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNCoils,
    3 x; D; K. M7 z5 W
  114.                eMBRegisterMode eMode )/ W1 L3 N+ p* g8 i" e
  115. {
    5 M$ d# y1 H7 m% d# \% r
  116.     //错误状态4 j4 g2 i, t6 g7 U) l
  117.     eMBErrorCode eStatus = MB_ENOERR;
      }3 a8 a! |6 c7 c% ?5 s
  118.     //寄存器个数. v* _) p, V: W: m# a4 z6 v$ w6 J8 z
  119.     int16_t iNCoils = ( int16_t )usNCoils;
    $ B( x# k5 y" `) f
  120.     //寄存器偏移量( Y- l0 T, M5 k6 c3 ^% S# k
  121.     int16_t usBitOffset;0 a: y6 z3 p' f; [, M

  122. % r+ p/ v; N# ]0 ?
  123.     //检查寄存器是否在指定范围内
    2 F% r  R- m) F' z, P6 V
  124.     if( ( (int16_t)usAddress >= REG_COILS_START ) &&
    9 g  Y$ w* L% ^3 U) C
  125.             ( usAddress + usNCoils <= REG_COILS_START + REG_COILS_SIZE ) )+ K. T3 \  D3 D. r
  126.     {/ ^0 d# y5 S+ E. S# @+ ^- c
  127.         //计算寄存器偏移量
    / S; }  K8 }* @  m. g# j" \
  128.         usBitOffset = ( int16_t )( usAddress - REG_COILS_START );
      I" F: i5 U; u
  129.         switch ( eMode )
    ' G' _  c3 \/ \5 p# F8 g5 ]7 z5 t
  130.         {! ]* r- G, w# e/ }- r0 ]" k, a4 V
  131.         //读操作  `( Y8 E. `3 G
  132.         case MB_REG_READ:$ G2 @4 f/ Z, J8 m
  133.             while( iNCoils > 0 )
    1 w2 C% m  J  N2 l& b7 M+ q
  134.             {* ]9 |+ `# m7 D) p
  135.                 *pucRegBuffer++ = xMBUtilGetBits( ucRegCoilsBuf, usBitOffset,
    , j+ {0 I1 M1 `! O. }# S, @7 @
  136.                                                   ( uint8_t )( iNCoils > 8 ? 8 : iNCoils ) );
    5 d- u/ F2 }8 z8 G" e" `! i; I
  137.                 iNCoils -= 8;
    ' ?8 a$ K3 \$ V* T, a
  138.                 usBitOffset += 8;% K' ^6 ~9 g5 T8 t9 g
  139.             }6 A" m' |8 r5 |0 D8 V& k
  140.             break;! b: V/ S5 M2 ~# X" o5 b* _
  141. 3 D/ H/ \1 V# m1 ~# t1 B
  142.         //写操作7 K) K+ j: Z" ^: Q
  143.         case MB_REG_WRITE:; s; j" y+ K' Y* ^' l6 a" Y" q
  144.             while( iNCoils > 0 )+ {) `3 ^( ~4 ~# w
  145.             {: Q: D* [6 y, v  B& l# e
  146.                 xMBUtilSetBits( ucRegCoilsBuf, usBitOffset,9 v$ q& W" C- [/ _+ T5 d
  147.                                 ( uint8_t )( iNCoils > 8 ? 8 : iNCoils ),
    % |: H7 ^4 E$ m3 M% z- c. b1 t
  148.                                 *pucRegBuffer++ );
    ' P6 p& X6 Y& E% W
  149.                 iNCoils -= 8;
    / ^/ y! k& c' S% Q, Z  W) o
  150.                 usBitOffset += 8;
    3 O% r! a/ V9 r8 s& m( T
  151.             }
    1 k' |* i0 n8 p$ @5 I
  152.             break;
    5 e& @. S: \/ u2 p5 ]7 H8 s# M
  153.         }
    . T/ @" @2 n% r4 Y' w2 {3 G, {
  154. 9 H* q" ]; C; I  R4 N5 Q) Z& l
  155.     }3 Q) S5 h6 ~3 _' O4 A; V8 T  k
  156.     else& f6 ^' |1 w. ~: L! x9 W& |# h, Y9 K# i
  157.     {
    5 b% p- \- g" |( x: |, k4 X* l
  158.         eStatus = MB_ENOREG;
    + M  b) S. W, h6 L9 m( h
  159.     }: W7 T5 k8 p& \+ `! o
  160.     return eStatus;
    8 d3 v& I9 y# Y# n9 Q" \: K+ f
  161. }
    9 @: J- l, F5 [, s) {* |( X1 _- s

  162. 7 f7 L4 s- Q+ f3 u3 t! B

  163. / c; a. J6 t" g8 r- |9 e1 |% J
  164. , [1 A! G& d6 q
  165. # ~1 a, f- _/ \! }, P1 d; q
  166. /**. q% q3 e# c5 @" @
  167. * @brief 开关输入寄存器处理函数,开关输入寄存器,可读
    * E, Q2 D! J3 V* T
  168. * @param pucRegBuffer 读操作---返回数据指针,写操作--返回数据指针: R6 S/ J& W5 R  i
  169. * usAddress 寄存器起始地址& Y( D9 c3 p1 O* h
  170. * usNRegs 寄存器长度" _, L+ x4 S! ~& E( c% ]4 v6 P2 Z  A2 q
  171. * eMode 操作方式,读或者写( j' B: {- U+ D2 A2 A0 j
  172. * @retval eStatus 寄存器状态( D; V6 A9 x% t. I, h
  173. */
    8 [# m  Y$ n* H! k2 E$ s# o& k# b; L
  174. eMBErrorCode( D" a& e* o8 u* F* D
  175. eMBRegDiscreteCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNDiscrete )6 c" S2 T, ~5 z9 j$ Z5 e
  176. {* @6 Y* `2 t' t. C
  177.     //错误状态8 `) T2 _4 m+ q7 Q( i
  178.     eMBErrorCode eStatus = MB_ENOERR;
    3 C) y1 N, [1 T4 D3 _( {
  179.     //操作寄存器个数; K* R7 l5 B( E. d
  180.     int16_t iNDiscrete = ( int16_t )usNDiscrete;
    : S, Z- y. J1 S1 Z
  181.     //偏移量
    $ y# c7 o' p. H
  182.     uint16_t usBitOffset;
    ) O7 F" ~: M  o& E
  183. " v5 ]  L* `2 B$ d
  184.     //判断寄存器时候再指定范围内( G; h* J! ^5 o6 `4 s4 f
  185.     if( ( (int16_t)usAddress >= REG_DISCRETE_START ) &&
    3 r1 i& m- x! I- t
  186.             ( usAddress + usNDiscrete <= REG_DISCRETE_START + REG_DISCRETE_SIZE ) )
    8 N& y( O0 D' A" [  a
  187.     {) Y1 v( ~7 w; ^+ I+ W" o6 R, [
  188.         //获得偏移量( k1 v9 ?1 i+ F* H, C
  189.         usBitOffset = ( uint16_t )( usAddress - REG_DISCRETE_START );
    " t$ m2 L4 y9 h' p7 L, ^% y6 U
  190. 5 y/ F$ S) n0 q" U; y
  191.         while( iNDiscrete > 0 ), O" _% G, ^+ {6 [+ l. g/ I) M
  192.         {
    + Z$ W, {- A  ]
  193.             *pucRegBuffer++ = xMBUtilGetBits( ucRegDiscreteBuf, usBitOffset,9 l! X# R4 E# q5 V+ J
  194.                                               ( uint8_t)( iNDiscrete > 8 ? 8 : iNDiscrete ) );0 w$ d( L, |* `5 M6 u% W
  195.             iNDiscrete -= 8;+ c7 v% q- F0 M: t8 `
  196.             usBitOffset += 8;! v7 M" Y8 Y; Q; ~8 M
  197.         }
    5 C& [6 n( @1 p* b! u+ t
  198. 4 J1 P$ d, c. k) q0 W
  199.     }2 s, }0 K5 ?& P' i1 F8 p. H- ]) x
  200.     else* q2 F  v" S4 L8 g$ h9 p  Z/ b
  201.     {
    % X6 ?& x; P$ F; M
  202.         eStatus = MB_ENOREG;
    ' ^5 W  E; G6 P, u
  203.     }; N5 I% ~$ d* H0 @8 B+ k+ z" e- [
  204.     return eStatus;/ P8 S( [1 Q- \8 v4 S! t. m6 A; p
  205. }: [5 }7 S  e2 B8 `

  206. 4 l. U6 h" i2 z$ q
  207. 8 H- B. M; u" v: X2 |' N9 ?6 y9 f
复制代码

: n0 R, `$ u+ ~& `porttimer.c是和定时器相关的实现接口,计算好预分频与装载值之后,可以直接调用原子例程。$ E1 ~; S" S# S; X: b. p+ K
  1. /*
    / j! j1 g6 g) H% H( A
  2. * FreeModbus Libary: BARE Port
    0 ]* J( ~3 l+ L$ V0 V- @
  3. * Copyright (C) 2006 Christian Walter <wolti@sil.at>! B. u. ?8 _; W! w
  4. *
    + f9 E' t  W5 |: T, F
  5. * This library is free software; you can redistribute it and/or. D5 Y6 M' [' c
  6. * modify it under the terms of the GNU Lesser General Public
    ' m' o% ?! y2 p" f1 U
  7. * License as published by the Free Software Foundation; either
    ; G: G; b9 |! G
  8. * version 2.1 of the License, or (at your option) any later version.6 J, _- l1 D$ A5 q. p8 |) P
  9. *
    ( ^; h) m9 }) j5 S+ c2 k. n
  10. * This library is distributed in the hope that it will be useful,
    ) i3 R. J6 Y2 B- Y% S
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
    ) `' m: w2 `& N( v; h  o
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    3 i( z; }: r# {9 O, m- F6 ^
  13. * Lesser General Public License for more details.8 i0 w4 I, e) q2 `  C  B4 h% k
  14. *. m; p! Z( `8 n6 `* F/ @
  15. * You should have received a copy of the GNU Lesser General Public( V2 i( u' q) N+ Q; q
  16. * License along with this library; if not, write to the Free Software
    - w0 R8 B9 d# x5 C8 l. f3 ^
  17. * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA: e6 k9 P9 p0 f. K) ^; J0 f
  18. *5 F8 C- B7 `& z: r" H! _# @
  19. * File: $Id$
    0 Y# ^. y  q/ u, q1 z* A
  20. */
    / B* u# L& @- y  C
  21. , D, F0 {4 s0 d& A4 X: \7 c
  22. #include "port.h"
    ! M+ u5 X) x# O( S, d7 N& k6 A/ L
  23. + N/ R1 G% o! e/ r
  24. /* ----------------------- Modbus includes ----------------------------------*/
    / u' P- \) b) P) |: ?) \5 ^
  25. #include "mb.h"
    ! T8 N: ]4 v6 p- u
  26. #include "mbport.h"
    5 k4 ^, G# {" z: e8 u# g# U( Z

  27. + ~! c$ a" p  Q& L# a# v
  28. #include "rs485.h", s* x  v, ]1 s
  29. 0 I+ |, w& c6 K# z& r" |: J
  30. /* ----------------------- static functions ---------------------------------*/
    9 I- m) {  x' Q! P9 I
  31. static void prvvUARTTxReadyISR( void );8 j3 e4 }  W2 n; x
  32. static void prvvUARTRxISR( void );; t( e6 l. b; \& F. O( W
  33. ' [- u; s6 r* c  I% ~" Q# Y
  34. /* ----------------------- Start implementation -----------------------------*/
    % y7 U( p/ j- c9 S" A& `+ \( |
  35. void
    ( @7 C" J: P. G! H  M
  36. vMBPortSerialEnable( BOOL xRxEnable, BOOL xTxEnable )
    + c, W: g  i  d/ x
  37. {
    2 `' g; o# I0 V  e6 I7 C6 \  E
  38.     /* If xRXEnable enable serial receive interrupts. If xTxENable enable4 i) S0 N& o" I/ y+ y& g
  39.      * transmitter empty interrupts.
    5 S8 [% m7 F$ O1 B) _; @6 A
  40.      */2 T5 y0 b* U  o# O" a% S) X% U- `* ~
  41.     if(xRxEnable)
      |4 B9 K3 @. [- F# Q7 f
  42.     {
    9 C, l1 M- R7 K, N; N3 Q
  43.         //使能接收和接收中断$ {% v3 X0 k5 W. S4 n
  44.         USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);
    + h1 Q0 `) E( a+ _2 f/ P. N9 D( m2 U
  45.         //MAX485操作 低电平为接收模式
    1 m9 U, ]6 V; y9 I5 {+ Z
  46.         //GPIO_ResetBits(GPIOD,GPIO_Pin_8);
    , d9 V: D' x3 O: r
  47.         RS485_TX_EN=0;  M& L/ b( K$ r/ R: z, a
  48.     }# @+ u. k/ K2 f6 I
  49.     else' ]) J9 R, z- K" o- x
  50.     {( t- i6 B( [+ S- E5 P# C4 Y
  51.         USART_ITConfig(USART2, USART_IT_RXNE, DISABLE);
    4 s3 d& Y; Y& B
  52.         //MAX485操作 高电平为发送模式7 j& x2 ^) H# H2 \5 B2 X
  53.         //GPIO_SetBits(GPIOD,GPIO_Pin_8);
      S( p( y% N" K* Q2 `4 J' k; o
  54.         RS485_TX_EN=1;
    / _3 O6 K1 l2 o) U/ i% W
  55.     }
    ' ^3 F) P& ^6 @0 M  }/ P
  56. 1 J/ R, \6 k; B) o, e! I
  57.     if(xTxEnable)- R% s9 L2 W# a" h
  58.     {
    6 M0 d* m& L  R/ U& T: \3 \8 @
  59.         //使能发送完成中断
    8 ~4 }5 @' ]" ?$ u" d
  60.         USART_ITConfig(USART2, USART_IT_TC, ENABLE);
    5 o; I: k' K0 t. P8 N* l+ z9 Q
  61.     }3 N2 M5 [4 U1 o' `4 y3 M
  62.     else
    2 q! ~0 N2 l6 s0 t) P3 h4 n) U$ _
  63.     {
    ' U* i) F& p' Z# ?( R' |( v! _) `
  64.         //禁止发送完成中断
    0 C' J# c& v" X6 c; D  |
  65.         USART_ITConfig(USART2, USART_IT_TC, DISABLE);
    , u8 F# i$ B: f: F5 A8 d. ], ]( \! ]$ S
  66.     }
    : a  r( N+ \9 _, {$ z6 c/ D3 e
  67. & f; I# l* O- E- t6 g

  68. * F* H  c# q- Y% z: O
  69. }
      r; \( O" R' F8 b; @/ `
  70. 9 U( h/ j/ Q! J& i7 }& y7 i- m
  71. BOOL/ R& f) v; R+ B4 H( z) I% L' x( Y6 K
  72. xMBPortSerialInit( UCHAR ucPORT, ULONG ulBaudRate, UCHAR ucDataBits, eMBParity eParity )' U$ W3 g9 g% z7 e
  73. {
    0 o" b2 @5 A1 T+ Q" Y5 {: q
  74.     RS485_Init(9600);        //初始化RS4859 o* m' P8 K5 K5 d$ ]* d: U
  75.     return TRUE;- n. Z: w; _% V6 h. w% k
  76.     //return FALSE;
    / o- n5 Q) q5 {: _; _
  77. }
    " r7 g5 I* d9 W. T6 @, R& N

  78. 5 l8 W) @1 V" b: }& q
  79. BOOL+ K  x  u  r* V
  80. xMBPortSerialPutByte( CHAR ucByte ). r3 p4 J+ e( N& a
  81. {+ R8 M9 K% H2 G, V6 t7 J4 A  ?: B
  82.     /* Put a byte in the UARTs transmit buffer. This function is called
    $ s' c5 f6 J% L1 S7 B  O0 |0 \  \
  83.      * by the protocol stack if pxMBFrameCBTransmitterEmpty( ) has been5 L& u) k7 R6 b& L' `' m
  84.      * called. */
    * m( H8 D1 J0 Z0 T% t
  85.     //发送数据5 M; o7 \2 R4 P: f; ^
  86.     USART_SendData(USART2, ucByte);
    1 K7 E9 X- T' Y5 F# O
  87.     return TRUE;) _: ^, i8 y$ `; [  L7 @! v9 H3 f
  88. }' @3 h% F( K5 X  k; e+ }

  89. 0 P. H2 A0 f8 K) I
  90. + A; b9 Z0 t1 e( Q3 P1 h
  91. BOOL- I) c4 E+ H4 L( x7 |$ J$ Q
  92. xMBPortSerialGetByte( CHAR * pucByte )
    ' f+ |2 {. F7 [* h' Y
  93. {+ M: C! F- z" x, p
  94.     /* Return the byte in the UARTs receive buffer. This function is called
    $ J+ L% ]- Y7 Y& v' A
  95.      * by the protocol stack after pxMBFrameCBByteReceived( ) has been called.
    6 Q# g0 o) `4 _  Z
  96.      */' k1 j: O9 p1 [
  97.     //接收数据) W$ ?. X, o/ R; M9 l( g# a  B
  98.     *pucByte = USART_ReceiveData(USART2);9 J: z5 U+ M+ J7 M  J) s( ?% _
  99.     return TRUE;9 f' F5 `' O2 z* J( H

  100. + m9 s8 b; t+ |4 N. y$ Z
  101. }5 T% P6 J0 W5 V( |, x4 n
  102. 2 |8 x; s1 A8 m" N. s8 x6 h4 k& V" [
  103. /* Create an interrupt handler for the transmit buffer empty interrupt- ^# e, S9 B7 M; i9 j" L7 q7 K. w
  104. * (or an equivalent) for your target processor. This function should then
    . n4 D2 f+ K7 C; |& e( C1 G: o
  105. * call pxMBFrameCBTransmitterEmpty( ) which tells the protocol stack that
    ) y6 Z2 u9 M3 U, ^1 C' t- k6 U
  106. * a new character can be sent. The protocol stack will then call1 Q6 m! U" O" s/ K3 u4 W9 G+ e
  107. * xMBPortSerialPutByte( ) to send the character.% v/ @( p4 P* D
  108. */
    4 R# b* Z. c( Q& m; m' T7 ~  \
  109. static void prvvUARTTxReadyISR( void )
    + W. {* z. c& i" \' S2 r
  110. {
    $ F' P. d' G8 O: v
  111.     pxMBFrameCBTransmitterEmpty(  );
    % _. x) i- {6 Y, ~% m
  112. }7 l4 P' Z* S8 W& Y6 q
  113. 2 G9 U4 ?; i5 S" X5 g
  114. /* Create an interrupt handler for the receive interrupt for your target: U; V- L. \0 v$ L2 w, Q; k
  115. * processor. This function should then call pxMBFrameCBByteReceived( ). The! r! {5 F/ T6 q
  116. * protocol stack will then call xMBPortSerialGetByte( ) to retrieve the* O' t3 v3 r$ \5 |3 n, x
  117. * character.
    ! J9 ?, y0 Q7 [' V4 m% H1 _/ i" _
  118. */
    ! ?! n9 t% u) G' t: ?
  119. static void prvvUARTRxISR( void )0 a* F. N$ i5 ~. c) P' ]: A2 ]# @
  120. {
    2 h8 j- a& ^1 F- S: M, M; W5 `$ W) m
  121.     pxMBFrameCBByteReceived(  );
    & Z6 g1 B% D1 f# T$ F4 Y
  122. }
    ' C4 M5 {/ Y0 R% c; u& c  D

  123. ; i& L6 g6 x: I6 A9 S" N; A
  124. void USART2_IRQHandler(void); w4 i% i0 Q$ D
  125. {
    $ D+ ]: l/ U  T: E9 ?2 K
  126.     if(USART_GetITStatus(USART2, USART_IT_RXNE) == SET)# R/ `! l, l6 ?/ U1 W7 O$ d
  127.     {4 U  p" \3 w6 j
  128.         prvvUARTRxISR();
    ( t. B/ g( t/ O! }! U! g( A
  129.         //清除中断标志位
    3 [$ Y, `+ m3 o/ Z( o9 L; [" y
  130.         USART_ClearITPendingBit(USART2, USART_IT_RXNE);$ j' K' i; T6 {3 y
  131.     }
    4 [  ^2 K0 a1 {: s% O# H9 D. r" F
  132. ! J( [" s* w6 D
  133.     //发生完成中断& o! v7 b7 G1 y0 H$ n
  134.     if(USART_GetITStatus(USART2, USART_IT_TC) == SET)8 I0 C9 ?" e8 e* N4 ]
  135.     {
    $ ^: J/ s3 Q' t) p
  136.         prvvUARTTxReadyISR();/ ^8 z- X& U  j/ j. s/ }
  137.         //清除中断标志
    " a2 x6 B6 U& N) F
  138.         USART_ClearITPendingBit(USART2, USART_IT_TC);" |) v5 Z' @! }( R
  139.     }
    5 }, b- _" Z! p

  140. 5 U) X& {" Z( l% [0 J  i* t
  141. }
    0 @& D4 }) D2 l) p! z: l4 @

  142. - @0 v7 @5 G) ?! S9 e
复制代码

4 B: J9 g+ R) k4 ]! lmodbus移植过程基本就完成了。
" T3 B5 R1 \5 ]9 P: K3 E4 l7 B————————————————( \. c( f" c1 h: S
版权声明:小盼你最萌哒
. d2 g! i2 y0 i: \- j如有侵权请联系删除  B' ]( q2 w9 o( n, w
; |. X* z' a; ?8 v+ k) t" S1 Z

4 v' ^  ]( \( }7 d8 H0 Z' N6 j' X
赞 收藏 评论0 发布时间:2023-3-14 16:54

举报

0个回答

所属标签

相似技术帖

官网相关资源

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