首先将FreeModbus移植到自己工程中,如下图所示:" u; s% e W4 |* k+ p( u* _
1 y' w9 A, I: Y* k1 k. S4 |. L: W S/ v7 |( m: [2 I8 u2 e' D
然后修改portserial.c和porttimer.c文件:. Q! |7 u- x2 I: |
portserial.c
; {% e# f3 b% a7 |* O( \" [# E! j9 d9 Q8 x
- /*
# W2 p* C; K# m& P4 t - * FreeModbus Libary: BARE Port7 g) D$ \ ^* w$ s/ h
- * Copyright (C) 2006 Christian Walter ' j6 ]2 I: i0 u" n2 I
- *
+ [ u" Y9 s/ u5 W: W/ B" Y: ~5 g* p' Y+ k - * This library is free software; you can redistribute it and/or
1 ~" H$ Q& [. D4 {/ ? u/ ` - * modify it under the terms of the GNU Lesser General Public9 g5 J8 h, T5 \3 ]
- * License as published by the Free Software Foundation; either
1 }( ~8 T3 w+ Q# x - * version 2.1 of the License, or (at your option) any later version./ ~0 F" P+ S. J
- * l6 ^$ O, A0 g+ y( {8 K+ w
- * This library is distributed in the hope that it will be useful,0 F3 U! ~& z) e; ` G% g
- * but WITHOUT ANY WARRANTY; without even the implied warranty of4 J4 t, d0 L/ D! |& j
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1 b \6 F, o8 U/ d - * Lesser General Public License for more details.( h/ h W" i E8 ]% ~% H- T
- *0 @- r% J3 y, a: g. g* Q
- * You should have received a copy of the GNU Lesser General Public0 _0 \& M3 O: u& R6 o( @
- * License along with this library; if not, write to the Free Software. }1 G; b; Y% w' b( _( s! f
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA- u( W! z% q' z+ x1 E' y
- *1 n1 r( W4 _6 m) r
- * File: $Id: portserial.c,v 1.1 2006/08/22 21:35:13 wolti Exp $ t# [+ J) K4 h' B# d3 r
- */& u1 K! C' O% }) c+ i
' v W8 q/ \) f# e8 G" l& ]3 ^, U- #include "port.h"$ x8 a$ \" u* ~ i y
- #include "stm32f10x.h"
. Y* C. }, C+ N0 ?. } - #include "modbus.h"
9 e9 g! a4 H% b8 D$ T) b# J- U" L- o - /* ----------------------- Modbus includes ----------------------------------*/: I( P# ?; X b: @
- #include "mb.h"6 ?+ r( O, }- r
- #include "mbport.h"3 k" ?, x: \' _$ m* F6 S1 p
- ( b% Q' c- o1 Q
- /* ----------------------- static functions ---------------------------------*/1 f3 z4 R- q6 z; L+ T8 @8 ]2 }& l
- static void prvvUARTTxReadyISR( void );9 S. \# `8 u# ] Q4 @- Z
- static void prvvUARTRxISR( void );1 z' Q5 `, Y/ e( `- n8 K
- `. o3 U7 I/ ^, K7 l* E- /* ----------------------- Start implementation -----------------------------*/
_0 I+ @1 p; e- A, j+ B - void
2 h% n' r* U/ A8 b( `5 U. o+ y - vMBPortSerialEnable( BOOL xRxEnable, BOOL xTxEnable )8 ^# U0 J! @& X. }8 U* D% P: _
- {
+ b" J/ X% l( g, z) e - /* If xRXEnable enable serial receive interrupts. If xTxENable enable
: s) y4 e. O0 `# j. p* A; X! |, } - * transmitter empty interrupts.; T- }8 b3 i4 j% c
- */8 ~' R6 O4 e$ u: D- E
- if(xRxEnable == TRUE)& B3 Q: D7 s( u. x5 v
- {
& W+ J9 K0 q( V- t* N+ x - USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);& \2 Q( g1 _5 P n0 v) C
- }
. a+ p1 k: @ q - else5 V1 u) ~9 l* W7 m' B, r- n
- {" ^0 W- b' Y, q& E
- USART_ITConfig(USART2, USART_IT_RXNE, DISABLE);3 Z8 J& I+ l' l" I, u2 Q' H: @
- }
. H! P6 `* n. b% i; k! ? -
; G) T! M2 \. {7 S4 |& J - if(xTxEnable == TRUE)
8 z& {/ j& r0 s+ I }. Y - {" ` }5 t+ g5 H( I V0 I' o
- USART_ITConfig(USART2, USART_IT_TC, ENABLE);
! y6 R M6 q3 O - }& @ D& L. Q( L' g
- else7 }6 B. F2 s5 K9 G7 F6 l* \7 E* T
- {! a6 Y) e- q V$ r& @
- USART_ITConfig(USART2, USART_IT_TC, DISABLE);
+ a' U3 |$ t% w7 P _ - }
2 U4 }% s0 q9 R1 i - }
% F$ b; P5 V0 M - * o0 T" j2 l0 ?" A% M
- BOOL9 o; u, G4 _% a4 O, Q& V3 ~# D
- xMBPortSerialInit( UCHAR ucPORT, ULONG ulBaudRate, UCHAR ucDataBits, eMBParity eParity )% T, x4 H& G2 L6 O
- {9 G& q* [' X- L& f0 x: x- [3 X
- modbus_uart_init((uint16_t)ulBaudRate); 4 R/ z' C7 X- L
- V8 g3 L7 c- j2 h! A
- return TRUE;+ o' ~' Y8 H0 E
- }' k+ \1 h# s1 }; f4 ]0 W/ U
- $ G0 o/ g$ V, l1 l n* [
- BOOL0 T2 V2 v% m9 }) z
- xMBPortSerialPutByte( CHAR ucByte )
& T- m" I' u7 h7 {( ~* V1 M - {
& I/ w+ o) T4 B$ H - /* Put a byte in the UARTs transmit buffer. This function is called, O3 }- F* Y% K& X4 N8 l( M& N# I
- * by the protocol stack if pxMBFrameCBTransmitterEmpty( ) has been
0 N% O, |9 ~ ]4 i8 G) A - * called. */
) X% E5 m. Q1 X7 ` - $ `6 N+ V1 `0 W# h! K9 K
- USART_SendData(USART2, ucByte);
0 I$ m8 R4 J0 e# u- { - return TRUE;
! `) [/ Y% p. n) }, x - }
0 L4 ~6 z! r( x& g6 [6 y- l - - m! B' u3 p# s( |+ c
- BOOL& x/ _0 c" k! c1 C! j
- xMBPortSerialGetByte( CHAR * pucByte )
- x" M* N! F' b- ? - {
6 I6 s; w3 J$ w' T4 \ - /* Return the byte in the UARTs receive buffer. This function is called2 _5 l) j- Z- k: M
- * by the protocol stack after pxMBFrameCBByteReceived( ) has been called.
; V" ]- ]0 u- `1 s+ g - */8 D1 a1 `; h% \! w1 p4 p
- *pucByte = USART_ReceiveData(USART2); 0 ^2 b/ e' z8 P) _ o) u
- return TRUE;5 a3 d5 o, K6 f$ w8 \
- }; P" f$ V! {1 o
- + J* [3 s# m: I' V1 ^
- /* Create an interrupt handler for the transmit buffer empty interrupt
0 A6 K9 R3 S) T1 t0 q - * (or an equivalent) for your target processor. This function should then1 U/ ^, A6 T7 `, G* z5 L
- * call pxMBFrameCBTransmitterEmpty( ) which tells the protocol stack that6 a$ G* [0 N# J/ j$ n% E6 \
- * a new character can be sent. The protocol stack will then call
$ t/ J8 g W8 p - * xMBPortSerialPutByte( ) to send the character.( R2 c- C- M! j1 A
- */
# r0 L& X% u- m- ]1 s/ P5 z& { - static void prvvUARTTxReadyISR( void ); J( s5 w! ]8 p* u- U7 d% `' `. s
- {
( R( \& \7 I h$ O. y% n - pxMBFrameCBTransmitterEmpty( );
. Y' F. }( R8 q* R: Q& d1 H - }
/ g$ E1 p m V
% c' a! [) e) v+ j0 R- /* Create an interrupt handler for the receive interrupt for your target
) n( [& [& B7 D* e7 ?/ Q+ p - * processor. This function should then call pxMBFrameCBByteReceived( ). The
" B. l3 Z+ v% @! W2 o$ E, h( y - * protocol stack will then call xMBPortSerialGetByte( ) to retrieve the- X; u7 i6 ]' [7 H, i
- * character.
O8 ~9 j+ E( I3 f6 X) I1 _ - */
/ H8 B9 X$ O& V Y3 v! ?# e - static void prvvUARTRxISR( void )! S+ p. ]4 Y: B. G8 S) R( Z& n
- {
4 Q& g: d$ Z9 P1 Q6 |7 H - pxMBFrameCBByteReceived( );
8 t* ?$ S' O* R4 s! M$ f$ H - }
4 J. _: T$ G( G. c$ F - % Y) X+ D1 @9 y# @% @1 h9 J5 Y
- /**
- k: {6 a6 I, q. T- Z) T* h - * @brief This function handles usart1 Handler.* d6 M2 L/ h) Z6 V3 D: z3 c3 I
- * @param None
* U8 b$ R4 }' z* i7 [* q! J v - * @retval None
5 i) p9 b' U' @' o% Y- F - */7 N) ^2 A* G: j& ]% t
- void USART2_IRQHandler(void)
" n; H* l3 T& w C1 J - {
9 _. m+ `2 w6 V - //发生接收中断
3 Z0 y+ C- e& r, {* d: S - if(USART_GetITStatus(USART2, USART_IT_RXNE) == SET)8 [# ]! n' @9 q+ [! p% e4 ^1 K( a
- {
- ^. P+ [4 Y/ t8 N( d# W% U% ^ - prvvUARTRxISR(); 1 F' ^7 f7 \8 R8 b5 _/ H$ G2 v) f
- //清除中断标志位
5 v6 J- o! a" ~. q2 I0 a - USART_ClearITPendingBit(USART2, USART_IT_RXNE); + P" o( A- t0 ]5 {
- }: n1 ~+ }9 j$ c2 h" p" ^8 A
- : K) p: J8 t8 x9 t2 V
- if(USART_GetITStatus(USART2, USART_IT_ORE) == SET)
, ^7 i* F+ A6 p - {
$ V* F4 J3 [( r& A - USART_ClearITPendingBit(USART2, USART_IT_ORE);% g, Z9 G& X: r7 m/ }. {! |
- prvvUARTRxISR();
r% J/ D2 K ~. v+ Z - }
1 g& d/ O m- L: A f
6 d5 Q3 n8 k$ c' {: N! t. x- //发生完成中断
* Z4 j& }8 h0 [$ T+ K* S& C- w: a - if(USART_GetITStatus(USART2, USART_IT_TC) == SET)
; E3 c9 |! @/ `2 Y4 [ - {" m/ Q k& w5 [) y$ ?7 n% W/ d p
- prvvUARTTxReadyISR();$ W/ F k$ ^( g9 W; a% x
- //清除中断标志# G+ a; p6 E$ C' y
- USART_ClearITPendingBit(USART2, USART_IT_TC);* \4 }1 T4 O3 x+ b8 L; A0 K
- }& V9 p) y9 V( `* L. j
- }, e' L' w6 P* E# x$ v) ^
复制代码 ; h! N, N8 \1 S; [" |. V3 J0 ]) V
porttimer.c
# [3 n2 A) L( R8 C
5 O6 A4 D2 l2 X$ v$ U5 z: d; P- & F& t" y( x" b# w7 Q+ i
- ```c
- F2 u! X. C' b2 F - /*
( G4 S' K6 R' }1 J - * FreeModbus Libary: BARE Port3 Z# r" [& Q) [/ D" W* G
- * Copyright (C) 2006 Christian Walter <<a href="mailto:wolti@sil.at">wolti@sil.at</a>>
1 T- b# V2 ~! j, ~ - *2 b" o. H; m6 Z U" o5 O2 O
- * This library is free software; you can redistribute it and/or I, ^: Y% |, R7 P6 w4 a& j- }
- * modify it under the terms of the GNU Lesser General Public
* a. u0 ~$ B# I, C - * License as published by the Free Software Foundation; either
. R& y+ }% I9 p - * version 2.1 of the License, or (at your option) any later version.
) n* H8 d$ ]) v" W: d C5 Z - *
# |# W* s0 D. x8 _ - * This library is distributed in the hope that it will be useful,
8 F) [* ~ i/ d' j7 T$ z- W - * but WITHOUT ANY WARRANTY; without even the implied warranty of
5 l# y, T1 C% M - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
' }7 U- T. T, |5 E - * Lesser General Public License for more details.7 F5 Y5 ^7 X( c k$ X# d
- *5 d. }9 S6 G4 N z( Y
- * You should have received a copy of the GNU Lesser General Public
( Q' R E" L' q# s7 n0 K5 ^ - * License along with this library; if not, write to the Free Software
8 @& @5 f, i3 U8 _ - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA8 _6 `1 d: R+ R! d* H
- *
' \1 g5 s# h9 |( _ - * File: $Id: porttimer.c,v 1.1 2006/08/22 21:35:13 wolti Exp $
8 k2 E8 I$ L) _4 ^ - */0 D: b4 p6 w* `+ D
: x0 @. Z) \7 o4 K6 u- /* ----------------------- Platform includes --------------------------------*// K" Z+ o7 \4 t) _
- #include "port.h"8 P* P0 c& n, y. s
- #include "modbus.h"
+ }) Q* @2 u3 q9 c. q - /* ----------------------- Modbus includes ----------------------------------*/
+ E1 P: W; P( X! i }& a# ] - #include "mb.h"7 b& p5 y3 a! Z; D& ]9 {; y& _
- #include "mbport.h") r x; y$ P; K/ K
- ! _. Z8 |5 F5 I1 r; f
- /* ----------------------- static functions ---------------------------------*/7 Y4 w' L# |3 j% i
- static void prvvTIMERExpiredISR( void );
2 c! s) M5 w7 p+ b7 W5 ?/ ^, v" l - : {+ w4 @3 l# @: `! Q) E
- /* ----------------------- Start implementation -----------------------------*/
* H$ e0 f' R) g3 o" ]; y s - BOOL
4 m# S3 A5 X( e0 N, E - xMBPortTimersInit( USHORT usTim1Timerout50us )2 Z8 F1 g9 V8 s& d9 Q* O t
- {, n. S5 A' q8 K
- modbus_timer_init(usTim1Timerout50us);( q; W* H% _0 d2 Q E: m9 s
' t, l& f+ k! L( g3 m# o1 Z- |- return TRUE;
- @6 i' r0 r" ~( z3 z* e, L - }
7 d& O4 W ]* }4 a* Q0 j - $ I0 {% E- r. ?$ M
- . l. L1 [: ]) k6 t
- void
: G4 J4 I! d) p. T/ B6 ~ - vMBPortTimersEnable( )
- i+ D1 K9 S0 B1 x; l1 F - {
0 N4 I' w5 S5 {$ A/ N9 i - /* Enable the timer with the timeout passed to xMBPortTimersInit( ) */
4 P, A8 y9 S0 ~' K* F$ r2 L; U - TIM_ClearITPendingBit(TIM3, TIM_IT_Update);
/ S; i9 k4 l1 s9 ?- [2 `5 ^9 f - TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE);* Y W% U8 I. q- I' R4 K/ b
- TIM_SetCounter(TIM3,0x0000);
) C& K, U" n/ `# y/ o4 p! T - TIM_Cmd(TIM3, ENABLE);( D0 e# s3 y3 g0 n& @1 z: ^1 t
- }
: `# ^5 s! b+ U k - \: u, \) o G: u5 n8 p' j
- void: t0 x' D% ^3 K: g6 H! y
- vMBPortTimersDisable( )
% L4 i# _( B ?" I- A - {
2 p, {$ z1 i$ d+ V3 N1 i - /* Disable any pending timers. */
$ M/ @, @1 m( O8 z - TIM_ClearITPendingBit(TIM3, TIM_IT_Update);
8 z& Y E2 X9 w7 _% f - TIM_ITConfig(TIM3, TIM_IT_Update, DISABLE);
. ?# N7 J/ I" d - TIM_SetCounter(TIM3,0x0000);
, o# C1 a1 y/ {! Y# C$ { - TIM_Cmd(TIM3, DISABLE);) o$ a1 |2 ^( U* L. P+ E
- }
+ Y1 z) |% L" y - . u( C; y. F& R# C: R; x/ u
- /* Create an ISR which is called whenever the timer has expired. This function0 s6 N' B2 _7 R- G$ _' Y" L
- * must then call pxMBPortCBTimerExpired( ) to notify the protocol stack that# g7 r$ s( W3 }0 S5 b" A1 D
- * the timer has expired.
2 d% X) a$ N0 v1 r$ a2 z - */
8 k4 v1 ?4 S7 S! f7 Q - static void prvvTIMERExpiredISR( void )
) Z+ f/ M' f( Y9 F! | - {
- x* z+ Z; J! \* Y$ k* Z9 I. t- \ g - ( void )pxMBPortCBTimerExpired( );
6 s) U# s2 E4 J5 Z$ S$ E* J3 k - }( i+ O& x7 `" Z5 m9 I1 @- \4 o
- # k# I+ |# I7 q6 q8 a; p
- void TIM3_IRQHandler(void)
* m) i! R7 ?+ s0 G5 h M& D - {2 e" @0 J1 p5 t1 n" R0 ^
- if(TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET)
- |( X2 X5 B5 { u - {2 F/ o" [! u0 q; a4 E$ P
- prvvTIMERExpiredISR();7 w6 |% e- C' j% M+ G' m( M! e
- TIM_ClearITPendingBit(TIM3, TIM_IT_Update);
* i8 s1 L7 `- H* Q0 ^8 w( U - }
2 z& |8 s3 ?2 J' j% z - }
复制代码 % j- u0 i' v1 w6 J6 p3 ~! i; q; |5 @) k
然后主函数中调用% I) P& }. j4 L X' {+ t7 U
3 a d' t/ P8 T
: Y: L7 J; L' B0 y! N( u" H- int main(void)
$ z4 m1 d' @' m$ C - {
) D5 M( z0 w N3 l3 M L - delay_init(); //延时函数初始化
3 T4 \# r# ~# H" ~ - NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
/ {) x* e6 Y$ X9 }& ^* N - uart_init(115200);
1 Q4 R3 Y' q/ T3 f - eMBInit(MB_RTU, 0x01, 0x01, 9600, MB_PAR_NONE);
! D% A+ K7 D' w: t, h- A - eMBEnable();
6 M9 B; u; F0 Y% h# p4 p1 O" t - while(1)
d1 w$ T6 q* t - {
4 \/ J" A2 j% p& d# W! h - (void)eMBPoll();
+ x3 {# O3 @4 l& n$ s0 t. _ - delay_ms(5);
; |# ^+ f1 O1 d, ^ - ) U/ c& [9 n5 i7 _- w9 r$ u6 f
- } " v, [* N4 Q3 B" a. B
- }
复制代码
8 k7 f' ?- p, o9 G其次还要实现读线圈、写线圈、读离散输入、写保持寄存器、读保持寄存器、读输入寄存器等功能,如下: r; p, p& y# T: K4 C0 \- j
/ k, M& ^9 s5 G! C- #define REG_INPUT_START 0x0001 //输入寄存器起始地址0 g1 D# V, S2 v
- #define REG_INPUT_NREGS 8 //输入寄存器数量
4 @3 N& {4 x$ b; M- m) J
4 ~. c0 m( P: Q* t. l6 U- #define REG_HOLDING_START 0x0001 //保持寄存器起始地址
% [5 f8 @9 c7 q) M* ~' Z/ S% M - #define REG_HOLDING_NREGS 8 //保持寄存器数量) B# l2 j' S, g8 }3 ^: A( t
- z& n( i* A3 ?, N3 U* w, q# \3 ?: }
- #define REG_COILS_START 0x0001 //线圈起始地址( |2 [* d0 j$ U
- #define REG_COILS_SIZE 16 //线圈数量
4 H1 E4 K" L( V* n2 v - / V/ d) j* J8 P8 a
- #define REG_DISCRETE_START 0x0001 //开关寄存器其实地址
5 l8 V4 h1 g- \$ E( C - #define REG_DISCRETE_SIZE 16 //开关寄存器数量
' V8 @/ i, \- H/ G - //输入寄存器内容
$ Z7 O$ h% ]5 o$ |4 j" G - uint16_t usRegInputBuf[REG_INPUT_NREGS] = {0x1000,0x1001,0x1002,0x1003,0x1004,0x1005,0x1006,0x1007};! Q( ^3 R2 G9 J; T
- //保持寄存器内容
$ k+ V5 ?& V3 p, q - uint16_t usRegHoldingBuf[REG_HOLDING_NREGS] = {0x2000,0x2001,0x2002,0x2003,0x2004,0x2005,0x2006,0x2007};
0 \9 |# l6 h* b! }$ c0 x3 R, N0 l - //线圈状态
8 a" n4 Q6 {' j/ b1 F - uint8_t ucRegCoilsBuf[REG_COILS_SIZE] = {0x01,0x01,0x00,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00};5 \6 x: Y; X' I
- //离散寄存器内容7 T1 Q9 p4 l; _+ v8 j. n6 m0 r
- uint8_t ucRegDiscreteBuf[REG_DISCRETE_SIZE] = {0x01,0x01,0x00,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x01}; ' g; y& o( ]8 P, s. j. M
- 7 {% B2 m! ~# n- T6 C M
- /****************************************************************************
9 o3 q3 [8 o* u; A - * 名 称:eMBRegInputCB 6 Q. z; e7 _+ O) Q" L
- * 功 能:读取输入寄存器,对应功能码是 04 eMBFuncReadInputRegister
) q9 d& Y- K" q y9 k' G5 c0 E - * 入口参数:pucRegBuffer: 数据缓存区,用于响应主机
( [& w. @" d3 f+ [/ A - * usAddress: 寄存器地址
6 p2 w0 ]5 u7 B - * usNRegs: 要读取的寄存器个数2 T3 o `% I, {) _0 |9 E
- * 出口参数:
* E$ p, I" P3 p - * 注 意:上位机发来的 帧格式是: SlaveAddr(1 Byte)+FuncCode(1 Byte)
% F8 j: Z/ I- s. m - * +StartAddrHiByte(1 Byte)+StartAddrLoByte(1 Byte)
+ ? R3 I* g6 V - * +LenAddrHiByte(1 Byte)+LenAddrLoByte(1 Byte)+( P3 l1 p4 }2 u+ _. q8 |
- * +CRCAddrHiByte(1 Byte)+CRCAddrLoByte(1 Byte)' @( [& l+ s1 F5 v' t: i8 E: q
- * 3 区7 ^' F) c8 p& h
- ****************************************************************************/
* W h; [5 u* J9 n - eMBErrorCode' }; }& M' @/ e4 z6 H! F
- eMBRegInputCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNRegs )
) A" b; W3 @2 C. |1 \! i# D - { e# i/ H+ q% x: \0 t. G3 }: |
- eMBErrorCode eStatus = MB_ENOERR;
7 ~: d% ]# F9 v' u2 S5 Y: C0 J6 o/ a - int iRegIndex;
8 R8 B, \- {2 } m# w
, ?1 p) v! z+ z- if( ( usAddress >= REG_INPUT_START )
7 Z$ c+ A5 Y, R, j - && ( usAddress + usNRegs <= REG_INPUT_START + REG_INPUT_NREGS ) ). F+ N7 S4 e4 R5 O: Q! V) ~
- {
( V% ^ b8 J N6 F# [, Y; x - iRegIndex = ( int )( usAddress - REG_INPUT_START );
1 G* p' c" \7 ~2 g6 w - while( usNRegs > 0 )
1 G0 r: C$ m5 S - {
6 |; ]9 s# z# n+ ^3 P5 {; O - *pucRegBuffer++ = ( UCHAR )( usRegInputBuf[iRegIndex] >> 8 );
$ Y* g3 s, }! i6 t' j: d5 [ - *pucRegBuffer++ = ( UCHAR )( usRegInputBuf[iRegIndex] & 0xFF );
; m) N8 Q0 f) {. f* P2 h4 c - iRegIndex++; O2 [* Z) S7 z/ {, y# r
- usNRegs--;9 h" p# _ O2 N& C# R9 Y
- }/ h* N( | h, ]8 W: Q5 F
- }
" b( ~( j3 ?: {4 Z/ ] - else- R: ^5 P8 z1 G* ~
- {
$ z1 n+ ]8 E T. x3 q6 @+ v - eStatus = MB_ENOREG;& L. C, y/ a# O5 n$ v
- }& y% H8 a4 u4 {+ [) T
- 2 R$ Y) g# }/ v$ X9 i
- return eStatus;: P2 u. [( z# |/ p* D1 ^
- }7 O9 H8 ]+ Y# u7 S* Z W
- . ~, P: C$ J2 l: d7 n. V
- /****************************************************************************
: F! Q7 U9 _. r" k - * 名 称:eMBRegHoldingCB + v9 m3 \, u! J' e! e$ h
- * 功 能:对应功能码有:06 写保持寄存器 eMBFuncWriteHoldingRegister * k. K; G5 Q& f" G" X
- * 16 写多个保持寄存器 eMBFuncWriteMultipleHoldingRegister& I/ f$ H8 _- k4 r O. e/ ]
- * 03 读保持寄存器 eMBFuncReadHoldingRegister* H: S% c( I- W' }7 D: A
- * 23 读写多个保持寄存器 eMBFuncReadWriteMultipleHoldingRegister `# \- m, e! \5 @
- * 入口参数:pucRegBuffer: 数据缓存区,用于响应主机
7 M i1 X1 q/ Z9 @/ i N3 p$ Q( \# P - * usAddress: 寄存器地址
( E, ~, t! U; r! F# ~* ~ - * usNRegs: 要读写的寄存器个数3 d/ D3 q+ ^5 Z8 q) N
- * eMode: 功能码
' _/ t$ n9 A+ ^; t2 L4 G - * 出口参数:
& [; V* D0 K8 N - * 注 意:4 区' `6 \/ o& i3 |5 \& L \" \
- ****************************************************************************/
- K- @" J O5 F. M. o* | - eMBErrorCode+ ?+ M+ V1 L3 ^0 i- W# d1 P+ f
- eMBRegHoldingCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNRegs, eMBRegisterMode eMode )
y2 w- i3 {) N* l, y( `$ z( l2 i - {9 _8 U0 D- y" i0 ~+ k
- eMBErrorCode eStatus = MB_ENOERR;
+ v: u( J% W' M! b - int iRegIndex;
+ \: e% C3 V6 n0 x8 O0 \ - . T+ G% [& \; y8 S
- # `4 P- a4 {+ K0 r0 Y% v
- if((usAddress >= REG_HOLDING_START)&&\
) T# U6 s6 T: T0 k( [ - ((usAddress+usNRegs) <= (REG_HOLDING_START + REG_HOLDING_NREGS))): |8 ]; a* w' o0 [
- {# K. D! K a9 f6 H' n
- iRegIndex = (int)(usAddress - REG_HOLDING_START);% s1 X f a0 B+ a3 c4 a
- switch(eMode)
/ |0 k9 v" O% h - {
4 r. C R. \, c' h8 `2 N% Y - case MB_REG_READ://读 MB_REG_READ = 0
8 p( t0 Z0 T) L - while(usNRegs > 0)( D) e' u3 p3 o! W( ?; b
- {
3 j% i, _; a6 J- v% w9 h - *pucRegBuffer++ = (u8)(usRegHoldingBuf[iRegIndex] >> 8);
; l' G# B4 o( U; k& h$ l; \0 v - *pucRegBuffer++ = (u8)(usRegHoldingBuf[iRegIndex] & 0xFF);
! c, J: {, T$ t6 s9 u - iRegIndex++;
# k- F ]+ ~' o% o2 g8 X+ P - usNRegs--; 4 n* {. v3 l( u. ^7 h6 {9 B
- }
6 m: c$ v M5 i+ Q - break;( i" i* {* M' `
- case MB_REG_WRITE://写 MB_REG_WRITE = 0
) ]( w+ T+ ~) H0 y d0 Z# m/ r - while(usNRegs > 0)
' i, |! L' d) Z. A$ G% E- v2 e+ v - { * C }) [" [6 }( i, O) H7 U4 j
- usRegHoldingBuf[iRegIndex] = *pucRegBuffer++ << 8;' f5 B& i/ S" U1 S: y6 P- a1 i
- usRegHoldingBuf[iRegIndex] |= *pucRegBuffer++;6 w1 x: d. {- Q; N. c
- iRegIndex++;
' r" U" a: r# D( a. K# i/ f - usNRegs--;
. S( Z# |0 X3 i& \ - }. e# w! K& f9 K5 O
- break;
1 i- u, `3 ]9 l$ X! w$ W - }
' ?1 [0 p9 |& E( ?! } - }& g" W9 d$ Q% c
- else//错误* J7 n* K$ T4 ?9 K- D, }
- {; e: `; C' T' B9 ^2 j& e* |6 a
- eStatus = MB_ENOREG;' @, v( I6 ~2 a" z# x
- } % H$ B* m! U& b$ u; a" d: w% Z- T: v
-
: m$ \4 D5 @" C* C% H - return eStatus;
4 ]+ ?& I9 o& c, D/ j8 X - }
7 k7 X# t: R: G2 t/ Y( l7 R5 f
, y @& O1 t* V- /****************************************************************************
! a8 r% f+ D. a9 _ - * 名 称:eMBRegCoilsCB
- ^) Z `( @- i$ w$ `! U, m# E - * 功 能:对应功能码有:01 读线圈 eMBFuncReadCoils8 p4 V9 D4 F0 Z& C& s! q' M
- * 05 写线圈 eMBFuncWriteCoil* L9 [+ y2 ^4 O4 e$ q# |8 V/ ?, _
- * 15 写多个线圈 eMBFuncWriteMultipleCoils" E4 l5 d$ p$ a a' ^1 y9 S; v( ?- x
- * 入口参数:pucRegBuffer: 数据缓存区,用于响应主机
; T5 {' K& p# Y4 m - * usAddress: 线圈地址
7 ?" Z a% O6 i5 `. ? - * usNCoils: 要读写的线圈个数* t. X8 e# r" A6 q* ^* D# r) n
- * eMode: 功能码# u0 h. ~6 B& L4 w d
- * 出口参数:2 K I; K! [" D5 b1 k
- * 注 意:如继电器 : C6 C! k- Z, ]% c1 J9 n0 c' `
- * 0 区8 x0 p7 s v# e- o- X
- ****************************************************************************/
$ e% K+ U1 f& ?+ s( M7 H( o - eMBErrorCode3 o; J' U2 z5 q+ N# D2 D8 V
- eMBRegCoilsCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNCoils, eMBRegisterMode eMode )4 j/ _+ Q( I$ e8 N0 c J
- {
' V2 E6 c8 O+ e. u- e% b* ~# B - eMBErrorCode eStatus = MB_ENOERR;; q8 d. ]+ K2 @( J0 f
- int iRegIndex;+ y8 \' D/ T& \( V5 o3 n
- u8 i;
0 c. F4 t' q: X1 z' c- ~. g - USHORT readNumber=usNCoils;
2 f z/ z( G: Q0 o! @ - USHORT coilValue=0x0000;! p- I) g! P# c
- if((usAddress >= REG_COILS_START)&&\
* k* k& W7 J+ B# E# I - ((usAddress+usNCoils) <= (REG_COILS_START + REG_COILS_SIZE)))8 \, _, L2 p7 [( {
- {# x& o e2 W. U; ]% x; W0 }
- iRegIndex = (int)(usAddress + usNCoils-REG_COILS_START);0 K5 C1 q" A% S+ H! j; H( A, {7 t6 |
- switch(eMode)" Y1 L! S9 C" A3 M. P
- { 8 O3 r. n9 Y* y6 o3 ~
- case MB_REG_READ://读 MB_REG_READ = 06 T0 g( _& h1 \/ i5 f
- for(i=0;i<usNCoils;i++)) x6 j5 t& C8 T. j# s+ R1 I
- {7 Q4 F* x. W' h* O* d$ m2 E) P
- readNumber--;
0 _* r6 ?8 q7 f" v* c - iRegIndex--;
% Z* C! W2 `2 ~1 T. L U2 c Y - coilValue|=ucRegCoilsBuf[iRegIndex]<<readNumber;) U. q, c2 V# H+ H6 o. o' W
- }4 p! n; y7 d* G% |! w
- if(usNCoils<=8)2 [" n- T" E Y) J
- {
6 V+ K. O% G) y' P' b, a# b - * pucRegBuffer=coilValue;, W2 b# b3 x- @9 L
- }
) [' O3 }, F( r9 p- f9 P' h) P - else
3 N5 A8 W r e5 v4 X - {
2 @& W+ ^- }( a: w5 U% e: P5 f, `, M - * pucRegBuffer++ = (coilValue)&0x00ff;1 n$ H4 F' x, \+ U) ^6 C9 P7 C
- * pucRegBuffer++ = (coilValue>>8)&0x00ff;, ?" n/ h/ h) M# J( _
- }
" a. P; T2 s4 r% Q+ d) Q - break; $ U a- U d8 k: [8 c
- case MB_REG_WRITE://写 MB_REG_WRITE = 1
8 x/ O7 L9 y( F - while(usNCoils > 0)
. M7 A) w. F6 ~2 ` - { }- g+ P$ A% h* E) t. a I7 O
- // usRegHoldingBuf[iRegIndex] = *pucRegBuffer++ << 8;
# K% z8 X6 s9 m - // usRegHoldingBuf[iRegIndex] |= *pucRegBuffer++;
% b+ g. T$ M. }. x: v4 u - iRegIndex++;
; A$ G9 u# W, M6 J - usNCoils--;
/ v2 a6 P( P, v# c% \ - }$ ~! b$ o9 O" Q5 X' c' b! c
- break;9 s% |3 l) L# b0 s7 F
- }9 y T7 f+ |$ I4 x% t! {' [
- }! x; ^, |) ? _5 ]
- else//错误) I3 R2 v; j7 Z8 W
- {" {3 z$ L) H# p/ U5 ]5 @
- eStatus = MB_ENOREG;- q' r% _' D( ?& a* B+ i
- }
9 F/ [/ ~1 E& A* B) x' {
% Z2 Z+ J+ J7 r- return eStatus;
4 d2 H! e1 ^; u& |2 }* o - }; W6 V% j- o2 T- H/ D9 {
- /****************************************************************************: c1 S7 {; J# x7 V) _
- * 名 称:eMBRegDiscreteCB 4 _ p5 b W! r4 f
- * 功 能:读取离散寄存器,对应功能码有:02 读离散寄存器 eMBFuncReadDiscreteInputs
" _" {; v" u* F0 b - * 入口参数:pucRegBuffer: 数据缓存区,用于响应主机 " |4 p# Y: x+ d- O
- * usAddress: 寄存器地址
0 k& T( l$ P1 H1 }5 `5 o: m - * usNDiscrete: 要读取的寄存器个数
2 `4 U" n- B9 O k) \, B - * 出口参数: y, x9 a1 u! m9 |
- * 注 意:1 区
/ g" ?6 j) ~% F/ J - ****************************************************************************/8 V2 @! q3 t9 H
- eMBErrorCode: k+ s, `7 Q4 B) v, _+ p) j
- eMBRegDiscreteCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNDiscrete )1 F$ v! J z( ]2 ^3 F; Z
- {
& j+ ~: Y/ m' n6 d - eMBErrorCode eStatus = MB_ENOERR;
0 M/ k1 N+ y; L, ^2 ]7 [+ N - int iRegIndex;
5 u6 M* W' G; U" R5 R$ I9 V - u8 i;
+ U& ^* E2 g$ F. Z- _1 { - USHORT readNumber=usNDiscrete;. w9 m# N" ^- I
- USHORT coilValue=0x0000;& M1 \6 V I8 C- U
- iRegIndex = (int)(usAddress + usNDiscrete-REG_DISCRETE_START);4 L9 b# H8 g- ]! G8 P3 s7 o3 R
- if((usAddress >= REG_DISCRETE_START)&&\/ D+ l7 l- ?0 Y/ G
- ((usAddress+usNDiscrete) <= (REG_DISCRETE_START + REG_DISCRETE_SIZE)))
S2 a f6 \4 I) R% F, a - {
4 q/ j& b5 ?$ Y8 B/ z9 w; H - for(i=0;i<usNDiscrete;i++)* K% d% D4 o: p1 J- s
- {/ S% n5 r; k, L, W* {& {# M
- readNumber--;
- y& S" ~; j3 s- n y( N- C4 I+ R - iRegIndex--;+ t( y* s" U0 _& ]
- coilValue|=ucRegDiscreteBuf[iRegIndex]<<readNumber;
5 d4 I) {5 x; w/ U6 g5 w! ~ - }5 `& y: @' h8 K0 [! D: U9 S
- if(usNDiscrete<=8)
% H" E! T8 F+ S - {4 p/ b F* }7 e9 Z2 x
- * pucRegBuffer=coilValue;
7 h& s5 R! [4 l. Z4 D - }
& h5 X7 X# L. a$ c - else
+ s7 h( T0 A0 { F7 Q7 u - {
! k' B$ t7 c6 Z/ z+ b - * pucRegBuffer++ = (coilValue)&0x00ff;
R3 i; j' C: Q5 w - * pucRegBuffer++ = (coilValue>>8)&0x00ff;. a4 i+ Z( j' u6 x6 a
- }
0 v* l4 \; e) a, C. r9 u - }6 U8 \. L! ? ], F+ }: i
- else
/ ]/ b, C; B, S - {
# @- f; o9 A& b5 E, k8 Q6 E - eStatus = MB_ENOREG;
7 @0 [9 c7 p, Q7 \% S' m - }1 y3 V- j( H" c" s/ f4 V
- return eStatus;, V( z' m/ g2 w. W% k0 O
- }' K0 [7 O4 K( r4 e1 m
, A9 {, j( I" }( e* {. p) O+ F& q8 D- ) y6 E0 O3 }2 J. x
. J, ]9 Q9 O- U9 v8 H% u- 8 ~0 i$ ~ q) E1 _
复制代码 ; ]" ^" M. B( R9 M6 P0 @0 a
; }- U E6 @2 V% O
, a' t4 k) G* K* E+ q |