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