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