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

关于类ModBus协议的例程分享

[复制链接]
cuyebiren 发布时间:2020-8-15 17:25
哎,长久不玩,基本的ADC、Time模块都不会用了。。。% }: a- x0 v2 K! o" d) c
大家应该遇到过类似:头、地址、命令、数据长度、数据、校验 这种格式的协议,比如 刷卡器模块、电表模块、串口屏等基本都是采用这种格式的协议——我称之为类ModBus协议,因为它不是严格的ModBus协议4 d1 f/ ?7 J+ Y
- R' Q4 L: _0 L! ]  w: M9 D8 ^
本例程所用开发板:普中PZ6806L
9 b- W/ v" t; k8 g* w- @8 z6 s本例程功能:通过UART控制数码管显示 0~9$ b2 `1 _. d1 t3 C, u
本例程所用的协议:
' x/ o6 y$ m- G" A+ y& G协议格式:head     address    cmd     length    datas    check  d" Y& T* W6 B& o3 s: N  F: K# A8 k9 l
bytes     :      1           1           1           1          n          1: P! k# z, [9 J$ a6 q6 U
说明:
. I$ P: ]$ y6 N1、length = datas 的长度,本历程固定为 18 E+ y) t; e: K* p/ P$ I
2、check  = address、 cmd、length、datas 的异或值
; U" o3 _* {: i1 U3、cmd 取值范围:0,1,2,3, ... 10,
. `8 Q. G+ P8 H) V; }      对应功能分别为:cmd = 0, 显示字符 0、cmd = 1,显示字符 1、。。。cmd = 9,显示字符 9,cmd = 10,循环显示 字符 0~9,间隔500ms
" d" @# P$ p+ w4、datas 字段未使用,可为任意值! ?: f. A$ [- `7 C0 u# ~
5、一般接收到报文后,应当返回应答信息,本例程为报文原样返回& X& _" q( C: x) B

- T- e; h. @0 A* r& E( t' W9 X
CubeMx配置过程:; z$ U* m# A' Z
配置过程附件里也有

9 S3 p. c2 X3 o4 R1 i" l' l 1.JPG 2.JPG 3.JPG 4.JPG 6.JPG
! s/ U8 r9 h( J( A" c: E! o% I* c8 d1 S6 H0 G
5.JPG 7.JPG 8.JPG 9.JPG , U, S7 I6 v. O9 z

1 j% ?: H# U- Z, e7 b- C; j% I- x& ]6 D% p. u% M
编写测试代码:
* a* `* I4 }9 ?9 j" ~. ?4 l这里主要说两点:
7 g+ n7 e& K) w* m% [1 i1、HAL_StatusTypeDef HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size); 2 D# a2 O) A4 _
12.JPG
0 j: P& L% L/ K! W. U3 _/ w% M- {9 D6 |/ l% l' j9 m, C7 d
   我发现,使用HAL库按标准库的方式处理UART通信也是可以的,这里把 Size 设为 1 即可,然后需要在UART回调函数中重复调用此函数;——我没有经过长时间大数据测试,不能保证这样做没有问题。# n7 A# _% I8 [9 }- R2 H5 I: u
2、善用 状态机。
' `. _$ _, D7 z+ e, o. ?: f# V  个人感觉 C语言 的难点就这4个:结构体、指针、状态机、软件寄存器(位域)- y) U& {" \1 C5 I! y
  接收状态机:8 t: Z# p# H" p! }" G& f# d7 b
   2640509f7e3037aeaa32da80832b1ef.jpg % A: V7 d8 A. X# Y
  1. switch(uart_rec.state) // 状态机-接收协议处理
    # y- E1 m5 m2 _9 t4 [# B
  2. {            // 协议格式: head(1byte)/address(1byte)/cmd(1byte)/length(1byte)/datas(length byte)/check(1byte)
    2 N& ~) M, ?1 y7 _+ u( h9 C
  3. case UART_Idle:
    : `5 Z1 T6 u6 R! r$ [+ ^
  4.   if (uart_rec_tmp == uart_rec.head) // UART_Idle ==> UART_Head+ E8 W# V9 T. F- |; G4 [& X6 ]5 n4 l
  5.    uart_rec.state = UART_Head;
    1 {+ c. _1 q% n3 p- v
  6.   break;) p" q4 S" \/ `8 c- l& y' U6 ]3 `
  7. case UART_Head:
    2 [- N# |' h9 E2 ^. o) D& T# ~9 k
  8.   if (uart_rec_tmp == uart_rec.addr) // UART_Head ==> UART_Addr
    / M8 h% f# x6 w2 w! H3 O
  9.    uart_rec.state = UART_Addr;
    2 ~( W9 @; N* V
  10.   else if (uart_rec_tmp != uart_rec.head) // UART_Head ==> UART_Idle/ T$ k( r/ A" V/ g
  11.    uart_rec.state = UART_Idle;
    7 T0 y1 l( B" S+ n
  12.   break;
    4 {, m" m6 P7 {. k( B  j
  13. case UART_Addr:& a4 v9 T7 o0 `( A: T' C
  14.   if (isValidCMD(uart_rec_tmp)) // UART_Addr ==> UART_CMD
    - E. @; v6 E& v/ w
  15.   {
    8 z( b0 t; n& L# n" V
  16.    uart_rec.cmd = uart_rec_tmp;
    . y6 u+ |& G. G2 }  _
  17.    uart_rec.state = UART_CMD;/ G, x* T+ P8 U+ w
  18.   }
    2 w4 _6 A' y5 @  M' M
  19.   else if (uart_rec_tmp == uart_rec.head) // UART_Addr ==> UART_Head
    ( n# L* }' G4 x
  20.    uart_rec.state = UART_Head;
    3 g+ i% d. h9 M2 Q
  21.   else             // UART_Addr ==> UART_Idle
      I( i0 ~* R. o
  22.    uart_rec.state = UART_Idle;2 {- x) t7 f! {! R9 L
  23.   break;
    4 ~' w; N. c4 d7 _. J
  24. case UART_CMD:
    - T4 q! g7 a$ O, y' T
  25.   if (isValidLen(uart_rec_tmp))
    ! g( V4 K' h. q6 b2 k
  26.   {, y' _& N2 g+ h0 ?6 a& N9 E
  27.    uart_rec.len = uart_rec_tmp;8 X  w* I1 N  l% v
  28.    uart_rec.cnt = 0;/ C+ w' Z" u$ G; x* \/ }
  29.    
    % k9 l' u# |7 @
  30.    if (uart_rec_tmp == 0)  // UART_CMD ==> UART_Datas" A: I* k4 y& H" Z
  31.     uart_rec.state = UART_Datas;
    ; [5 D" H2 x/ `: O% K3 h$ E$ `
  32.    else           // UART_CMD ==> UART_Len
    " A9 v9 {! Q+ `- h
  33.     uart_rec.state = UART_Len;* F1 K' H# y* z0 U. {/ u
  34.   }5 j" [) a! f! w3 @4 f' x' t
  35.   else if (uart_rec_tmp == uart_rec.head) // UART_CMD ==> UART_Head
    : {* F& Q" \% @4 V) L: {
  36.    uart_rec.state = UART_Head;
    . L& y% A7 P' ]; p+ m2 A
  37.   else             // UART_CMD ==> UART_Idle
    1 b( x- u  y  V3 o; s+ \9 B9 |
  38.    uart_rec.state = UART_Idle;
    3 h7 f/ `, k2 _/ j- Y: B
  39.   break;, q  S# \9 e/ {+ I% X$ U
  40. case UART_Len:! a/ `5 L0 i& M: i$ J0 f
  41.   uart_rec.buf[uart_rec.cnt] = uart_rec_tmp;
    $ D: G, N+ n* v
  42.   uart_rec.cnt++;
    * J% @6 X2 A! |, @1 F( e1 M4 Y- P
  43.   
    9 P( U: M" }4 {3 I2 ~- D; v# W- g
  44.   if (uart_rec.cnt == uart_rec.len)  // UART_Len ==> UART_Datas
    2 W- h) D$ _3 M. \5 `! h/ K
  45.    uart_rec.state = UART_Datas;
    ) \1 \5 ?- l5 u( |4 A
  46.   break;* t, d9 @. s& W  m! w  c
  47. case UART_Datas:
    8 [3 A' x. c4 Z5 w+ @; W
  48.   if (uart_rec_tmp == checkUartBuf(&uart_rec)) // UART_Datas ==> UART_Complete
    , W+ ?. g6 w1 A1 X( X
  49.    uart_rec.state = UART_Complete;
    ' y8 b" @% b& l* _1 K9 e
  50.   else if (uart_rec_tmp == uart_rec.head) // UART_Datas ==> UART_Head
    , ?" Y  s: ?! Y3 |1 M
  51.    uart_rec.state = UART_Head;
    1 O" y' d3 w  b' [0 {/ h
  52.   else                // UART_Datas ==> UART_Idle
    4 ]; h, v+ e+ @/ N
  53.    uart_rec.state = UART_Idle;5 r: _( s4 F4 |' O7 V% C
  54.   break;, ^; T: N$ u, D9 _5 I& X
  55. case UART_Complete:  // 在 uart_recHandle() 中 UART_Complete ==> UART_Idle
    ( t, y  m  A+ m) Z7 C! A
  56.   break;
    ) N5 s7 B3 D: P" H5 l1 V8 c
  57. default: uart_rec.state = UART_Idle; break;" J& o; h0 e* C6 V2 j# R
  58. }. M5 W' c  i. P! r- G$ H
复制代码

4 F- q2 V3 u& ?; }# g; ]测试:(测试视频请查看附件)
: x$ \4 Z: J: C3 F  @, S' e* a 13.JPG
) a/ u! ]4 I2 Z1 P. W, F
/ m7 I$ g# v0 w, i
& l; f* z0 C8 i6 I2 p奉上全部工程和文件:% f7 p8 v5 T- F- f- a- ]1 g
modbus_fake.rar (18.69 MB, 下载次数: 72)
赞 2 收藏 2 评论2 发布时间:2020-8-15 17:25

举报

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