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