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

如何在裸机stm32移植FreeModbus

[复制链接]
攻城狮Melo 发布时间:2023-3-14 16:54
官方下载freemodbus-v1.6.zip源码,然后把源码中的modbus文件夹、demo\BARE\port文件夹导入工程。; \  u) G. b* }

9 y5 m/ |  D8 x- k1 D/ \% z: v先是一波无脑导,把文件夹里所有文件导入。
) a+ a# o& O  p% v2 [

+ x3 X# }: _! p( M: W0 S存储区配置,单片机上定义的起始地址要比实际通信过程中读写的地址+1。$ g+ A4 ~0 n9 X7 T4 {
  1. #include "mb.h"
      D( [( w" _# B- q
  2. #include "mbport.h"/ X! T* G' s0 D" {+ n) [4 F
  3. #include "mbutils.h"
    : p3 I2 K  O& d6 S
  4. //输入寄存器, [6 p* x6 N) i4 m$ G0 K4 _
  5. #define REG_INPUT_START 1001+ H( \( J  Y' D( ]
  6. #define REG_INPUT_NREGS 2
    ' n2 r3 }- L  m7 M0 `- D! {

  7. 5 q0 T) O) {5 K6 i. y
  8. static USHORT   usRegInputStart = REG_INPUT_START;9 S: V) \2 h1 J: y6 d1 z6 J4 x! q
  9. static USHORT   usRegInputBuf[REG_INPUT_NREGS];, n( }6 l& N2 Q: d+ ^( ^1 y
  10. . V' c: n9 c& b& @( W5 r
  11. //保持寄存器3 Y: l  B) u) T4 W7 c, e
  12. #define REG_HOLDING_START 20017 S8 K: c7 v7 B. ^' x3 M6 P' r
  13. #define REG_HOLDING_NREGS 1
    " g2 |! E* J; ~$ [) U) a3 k# x

  14. , Y& G" D9 f! X" I& K
  15. static USHORT   usRegHoldingStart = REG_HOLDING_START;
    * w& W, T9 _( s: O7 x5 u8 h& H
  16. static USHORT   usRegHoldingBuf[REG_HOLDING_NREGS];# Z$ Y, l( K3 E! t; r
  17. # b1 s1 Q* Y" y' c7 G
  18. //输出线圈点) R2 q+ q' N8 }4 x
  19. #define REG_COILS_START 3001  M: U5 |! \! [- P3 e. E- d. w* a
  20. #define REG_COILS_SIZE 4" Y* v0 u( p/ k, e
  21. : I; N3 i  ^/ [% H# w& Y# D* b
  22. static USHORT   usRegCoilsStart = REG_COILS_START;
    / ~9 n9 S! [6 q9 f
  23. static UCHAR           ucRegCoilsBuf[REG_COILS_SIZE/8+(REG_COILS_SIZE%8?1:0)];
    , _$ E, g4 O; n* f1 @" k/ P/ p
  24. 9 K5 B7 ]0 ^0 @# y
  25. //离散输入点1 @: C( ?- \' |3 t
  26. #define REG_DISCRETE_START 4001, _2 E% S. X. o+ \
  27. #define REG_DISCRETE_SIZE 8
    0 k/ h5 t2 |( g
  28. . |8 K  K; f1 @  X
  29. static USHORT   usRegDiscreteStart = REG_DISCRETE_START;
    / w# g: `6 G; z
  30. static UCHAR           ucRegDiscreteBuf[REG_DISCRETE_SIZE/8+(REG_DISCRETE_SIZE%8?1:0)];& x! c6 U. |( a$ z" F. x$ v

  31. 0 @, [4 ?5 w: D, o
复制代码

  P% I% j" A2 g" k7 L- {; `9 s1 F主程序就是标准的运行三连+IO读写。
( V% r5 M; V6 f, ~" D9 }4 p
  1. eStatus = eMBInit( MB_RTU, addr, 0, 9600, MB_PAR_EVEN );6 W+ N$ v6 [9 f7 q- m) L
  2. 8 E& z  m4 c5 T
  3.     /* Enable the Modbus Protocol Stack. */
    " X8 G1 C2 F) M  }8 T; b& o! ^$ ~4 f
  4.     eStatus = eMBEnable(  );
    6 ]$ q. d; M, J* }' T' a3 T

  5. 7 x- K6 b/ `  V! _, [' z
  6.     for( ;; )# z+ b# L) S5 G0 U# e
  7.     {
    & g' H4 w) R) t
  8.         ( void )eMBPoll(  );
    5 R9 M# y1 ^) A
  9.         usRegInputBuf[0]=Get_Adc_Average(8,10);
    / Z0 D9 Z4 q1 |; @4 Q$ P; t* p6 Z
  10.         usRegInputBuf[1]=Get_Adc_Average(9,10);7 g$ ]; s9 U5 _8 X' S$ M
  11.                        
    : z8 K2 l) i5 M! e' k3 v1 i
  12.         ucRegDiscreteBuf[0]=(GPIOB->IDR&0xFFFFFF00)>>8;
    & |. D7 f( x9 k
  13.         GPIOB->ODR=GPIOB->ODR&0xFFFFFF0F;; u8 v* {1 h5 o+ ~- ]
  14.         GPIOB->ODR=GPIOB->ODR|ucRegCoilsBuf[0]<<4;% N4 u# I" I9 j
  15.     }3 l( x) d9 \% \
复制代码
' K, n# {' l/ U; T
支持的4种读写function扔在主函数后面就行了。
! I4 c  I  C& ~2 R( D/ P
  1. /*** i( J, G+ S8 _4 T8 |, i/ m
  2. * @brief 输入寄存器处理函数,输入寄存器可读,但不可写。
    6 r: S8 ~6 ~& L; s
  3. * @param pucRegBuffer 返回数据指针
    3 `+ E6 t. m1 c: q
  4. * usAddress 寄存器起始地址: v: B. D9 u1 Z; _7 w: [) k
  5. * usNRegs 寄存器长度
    6 g, v, _. O3 I: q3 y2 q, f
  6. * @retval eStatus 寄存器状态& f% G- e4 ^. w) I3 Y! E
  7. */
    1 ]* V8 g( p7 p% f6 {
  8. eMBErrorCode
    5 y' ?' f5 U$ c6 H* g9 B
  9. eMBRegInputCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNRegs )
    2 s% }0 F; R- n
  10. {* M" J7 K5 l  N, A  B1 H+ a
  11.     eMBErrorCode eStatus = MB_ENOERR;
    / G9 |/ U/ E3 u3 {" z  U0 z5 e+ s
  12.     int16_t iRegIndex;5 s; l$ |3 ^4 O( P% X" L4 I9 B
  13. 7 i$ \6 q/ Y8 n* z0 j  o- r
  14.     //查询是否在寄存器范围内+ T; v2 \" S. R6 M3 E2 _
  15.     //为了避免警告,修改为有符号整数7 {: F) V$ d* g4 a6 ?/ z! S/ Q
  16.     if( ( (int16_t)usAddress >= REG_INPUT_START ) \: T% O1 B8 P2 g
  17.             && ( usAddress + usNRegs <= REG_INPUT_START + REG_INPUT_NREGS ) )
      X- t/ y, E' g1 A
  18.     {
    2 B" j1 O# V# m# A( J  e
  19.         //获得操作偏移量,本次操作起始地址-输入寄存器的初始地址
    " T$ l* M$ x) A1 x0 B6 W- A! _& d
  20.         iRegIndex = ( int16_t )( usAddress - REG_INPUT_START );
    $ I7 }/ {; m1 h5 m# r
  21.         //逐个赋值0 w. \$ Y2 t6 r6 Y+ [- {0 g
  22.         while( usNRegs > 0 )
    % g0 J* P, Y& b! G& a2 P8 ^
  23.         {
    ; A' Z5 g- p$ z, t, Z
  24.             //赋值高字节
    , ?' B( B+ U+ S& ~& ^5 f7 v; Y
  25.             *pucRegBuffer++ = ( uint8_t )( usRegInputBuf[iRegIndex] >> 8 );* S1 H0 _8 f" }
  26.             //赋值低字节
    1 u( @, M2 x- T3 L0 k: ?+ y
  27.             *pucRegBuffer++ = ( uint8_t )( usRegInputBuf[iRegIndex] & 0xFF );
    - O" p" M. H! m
  28.             //偏移量增加
      L8 T5 c4 k& s+ v/ S* U" G3 i
  29.             iRegIndex++;
    , M$ A! _5 e% t+ A
  30.             //被操作寄存器数量递减$ T+ H/ L- Y4 D+ T& T
  31.             usNRegs--;
    + x+ ^5 z. ~+ v4 i
  32.         }8 C+ P/ @2 B; n9 ^$ E
  33.     }
    ( Y) [2 n8 j7 \& V# [: o6 ?, z( ?
  34.     else9 G! g3 `; F5 \; I
  35.     {
    7 s4 N% [* f5 A8 j
  36.         //返回错误状态,无寄存器
    7 a8 z4 I3 i, X, S$ e8 l+ e% X& K) `4 _
  37.         eStatus = MB_ENOREG;& Q( S+ _* o0 v6 ~) j' P: U1 g
  38.     }
    - X1 Z# Q' S7 U9 d4 Q) Z

  39. 7 i& `& a( b1 r4 y' F  T
  40.     return eStatus;
    9 C( k" R1 |0 N% G7 O% a( l3 D5 E
  41. }, X3 H# D) B/ N: V

  42. 9 f6 }$ k5 ]+ g7 }
  43. /**' \# ^( H4 \& t8 d  D2 [" H8 u
  44. * @brief 保持寄存器处理函数,保持寄存器可读,可读可写9 z2 T6 \7 {! ~; T6 G$ `
  45. * @param pucRegBuffer 读操作时--返回数据指针,写操作时--输入数据指针
    + |0 J0 i: L1 d! k8 R& ]
  46. * usAddress 寄存器起始地址
      T, Q! R& e; _. N
  47. * usNRegs 寄存器长度2 U6 }3 }8 o7 _, K8 G
  48. * eMode 操作方式,读或者写+ I# v6 G; O. F7 A  V
  49. * @retval eStatus 寄存器状态1 @: i+ K' V" {7 Z+ z$ Z
  50. */
    0 O. R  i' Z! r7 @* v
  51. eMBErrorCode6 \9 R1 `* _7 K
  52. eMBRegHoldingCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNRegs,
      g5 S; Z5 I3 h" c
  53.                  eMBRegisterMode eMode )
    2 a$ y1 ~/ r" Y  e* u
  54. {4 \$ U% j! F# W/ a7 ~
  55.     //错误状态8 w. \4 M  D4 Z1 v0 Y8 r& I1 u
  56.     eMBErrorCode eStatus = MB_ENOERR;
    1 }) N. F* u7 M0 j0 o& B* u  f% ^
  57.     //偏移量6 p3 u* K. ~8 l( M
  58.     int16_t iRegIndex;8 P# a$ w  Z" B  h) f7 B9 M

  59. ) G& v1 k/ c' q/ }' Y) E3 }
  60.     //判断寄存器是不是在范围内
    4 O( ^( P2 Y4 i6 p. W4 P/ Z
  61.     if( ( (int16_t)usAddress >= REG_HOLDING_START ) \
    9 S9 S$ X9 ^; {6 y. c: ]0 Q5 C! b$ h
  62.             && ( usAddress + usNRegs <= REG_HOLDING_START + REG_HOLDING_NREGS ) )! s/ b8 J2 U* Y* U
  63.     {0 j' `' B% X& N" B# u
  64.         //计算偏移量
    ( }& i' D; q  I, c; z$ C+ I
  65.         iRegIndex = ( int16_t )( usAddress - REG_HOLDING_START );
    * V1 y. o# a# F

  66. 8 c0 l( m/ |& ~5 A% U
  67.         switch ( eMode )
    ; ~- X" J$ @& i
  68.         {
    ) K1 z! y$ b7 U. d/ ]0 Z
  69.         //读处理函数
    ; v* B1 z8 m- Q
  70.         case MB_REG_READ:+ V7 D7 Y5 j& w. X) ~( t, O* g* v
  71.             while( usNRegs > 0 )
    ) r8 ]! u) S6 U, R# K5 _
  72.             {
      W; L7 w" z& s4 N9 s$ G6 d2 j3 }
  73.                 *pucRegBuffer++ = ( uint8_t )( usRegHoldingBuf[iRegIndex] >> 8 );) \& i: i1 ?1 Z6 I( W
  74.                 *pucRegBuffer++ = ( uint8_t )( usRegHoldingBuf[iRegIndex] & 0xFF );9 t# m9 p# `& P+ ^& F# d! m
  75.                 iRegIndex++;9 M; N% S0 D; V
  76.                 usNRegs--;
    . Z8 b5 }/ x) b
  77.             }
    # W$ x5 a# U  l" v- V# j
  78.             break;. |- D/ V) b2 E& C0 x1 y: d# o2 e

  79. . p5 B2 H( q# b3 G" j7 x
  80.         //写处理函数) B/ \% X: K7 A- x2 j. S8 l8 n& x
  81.         case MB_REG_WRITE:9 G, {- ?# s$ G; Y$ Y9 Y
  82.             while( usNRegs > 0 )5 v5 ]. W" l) R8 G4 Z% k
  83.             {: b  X; c! h- O1 s( b. R
  84.                 usRegHoldingBuf[iRegIndex] = *pucRegBuffer++ << 8;# d! _! M; ?# }% Y: D
  85.                 usRegHoldingBuf[iRegIndex] |= *pucRegBuffer++;
    2 h- [! J& k. `3 o' k" C
  86.                 iRegIndex++;& x% T* `5 h' b0 U
  87.                 usNRegs--;
    4 z* y1 D) R; z0 h# N) c# H
  88.             }  W, O! N: @, o- ?* @$ V# m
  89.             break;
    # r- G/ R) H! h- N# J( e' y3 A
  90.         }
    ! a- K$ [3 f6 a; |9 r
  91.     }
    ( f( O5 i! o9 F
  92.     else% f: |6 P' |! `( t0 A. N
  93.     {
    $ N( p! S3 |" v0 e/ P! U8 S" x
  94.         //返回错误状态
      {/ o$ G0 a+ L
  95.         eStatus = MB_ENOREG;& `; Z' H' A# Y
  96.     }
      p( L* \$ _% k' z
  97.   }, f0 Z' k5 L0 ~. I
  98.     return eStatus;6 d9 v1 n$ D2 k- L
  99. }
      I  [6 ^* B' q9 C% }0 n

  100. 2 [/ w8 q" k, B, I
  101. 5 j; P, \* O! u( e: \% h/ X
  102. 9 }" ^; J7 O) v  ~& e
  103. # b7 i# |# V8 G8 f; ]) A% ?
  104. /**' x/ m& @5 k6 U
  105. * @brief 线圈寄存器处理函数,线圈寄存器可读,可读可写
    6 M" U( U1 x' Z3 |: u
  106. * @param pucRegBuffer 读操作---返回数据指针,写操作--返回数据指针# `3 o4 l# D2 J/ Z% G
  107. * usAddress 寄存器起始地址; ]+ {. S+ i7 O) ]0 {8 F
  108. * usNRegs 寄存器长度
    , Y- T, A2 }# i1 _
  109. * eMode 操作方式,读或者写
    + p8 U$ W  N+ R2 ]: E! r
  110. * @retval eStatus 寄存器状态4 @* P% i; h  ]! _
  111. */8 S  f$ ]! ^- J2 I
  112. eMBErrorCode
    + K2 K$ `  Z# y$ b3 I( e6 x
  113. eMBRegCoilsCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNCoils,
    5 I0 b( o( X9 H9 w
  114.                eMBRegisterMode eMode )
    $ m& J$ Q' M0 b2 Y* }+ H
  115. {
    7 ]8 A0 E) ]* |: g& a5 c" z
  116.     //错误状态
    3 ?. |+ M1 v0 ~! R  R- ^
  117.     eMBErrorCode eStatus = MB_ENOERR;
    / D9 Y' r1 |* d, q7 H3 u
  118.     //寄存器个数/ K# K% T/ p0 b) k
  119.     int16_t iNCoils = ( int16_t )usNCoils;
    ) f5 v& ~4 b9 K$ B7 ?" d
  120.     //寄存器偏移量
    * f, v5 \- O0 h# ?
  121.     int16_t usBitOffset;3 z7 x% R- [, v; s# D' [9 ~

  122. - r) [1 E4 Z" `% T$ M* ]5 E
  123.     //检查寄存器是否在指定范围内3 D1 a( K% @4 w6 q" r2 X
  124.     if( ( (int16_t)usAddress >= REG_COILS_START ) &&/ h+ Q; c! q- I* u+ b: b
  125.             ( usAddress + usNCoils <= REG_COILS_START + REG_COILS_SIZE ) )
    7 H8 R1 S0 j6 Y4 R
  126.     {
    5 d( L. _8 U) e( E1 ]
  127.         //计算寄存器偏移量/ w- y& c2 R" r: m" @! R% }
  128.         usBitOffset = ( int16_t )( usAddress - REG_COILS_START );
    5 P4 s$ v! a9 U+ n  g
  129.         switch ( eMode ). ^2 m& w0 g: {3 ~0 h, M. ]
  130.         {% G8 }7 a9 t) `& W
  131.         //读操作3 P2 q2 [; s8 l! [+ V& X- @
  132.         case MB_REG_READ:
    . h/ ~# i6 {7 n" h" N
  133.             while( iNCoils > 0 )
    8 Q1 {; X2 C0 W. r" e2 z
  134.             {
    ( o! p( _& m3 y4 z( v
  135.                 *pucRegBuffer++ = xMBUtilGetBits( ucRegCoilsBuf, usBitOffset,- k% o+ d  y# q
  136.                                                   ( uint8_t )( iNCoils > 8 ? 8 : iNCoils ) );- X/ U4 u, A8 K  O5 Q( Z3 m
  137.                 iNCoils -= 8;
    ! D. W' L+ E& }7 O/ v" @& r
  138.                 usBitOffset += 8;
    1 u# U# _: O5 t+ L7 r
  139.             }
    0 h) F: i* ^  [& L* B
  140.             break;
    : I' l' y/ l' C3 O( N6 j% H

  141. 2 |/ [, D4 ^5 [- ?
  142.         //写操作
    % }" ]% |" }! F, e; m+ ^5 ?
  143.         case MB_REG_WRITE:
    ) P8 n7 z6 h" s! ?5 Q8 s3 m& u0 h
  144.             while( iNCoils > 0 )
    6 t- M* O3 E4 H( ~/ R% v3 W/ v
  145.             {
    & i& }3 J  q4 J$ V3 J2 K- \
  146.                 xMBUtilSetBits( ucRegCoilsBuf, usBitOffset,
    - Q3 @& q" P2 O
  147.                                 ( uint8_t )( iNCoils > 8 ? 8 : iNCoils ),
    * W) `) H' {. C  ?7 T0 U$ A
  148.                                 *pucRegBuffer++ );/ ^9 x9 }" v1 h4 {5 [1 R; K: y
  149.                 iNCoils -= 8;& ^- T/ c' N0 ~/ r" ^+ G/ W
  150.                 usBitOffset += 8;& [1 W/ G, a4 Q+ v1 c/ J
  151.             }
    ( x4 Q; s4 d( b2 C$ h7 R  K
  152.             break;
    + z. @0 s( G7 @
  153.         }8 r  B* Z- w. I: j  p" J
  154. 9 \$ j" y" R2 C/ K" {2 F
  155.     }
    . Q+ z" y0 W2 g9 N
  156.     else2 S/ R5 M. N/ X- x" ]
  157.     {
    1 O: f  W. }( Y
  158.         eStatus = MB_ENOREG;
    $ q3 t/ p9 G, C& ?& I; X
  159.     }
    ; j/ v! X& L& P9 _$ C& A( L
  160.     return eStatus;, N$ `  g+ \; y- C8 s7 T
  161. }
    + G1 ]" Z; T- R. S
  162.   h( n% Z& t5 G$ u
  163. 7 a9 w) ^) P2 m$ ], C/ o( O! g

  164. # Z3 z7 g, N0 F# o* v0 ^7 b
  165. - W, C3 F9 B8 v5 K% T
  166. /**7 p" m; J0 \: I* G1 v
  167. * @brief 开关输入寄存器处理函数,开关输入寄存器,可读
    3 f, c/ v  F) M0 h3 X( z+ }* U5 m
  168. * @param pucRegBuffer 读操作---返回数据指针,写操作--返回数据指针
    ( _% `1 E; P. a0 \0 r
  169. * usAddress 寄存器起始地址/ h. ~2 L/ b6 T
  170. * usNRegs 寄存器长度
    ( ]5 @% z, _3 e5 F# C. P2 w
  171. * eMode 操作方式,读或者写! C/ Y% {9 \  f1 e
  172. * @retval eStatus 寄存器状态
    / H( k% _  A3 T) r$ o0 z, F3 ]3 q
  173. */, o7 @! Z+ p# J3 X4 @3 O. U3 L
  174. eMBErrorCode/ H/ n* u' i2 \9 X: z
  175. eMBRegDiscreteCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNDiscrete )
    * Y; R  L8 w! g
  176. {7 w" _/ o  o0 i: [2 T
  177.     //错误状态7 U- o3 [4 |' w6 M
  178.     eMBErrorCode eStatus = MB_ENOERR;
      f6 H0 o( ]4 @, p9 N# O
  179.     //操作寄存器个数7 a, M' r' x. U3 j
  180.     int16_t iNDiscrete = ( int16_t )usNDiscrete;
    . I0 D! a  z: a2 V
  181.     //偏移量' B/ O: m$ d8 x0 O. y
  182.     uint16_t usBitOffset;
    3 o" T  a5 p! \, k- D2 p

  183. ) o  _7 @: t' z  I2 G$ b5 m" C5 C
  184.     //判断寄存器时候再指定范围内
    & Z0 y8 T: R; L0 E2 l; b+ ^/ L
  185.     if( ( (int16_t)usAddress >= REG_DISCRETE_START ) &&) l: u' \) q1 [. T  Z
  186.             ( usAddress + usNDiscrete <= REG_DISCRETE_START + REG_DISCRETE_SIZE ) )$ Q7 H+ _/ d. x( c' R$ R0 a$ B  y9 N, C
  187.     {4 G; G2 a& w4 c: s
  188.         //获得偏移量) w- v$ G' N% C6 ?$ A
  189.         usBitOffset = ( uint16_t )( usAddress - REG_DISCRETE_START );
    8 |* a8 x- P* v& W. k- B+ {

  190. - t  R: x$ f( F( o- L
  191.         while( iNDiscrete > 0 )
    4 y( K: V; J" Y% w; K0 j3 ?
  192.         {6 H; {2 d7 {+ d' a1 Z# C) {4 d
  193.             *pucRegBuffer++ = xMBUtilGetBits( ucRegDiscreteBuf, usBitOffset,
    % U# m2 F/ q+ D& ~" b
  194.                                               ( uint8_t)( iNDiscrete > 8 ? 8 : iNDiscrete ) );
    9 g0 ~5 `7 N8 i5 a
  195.             iNDiscrete -= 8;
    1 J$ j: X7 }$ n* h4 E5 O. X' O
  196.             usBitOffset += 8;
    % e! D  V; g; r( S$ z( @" Y% ~; \$ ^
  197.         }
    ) B" k* ]# m; P9 p* f0 ]4 w

  198. $ c. z' h" s  g. p9 u+ c5 i
  199.     }/ @3 T( {' r1 }4 d; p# Y
  200.     else
    3 n( D% G; M( [* R8 g6 `( D7 F
  201.     {% O- R$ h6 v; Z1 R
  202.         eStatus = MB_ENOREG;
    ' m  a' Y6 \! G/ N) y
  203.     }) a- X8 r) r5 p, N( B3 p3 c
  204.     return eStatus;
    8 F* q5 R: H# G6 v
  205. }; b8 Q/ i* R3 o* y7 u9 v( ^8 X

  206. * B4 W+ n( I  ^! B6 R

  207. % l/ ]1 y  i1 N/ H1 w
复制代码
+ N! |& D5 k4 `) G- n6 b
porttimer.c是和定时器相关的实现接口,计算好预分频与装载值之后,可以直接调用原子例程。! e3 P3 n  B- l) R+ G6 c2 r+ q
  1. /*9 n' l+ h: e$ a
  2. * FreeModbus Libary: BARE Port6 i* [" ^3 p+ Z( y" S
  3. * Copyright (C) 2006 Christian Walter <wolti@sil.at>" Y" N5 A' ^, S4 S$ N2 _, O
  4. *
    " f, V2 n! f7 j2 s& |& j/ }; `8 Y
  5. * This library is free software; you can redistribute it and/or
    7 A  F% I$ Q# n2 T' H" }: j
  6. * modify it under the terms of the GNU Lesser General Public! M; ^% g- K; s" `2 I2 X
  7. * License as published by the Free Software Foundation; either
    0 t6 t4 D2 c/ X! X$ {7 _2 A
  8. * version 2.1 of the License, or (at your option) any later version.
    % O# e6 s6 h, p3 V. h( t5 n% X
  9. *
    % O. @- J8 [# ]' a( ^
  10. * This library is distributed in the hope that it will be useful,) `0 c' G( Q! V3 f+ _# M
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
      S0 x9 N. {8 a" l5 C* T/ t
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU% Z4 }+ @, i$ M+ R  b* [0 R. l/ f" R
  13. * Lesser General Public License for more details.
    - l! o0 o" U! {' p  n/ E  J; q
  14. *
    % Y* c5 T6 Z. i; i3 s* }- ?: X8 O
  15. * You should have received a copy of the GNU Lesser General Public. N$ s0 O# E$ L: T( }
  16. * License along with this library; if not, write to the Free Software
    - O; ]1 O. M7 ^) L& Y2 N
  17. * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
    $ D- e, I+ d3 o- p# k" _5 h4 d
  18. *# h/ g3 O4 b8 g7 ^" A
  19. * File: $Id$' p+ U, ?$ D3 u! L
  20. */0 c% P- X( P* n" G! }
  21. 8 U9 A! |* ^+ r3 \5 _2 s5 p
  22. #include "port.h"
    1 j+ i! X, m1 U; Z9 a2 W
  23. 9 K+ Y& `/ Q- W& J  S
  24. /* ----------------------- Modbus includes ----------------------------------*/. O, j* y6 R& i( n- J  c! [1 Z
  25. #include "mb.h"
    , _5 ?- \+ b6 b. v' J2 P
  26. #include "mbport.h"
    2 I+ m2 H# d  K8 n% G7 m
  27. 0 O) n: ^9 ]8 M1 K( E
  28. #include "rs485.h"# U' C; r/ m% f* ~( P
  29. 6 g% ]+ |( n0 B6 \& I3 F
  30. /* ----------------------- static functions ---------------------------------*/5 l* U0 p  h# l& [+ ~/ w+ c+ A
  31. static void prvvUARTTxReadyISR( void );  s: `: _0 G) W( u' l7 m- P! Y
  32. static void prvvUARTRxISR( void );
    1 I4 p% ^! ~( z" b- O4 K
  33. $ e- Y2 G" k% [. Y4 A
  34. /* ----------------------- Start implementation -----------------------------*/+ M$ D! |3 E8 |; t
  35. void
    % Q# o2 C: v, I. M
  36. vMBPortSerialEnable( BOOL xRxEnable, BOOL xTxEnable )
    ; i+ @& ]5 o+ A# p2 g
  37. {
    4 N; k! r+ }, L" i% c/ Z1 {- z
  38.     /* If xRXEnable enable serial receive interrupts. If xTxENable enable
    / L# i5 ^' ]+ k- F
  39.      * transmitter empty interrupts.
    , n8 C; l" m6 O+ t0 P( R0 u$ R
  40.      */
    4 H4 ]9 V5 y- r
  41.     if(xRxEnable)
    1 Y  D% r' R- _' }: [/ I
  42.     {- M# W5 r; Y9 C# y+ Z3 h/ M* \# n9 \% C
  43.         //使能接收和接收中断( Y: \7 H5 C5 P( s; d. Y
  44.         USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);
    - ~4 S: |& W! e7 E1 M5 T
  45.         //MAX485操作 低电平为接收模式4 h  G7 a  G; R- K# d. @
  46.         //GPIO_ResetBits(GPIOD,GPIO_Pin_8);
    9 n* o. e- B; N" Z: `( U
  47.         RS485_TX_EN=0;+ R& H  |8 [6 [4 f$ o) s% P
  48.     }
    2 U( v; t4 m( C8 I0 M
  49.     else% N4 Q; z& z" [: i1 N; I
  50.     {
    ; U8 r8 W+ S% ?  j- B
  51.         USART_ITConfig(USART2, USART_IT_RXNE, DISABLE);
    7 h3 P- o8 [9 a: [1 Y5 x
  52.         //MAX485操作 高电平为发送模式! d) P' I1 [; h0 b% E7 w: I: g
  53.         //GPIO_SetBits(GPIOD,GPIO_Pin_8);
    . c% O( Z8 {+ Q, K
  54.         RS485_TX_EN=1;" N+ \; e  q6 e/ A+ t* {
  55.     }
    ( C1 g% `/ R+ j- g/ {5 W
  56. 4 x# s; p. [/ J  p
  57.     if(xTxEnable)) a9 m. I. P+ |2 u% `; j
  58.     {
    . {1 w/ s3 U- ~4 _" A5 y8 H
  59.         //使能发送完成中断. @- Z! c' T7 t8 ]! R
  60.         USART_ITConfig(USART2, USART_IT_TC, ENABLE);. \* p8 }, Q$ W
  61.     }' ~! b3 I0 |8 |3 h9 x4 F( N
  62.     else
    3 ]/ F  Y& C% ^1 L
  63.     {
    0 l) z, {! y3 D1 [
  64.         //禁止发送完成中断. u& \% [6 o* @1 O. @& b
  65.         USART_ITConfig(USART2, USART_IT_TC, DISABLE);% }& F/ l: S# f, h% i: l# V
  66.     }) O  J- ?, g" N. s/ ]3 x* _

  67. 5 b" S+ d3 `5 w5 p; |* V7 ?
  68. 6 k8 A# R" r6 Z4 X# T" P
  69. }- f3 Q& x3 S" E" w" h5 x
  70. # c6 c5 c  ~6 `/ S
  71. BOOL+ O; G" L1 z2 f
  72. xMBPortSerialInit( UCHAR ucPORT, ULONG ulBaudRate, UCHAR ucDataBits, eMBParity eParity )1 Q! k' s1 R0 a- Q; Y6 J0 q
  73. {' l, p! I9 f% `! G5 ?
  74.     RS485_Init(9600);        //初始化RS485( M' [$ L5 h/ V( l
  75.     return TRUE;
    / f# E  D# i$ G+ b: w$ c& v/ K
  76.     //return FALSE;& F# c0 p7 }% O" g
  77. }
    0 ~0 d/ S. a& o$ {0 {1 `8 t
  78. - q& L  G1 q7 \. i
  79. BOOL
    , ?# O% W* z; {# X9 r! ~, B# f
  80. xMBPortSerialPutByte( CHAR ucByte )5 @& w; ]5 a" ?+ W
  81. {5 u/ ~2 L: l6 c" r5 Q$ s: x7 o
  82.     /* Put a byte in the UARTs transmit buffer. This function is called
    6 |/ A; u" V/ V: [$ o
  83.      * by the protocol stack if pxMBFrameCBTransmitterEmpty( ) has been& Y! f, X& F- O6 \4 x1 Y9 h% R* K
  84.      * called. */- J2 @* i# A  f+ J; u
  85.     //发送数据0 f% S( N: q% e9 V. v5 _7 j. q$ a
  86.     USART_SendData(USART2, ucByte);
    4 Q- J8 q# y( T8 M) c" {! I
  87.     return TRUE;
    * i8 |9 _* r" N& |7 Z
  88. }
    + T; ~( d) s& x" m' W

  89. 3 e' a; i4 d" y% n0 n
  90. / [2 @. d9 |" [, r" \
  91. BOOL  Q4 x& ^5 k) |' M, c. P) G
  92. xMBPortSerialGetByte( CHAR * pucByte )6 ]! |% W; |1 K/ ]0 Y( J
  93. {
    ! L, j, x5 z$ `% ^  V  c. m
  94.     /* Return the byte in the UARTs receive buffer. This function is called
    ' l6 {& j$ E) j3 V
  95.      * by the protocol stack after pxMBFrameCBByteReceived( ) has been called.5 D7 Q. R! }1 U% Z5 u
  96.      */; c8 A2 b' {2 e6 p; O2 o
  97.     //接收数据
    9 ^. q6 p$ M' ]- ^/ q* R
  98.     *pucByte = USART_ReceiveData(USART2);' M) [( ]$ F! B0 n
  99.     return TRUE;/ T) E& w7 h/ L) Q; |: C, j5 @
  100. 3 K6 p: _6 T4 D6 N
  101. }* s5 D' D) r2 s& G

  102. ' N' F9 g3 z' N8 ^% P
  103. /* Create an interrupt handler for the transmit buffer empty interrupt
    9 Q9 [. J; U: t. E
  104. * (or an equivalent) for your target processor. This function should then% }% g7 l) z2 R* x7 Q8 E
  105. * call pxMBFrameCBTransmitterEmpty( ) which tells the protocol stack that7 \! c" S8 |+ J- g# m1 Z
  106. * a new character can be sent. The protocol stack will then call7 e/ \; h% H7 I% X3 k2 q, k
  107. * xMBPortSerialPutByte( ) to send the character.- R1 s. e8 w, S/ P
  108. */
    . X6 P0 P) s8 r( E' N' N- Y
  109. static void prvvUARTTxReadyISR( void ); R6 j* f. ?+ q- L3 I
  110. {5 M* c& @, z9 A7 S& C; r% b1 s5 c
  111.     pxMBFrameCBTransmitterEmpty(  );5 a- \9 E, H3 Z# h
  112. }
    ! k- Y; Z( c$ ?' x& L

  113. + o# P9 o, {0 V! c5 S) S
  114. /* Create an interrupt handler for the receive interrupt for your target
    4 N# l- y% s7 ~( X# t) f6 ?
  115. * processor. This function should then call pxMBFrameCBByteReceived( ). The
    6 e# {( {- Y0 |, h& p
  116. * protocol stack will then call xMBPortSerialGetByte( ) to retrieve the7 i% C; e8 a( _2 w8 g
  117. * character.$ O3 }% }9 A4 k* _7 v
  118. */
    + ]( `- _% B3 J9 d9 @. J9 x& ^$ b
  119. static void prvvUARTRxISR( void )
    7 c2 ?9 G) R2 ]( a1 b
  120. {
    0 [3 w. c0 |2 L: `3 c% c$ @- b
  121.     pxMBFrameCBByteReceived(  );1 T# U$ e) X3 @# T3 I
  122. }
    2 ?9 Y  E8 H! m. L; }, o/ \7 j
  123. 0 x0 X9 |) M  y* Z: U$ k) U
  124. void USART2_IRQHandler(void)4 R2 v* k( B; N6 w3 {1 U  r
  125. {
    , [# _1 k1 W, L# x2 q9 J
  126.     if(USART_GetITStatus(USART2, USART_IT_RXNE) == SET)
    4 O+ n3 M' k( A) F. c6 q
  127.     {+ Y8 h8 ]: ]) _: P& I0 D9 C
  128.         prvvUARTRxISR();. T1 `2 X) `7 O3 k/ ]% c0 r* I
  129.         //清除中断标志位
    - `$ d& }% J1 c9 S9 O# U; h2 M
  130.         USART_ClearITPendingBit(USART2, USART_IT_RXNE);
    " a( Z* G0 u' `5 ^% Q( P( H
  131.     }
    ; b, e& G8 T6 D
  132.   K1 o, d6 F: {( c1 s
  133.     //发生完成中断
    2 H8 O) w8 E' w1 J* y/ C
  134.     if(USART_GetITStatus(USART2, USART_IT_TC) == SET)
    1 H2 t( R3 D# x4 h0 [* z
  135.     {5 T) O5 b. {' y+ `( W* _
  136.         prvvUARTTxReadyISR();
    - Y8 a8 ?$ e2 g8 Q+ a- Q8 p
  137.         //清除中断标志
    8 J6 x* }7 I6 C- r7 o& s9 e5 a6 `3 y
  138.         USART_ClearITPendingBit(USART2, USART_IT_TC);
    & B3 e* O, Q% O; G* h, [
  139.     }
    6 H& k: I, Z' z; ]! m7 x
  140. 3 W4 x; `  \, C
  141. }8 g( K' j5 z/ c6 d; m0 Q

  142. 2 D) r" v0 p- e( D/ w2 S# G
复制代码

! Y+ U# P. Y0 w3 U9 wmodbus移植过程基本就完成了。3 f8 R! O$ c$ G: m
————————————————
7 F! x' V1 h$ J( B$ h版权声明:小盼你最萌哒/ x% v; A) k+ Y" T- g: N6 W
如有侵权请联系删除
8 i+ f8 M8 P9 |5 C2 V1 W  u; {6 i1 Y3 z" h
5 k0 ?5 }$ x  q0 B
收藏 评论0 发布时间:2023-3-14 16:54

举报

0个回答

所属标签

相似分享

官网相关资源

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