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