你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

STM32F的232口简易MODBUS-RTU通讯程序

[复制链接]
incompletely 发布时间:2008-9-3 20:07
/*****************************************************! `5 Z  o7 W: F* l, y% _
          modbus-rtu 通讯规约
& H2 |" W& z4 k( Q通讯方式:rs-485 半双功
8 m' W; P* `6 Y( u校验方式:crc16
) p5 X, n6 \: M3 H5 H" |7 Z1 E9 m$ k$ T. j+ l停止位:2位
9 R. e/ I4 E- B8 S2 I: L编写:孙可
  ~2 b' O8 ]$ o! V( y0 n; n; o编程思路:
7 W6 ~8 O* g- ~    1.串口中断允许自动接收总线上的信息,当接收的字节后超过3.5个字节时间没有新的字节认为本次接收完成,接收完成标志置1;如果接收完成标志已经置1又有数据进来则丢弃新来的数据。! R2 ]0 k7 x5 g4 Z
    2.串口接收数据的处理, 当接收完成标志置1进入接收数据处理, (1)首先判断接收的第一位数据与本机地址是否相同,如果不相同清空接收缓存不发送任何信息; (2)接收的第一位数据与本机地址相同,则对接收缓存中的数据进行crc16校验,如果接收的校验位与本校验结果不相同清空接收缓存不发送任何信息;(3)如果crc16校验正确则根据数据串中的命令码进行相应的处理。$ Y( u% Q* H2 h! U2 e# f2 ?! x0 l( Y& @* A
******************************************************/! i1 D; u  `& l1 u' I& _
! m6 l+ x; y, ?  a
#include "modbus.h"* v) J$ s; M4 R! N8 |& N# p% }* H
u8 Com0_id = 0x05;//本机串口0的通讯地址3 ]- B2 r5 d0 b
u8 Uart0_rev_buff[100];//com0串口接收缓冲区/ O3 W5 D1 S" M% b; S" X
u8 Uart0_send_buff[100];//com0串口发送缓冲区7 y1 _& w6 g4 X) t7 q
vu8 Uart0_rev_count;3 s0 k3 i$ c5 _: X2 i- e7 h/ \- w
vs8 Uart0_send_counter = 0;
1 G6 g: y3 U# f1 a" R; D- ovu8 Uart0_rev_comflag;
4 P# M$ Q# w) \2 Nvu8 Crc_counter = 0;//com0校验计数器" H5 F# \, Z1 }
vu8 *Uart0_send_pointer = Uart0_send_buff;//com0串口发送指针
5 }  O/ Y4 G, h  O% P) P  Kvu16 Mkgz_bz = 0;//模块故障标志1:输入异常,2:过压,3:欠压,4:过温3 k4 w+ O1 G2 t7 T2 k6 i5 N, h
vu16 Out_current = 50;//输出电流
( `) d: N2 l4 C9 [1 |4 Wvu16 Out_voltage = 240;//输出电压3 P% ?- D: W/ y1 c' V
vu16 Mkzt_bz = 0;//模块状态标志
& N7 v, k0 ~7 F; H9 Evu16 OutX_current = 1000;//输出限流
, [) C' G, l; Y/ x6 _4 \* E3 `" E- p* Kvu16 Jc_voltage = 2530;//均充电压  I; P& k& r' o, X: f* U% G2 C
vu16 Fc_voltage = 2400;//浮充电压' Y, ]5 T$ o) x" Q: L: d
vu16 user_day = 1825;//使用天数, S1 F! I( t$ P9 H2 j. e

0 A" B( c( z. P) ~+ n: D2 [7 X) Vvoid Delay(vu32 nCount);
' h; Z* o/ x7 \6 f& l) m, [3 sunsigned short getCRC16(volatile unsigned char *ptr,unsigned char len) ;
: B3 a* ]. f' [- c3 P2 vvoid mov_data(u8 a[100],u8 b[100],u8 c);
) f# F6 [- o* F2 s3 q0 pvoid Modbus_Function_3(void); - s4 M" |# J4 ^( R! Y8 v  k
void Modbus_Function_6(void);       $ W' z2 d: ?- P% y8 v% h
/***************************************
* T0 n3 ]6 w! J% Q' c7 U% }函数名称:crc16校验
% ]2 R: i" h; c: J: ]" T/ K函数功能:crc16校验$ r" F7 O  `! ]: S; m& [( O# \3 ?
函数输入:字节指针*ptr,数据长度len5 t0 I) D. T* O, ?& j7 F5 |
函数返回:双字节crc' j( P, ~& o9 A
函数编写:孙可
& s% L9 n: h2 c. L0 C) g编写日期:2008年6月9日; F' W7 k5 O& j! D
函数版本:v0.2% K; X# Y+ e) i* [, J
****************************************/
( m$ s4 Q5 a6 e$ V- t* o8 Cunsigned short getCRC16(volatile unsigned char *ptr,unsigned char len) / Q4 h! w( r) B4 k, F2 K! S
{ ! \, b3 T  T! k: W5 r& u+ ~8 ^. j
    unsigned char i;
: ?! U( q' `- S8 P( m8 |$ G. G) ?    unsigned short crc = 0xFFFF;
; ~: _; J0 c/ d8 f- m5 Z    if(len==0)
9 S- V$ \9 q' |. S: c' L3 q! [% f0 t    {
  ~% k5 i7 ]: I  i7 m  `        len = 1;; m# X7 e1 ?8 n; m* ]# u& ~
    } & d  z( I$ n5 M% |- ?4 n
    while(len--)  
; I! f* E' n) _( e9 {4 [    {   4 ^7 t" l3 T; @
        crc ^= *ptr; # @% z4 T9 s( a) Y) X7 j$ z4 b: X
        for(i=0; i>= 1;  ; m0 _3 }- y  d( k; H: b- a
                crc ^= 0xA001; 2 P* W$ b: U2 W: r2 Z' x
         }  ( \3 a8 R- ]0 A* B/ h( M- _
         else , R' q) U% K) [& Q
      {7 r- L$ {" L  z" B. r/ P
                crc >>= 1;9 E* @5 |" q; F0 J) n# o  M
         } 8 a! e" _& o# D( ~0 L$ _
        }         
$ i" q$ o+ h% M) D8 G3 k2 j6 g7 j        ptr++; ( }' h0 Q3 g% d
    } 7 h& v* _1 B2 B. N
    return(crc);
3 z/ l: c& Z7 Z$ ]- {, B" A} ' |( p# b9 c+ ?' U" ~  g( |
/***************************************
9 X8 F  s" x) y- \    块数据复制数据函数
2 x  h2 ?; m3 _; q功能:把数组a的c个数据复制到数组b中
+ W/ S! P- H( |8 u输入:指针a,指针b,数据个数c
. N$ x4 S" ^7 L  H$ y/ H2 J! W返回:无* y0 I" f  y* K+ a6 B
编写:孙可
) w8 F1 a' |) L" x: P1 p% Z编写日期:2008年3月28日+ f) X/ D8 E- R# _: Y4 W  c9 B; {
版本:v0.1
3 _6 n- X! Q! g8 _* r  Q****************************************/8 f* x9 [+ V; I; M7 S4 ^# V
void mov_data(u8 a[100],u8 b[100],u8 c)! P% e5 j8 G' O$ b$ t! H
{' h8 j; U6 s; M
    u8 i;
0 S6 U( c0 |! N2 u    for(i=c; i>0; i--)5 p* p# c" j. k
    {
; W# q7 V: T6 O8 ^            a = b;3 g  Q' F. L6 ^  D; A" Q
    }
7 [8 W. |, t* b7 W$ a  @}% v. g- ~+ O" N9 ]2 j
/////////////////////////////////////////////////////////////////////// 4 J- j& |  r! e3 B/ |
void Modbus_Function_3(void) 0 ]9 Z# j% i$ M
{
/ U) S; f6 p, G0 v0 u+ [    u16 tempdress = 0;
4 O8 \, T( F2 W1 R+ u% A    u8 i = 3; / U/ _: ^2 Q: T/ }3 q/ i
    u16 crcresult;         
# \; `# I/ w6 k    tempdress = (Uart0_rev_buff[2] = 0x0120) & (tempdress + Uart0_rev_buff[5] < 0x0132))" y/ v! ]+ W  u2 G5 T! j4 M
    {; h- g0 J% J. u" e
        Uart0_send_buff[0] = Com0_id;
9 \& ~& ~. ]. ^  K8 [6 w  j- G        Uart0_send_buff[1] = 0x03;
( C6 \) h0 t$ a8 g! Y4 X0 b$ Y        Uart0_send_buff[2] = 2 * Uart0_rev_buff[5];
* V  k4 g( z. x8 K4 R        Uart0_send_counter = 2 * Uart0_rev_buff[5] + 3;
/ s0 r# i& u% E2 y        switch(tempdress); n- v- M1 ~( W# e# m; b" }+ P
     {( p: O, ?0 y9 N/ O
            case 0x0120:
3 \1 r  H! ^' R: O/ i5 H; K      {; |3 `+ p( k/ c. {' q
                Uart0_send_buff = Mkgz_bz & 0xff;
9 f, o& q  x) G* I  Y          i++;2 _- Q9 r( D. s- w0 _$ w7 c
                Uart0_send_buff = (Mkgz_bz >> 8) & 0xff;
- \  m) z# J7 Z: J# N             i++; 4 D8 c3 l# S! w; i
            }//后面不放break的目的是继续往下执行
  O; u; J& R3 s            case 0x0122:
3 z. R+ r( N. I$ n2 b2 I      {$ r" a. z/ ?( X% p; V
                Uart0_send_buff = Out_voltage & 0xff;! ~/ P3 t$ Z! ~/ q' }1 Z
          i++;9 r/ g. E' E& Z$ N, L1 R! S
                Uart0_send_buff = (Out_voltage >> 8) & 0xff;8 |6 {7 e9 T9 E/ g4 y
             i++;
, v9 C* m' Y6 r) u* b+ p1 ?      }1 h  J- |- g/ k. h5 R. e/ u3 ]6 @( ^
            case 0x0124:
  ?  P8 i' x5 t6 }$ r9 J& R7 v      {- `' e) |1 @' E& A, H0 Y, z1 O
                Uart0_send_buff = Out_current & 0xff;
7 T: S7 D' }8 h4 f2 \          i++;
6 C. M" G8 [3 f, L& W                Uart0_send_buff = (Out_current >> 8) & 0xff;( }1 G" {' y3 q  {3 }0 M2 a+ p6 s
             i++;
, K" D* ^( @$ Q2 h7 N- q7 M7 B( a      }
. I6 |' D8 Q0 w( j            case 0x0126:
' u* x, K0 z( i0 }$ Q      {
; S+ k" O0 s8 ~& K                Uart0_send_buff = Mkzt_bz & 0xff;
  ^7 ?5 U6 E8 q& o0 `9 X          i++;
' o# ]0 f0 a4 ?. `+ `                Uart0_send_buff = (Mkzt_bz >> 8) & 0xff;
( o; b: ^4 S3 J7 c4 ^             i++;
- _: b  C( [  R* s, q; F      }9 y6 W" n* F* g* [: s0 @
            case 0x0128://这个地址是备用的里面的数据没有意义! p# y4 l- E4 t) l# q
      {! m0 K% y2 ^& p8 f1 ^
                Uart0_send_buff = 0x00;
+ w) s7 K2 S' U% r9 Z1 {) N( B7 o          i++;
! J  n, o0 y' F) E4 k- S6 y                Uart0_send_buff = 0x00;7 h! \8 {  A/ C" N
             i++;
0 ]; j" `7 R4 K5 Z- K; L7 L: q      }6 d+ m- r" x" k
            case 0x012A:
  ]; Q+ l# N- d9 A4 z( }      {
, i& V- @* p0 d4 D( M                Uart0_send_buff = OutX_current & 0xff;
& v: X9 D2 g+ Y- z" v/ x3 U) s          i++;5 a* D+ G- S3 C- f$ K9 c
                Uart0_send_buff = (OutX_current >> 8) & 0xff;) O$ \+ |# f6 X( N
          i++;# N6 z- \, u" S
      }/ q4 p5 X# H  s- L% c& H
            case 0x012C:
; G6 Q: E5 B1 ^( Y  Q" m      {
' Q; A6 P' D8 C2 E) `                Uart0_send_buff = Jc_voltage & 0xff;
* w7 m, \0 L6 v: N          i++;
2 A, `8 K2 J1 [4 F( }# a+ t                Uart0_send_buff = (Jc_voltage >> 8) & 0xff;9 r0 ]7 |0 k; }0 W4 W+ e0 w
          i++;
2 P, I( Z, P& Z% M  D2 T0 y6 F4 `      }
4 u; Q7 @7 B+ d/ \- z7 O0 {& Q  K            case 0x012E:
" S) y. g, H( ?      {
! R# k4 `9 T9 l. I! t  [                Uart0_send_buff = Fc_voltage & 0xff;0 b$ [% q  R' d3 j: z% ^% \! ]4 s) Z
          i++;: a& B1 ~- K6 e5 Q& M% B
                Uart0_send_buff = (Fc_voltage >> 8) & 0xff;
9 N; A2 r8 N( ]# k! G          i++;
: J* f7 F* T- [$ M& v6 z      }
$ h1 |8 k" l3 u) I            case 0x0130:7 j3 ^/ h0 U/ f* p
      {
  G1 y+ l: k& {& H# P+ [, E8 {0 x( }                Uart0_send_buff = 0x00;/ ?. J6 U: F8 \  f/ u/ U
          i++;
1 A" T/ O. h" o                Uart0_send_buff = 0x00;
, ~5 I- h) t* V, u3 _          i++;! \5 e0 y0 T! J5 X3 y5 V5 f
      }
) U' d* {- ?+ i2 W* I# R; d+ r     } 3 T1 y$ |- \. h0 Z& J
        //UCSRB |= (1
赞 收藏 评论10 发布时间:2008-9-3 20:07

举报

10个回答
qsj 回答时间:2008-12-28 14:27:45

RE:STM32F的232口简易MODBUS-RTU通讯程序

qazwsx333-13599 回答时间:2009-6-19 10:41:44

RE:STM32F的232口简易MODBUS-RTU通讯程序

billylu06 回答时间:2009-9-3 09:31:35

RE:STM32F的232口简易MODBUS-RTU通讯程序

真的實用,省了時間
judge1 回答时间:2012-12-9 19:39:49

RE:STM32F的232口简易MODBUS-RTU通讯程序

谢谢楼主无私分享。
hai2000 回答时间:2013-7-25 10:15:01

回复:STM32F的232口简易MODBUS-RTU通讯程序

大哥有几个地方,我不太明白:1----Crc_counter似乎只有定义,但是没有赋值;2---Uart0_rev_comflag 问题同上  3----似乎没有主函数MAIN* T( t  @: _' b2 o
为方便沟通,特此留下QQ1024829053
walkout 回答时间:2013-7-26 14:01:17

RE:STM32F的232口简易MODBUS-RTU通讯程序

看看
horseman 回答时间:2017-10-23 07:36:56
Thanks!
owenqll 回答时间:2017-10-23 08:47:13
void mov_data(u8 a[100],u8 b[100],u8 c)
  \6 G( m! o2 z{
1 X7 }, F* q* p* q7 R5 f3 T6 V    u8 i;8 |  j6 p8 L: ?  o
    for(i=c; i>0; i--)' s9 V6 E7 h' k9 c: p8 q, ]' j
    {
  M8 R0 u. a6 J. f( D% Z# V, w            a = b;2 W/ I8 A$ l! b, i5 c7 M6 W2 B
    }
# q! w% {5 b% {}3 S$ d! o( D1 X; i& F7 j1 W( x+ z; R2 J

) `7 s" o7 b. r0 ?6 B这个函数有问题吧? a、b分别是数组名称,能直接用a=b吗?
awxcd 回答时间:2018-7-9 18:01:28
谢谢
超声波¹³⁹⁶²²²²³¹³ 回答时间:2021-2-13 00:48:33
正好研究MODBUS。学习了。

所属标签

相似技术帖

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版