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

【经验分享】STM32驱动URM04超声波测距模块

[复制链接]
STMCU小助手 发布时间:2022-3-25 13:34
URM04简介:, Z2 O; v+ M' j& Z0 n
URM04采用了RS485串行通信总线的架构,支持多传感器的并行工作,有着两个RS-485接口,最多支持32个超声波的并联,8 w" Y; r$ U# B& p2 s' V, K' p
内置温度传感器辅助校正距离值,同时支持温度的测量6 o* F& p, V0 q* \8 H
应用场合:移动机器人,停车场,安全检测,超声波空间定位。
0 d7 R( L3 ^9 t1 u3 M1 M) J" ^; a3 h; E# w5 U( w. T$ T
20190802212451324.png   P/ h9 B8 E9 z7 |+ l

1 R2 I- }! o' a0 N6 a3 N: `性能描述:  U5 v8 X1 t% A8 K/ y( y0 S2 R
工作电源:+5V4 q4 b7 Y! L4 U2 c- V# j
接口方式:RS485  RS485总线通讯,6 o# l7 j4 z/ E# `; _
超声波距离测量:8 G% h4 S! T9 {
最大距离4cm―500cm
0 V, i# E. H# f, g' ]测量范围角度: 60度
  w, @) ^6 H9 C( e# ]芯片型号:Atmel公司的ATmega8芯片  MAX202 MAX485 ST温度测量芯片
& Z) u3 E7 K' _" U& O. @4 L
测量流程:
- Y! P& Q: u% U) }' }3 b- V1触发超声波与温度测量指令
% @5 b4 @: n. k& V* S; k7 G# Q

6 k1 ?4 o, P  J6 q3 H/ H 20190803083618883.png 7 b0 q) `, u, L9 i+ x+ m, H& y  K2 B
7 V7 T7 l1 C$ y, J
发送指令后,超声波开始测量,温度开始测量,无返回值
4 h% S3 x2 k% R  B- J: n# N* T( I
2延时30MS, B! T9 L) K+ I

2 O3 |5 ^4 s0 X+ T$ k/ j" m! }; B+ D超声波最大测距5米,反射路径10米,声速度331米/秒)  10/331=0.03021  //30MS* X1 {# ]* Y& J% c, U
/ q3 n: |1 P; l/ N% o4 H: G! ]1 ?
3超声波测距读取指令! Y- @( Q$ P4 e& [

& r/ p. i" E9 Q& ]$ c 20190803084139157.png * V# ^/ ~! Q$ n8 m9 b
; y1 |  k  V  }. _; c
测量完一次之后,数据会被存储在ATmega8芯片中,只有发送读取指令,才会有数据返回+ ^' u! ?$ j' x1 }

2 K' t  B! }- D% e5 w/ p$ k/ @9 {返回值:8 D  a8 b! x. ~6 B: o9 i

4 u9 ^' l! {3 S! m 20190803085236823.png
) J3 y/ C0 `5 U# x/ A! S4 Y* E5 n& U1 Z4 R0 f
测量成功返回16位距离数据,两字节0XFF表示测量失败* c9 V7 Z4 J$ v7 T5 v& {; Q  j

& r/ b/ X/ A+ v: ~/ p4温度读取指令:
- B' P# W# p0 E& l
& [/ ?/ L& |, P% X& f) Z! _
20190803085701601.png
; Y' {1 j2 r( V/ L  }" y" M  v& T$ [
与超声波只有命令字节不同+ h8 d0 Y3 n9 y- D4 d
' ]! _3 ?% |6 i. [
返回值:) h7 |7 s! z* |/ e1 X7 a

; C$ N! q% W. \8 a 20190803085807113.png
& h; M! }* m1 Y2 Q2 Y  D( Z' D+ q7 ^+ _2 U
调试经验:
6 }) v( r: A, v( q$ \$ _; Z1注意超声波要接的是5V,不是3.3V,使用下载器时一般都是3.3V供电,这就导致在线调试没有数据,应该给板子供上电,下载器不供电,超声波接到5V电源口,并且检测下是不是5V.
( L& {" C+ R4 I% N: w* H5 l" N6 u- w# y7 L$ j, L( v0 x
2.测距时不要距离太近,会导致数据不准确     PS:  太近超声波会有回波干扰 7 j7 g3 J3 U+ b* U: _
! ~/ Y6 c" G, ^( a0 q6 Z
3.超声波测距的性能与被测物表面材料有很大关系,如毛料、布料对超声波 的反射率很小,会严重影响测量结果。2 P& s3 g6 n- f4 w

7 i; m3 U) n0 g2 ~, f4.测距等待一定的时间,如果超时后依然没有数据返回,就放弃,而进行下一次测量。9 D7 \, y2 y; h7 ?4 [

; A; u6 b. ]/ j4.URM04 V2.0 如果与主板有数据交流,其上的LED灯会一闪一闪的
8 s7 B- |& k7 y  X, m0 s' v
" C; X! ]2 G  V7 o5.URM04 V2.0 的波特率为固定值19200。或1152008 W8 j! l  a2 R: ~, N
' c, P- C  v/ @9 q
关于这个找了半天发现是在10年七月之后买的都是19200 之前买的都是115200,# k& A3 Q& b# p0 B6 T4 {6 c

  r9 q5 v0 n* Q1 b, T0 e 20190803092813633.png 3 j+ X# U" P2 y: \$ M4 }  y
: ]& x7 x! T+ g. N# l9 D) Z
6 UATR接收数据的中断要改!!可以自己根据返回的数据特征做相应处理,或者接受8个字节直接退出
, F6 \: w! f7 {/ _
1 O% Z- I& W) L+ b9 o
话不多说我们直接看代码:& ~" o+ ?/ B3 w! ]# `
9 z1 r1 g5 L" i9 D" j
超声波数据测量

, S& [6 f" O, A7 ?# F( h" p! s
  1. /*! & w6 r1 J9 L  a! c* ]  A) B9 x/ p
  2. *  @brief      超声波数据测量  g# d" Z! S( \6 G) E" D1 t& D, D
  3. *  @since      v1.0  P; R+ h- n7 x: }1 z; a6 p  b; i
  4. *  @param  device   超声波地址
    0 h3 Y- c4 F1 e7 W* @1 v! O) O
  5. *  @author     Z小旋, o, d/ A  Q, z
  6. */
    9 P  z# A" M8 r' a" a2 J, J
  7. void MeasureDistance(u8 device) {4 i0 D; }4 [  i( G3 p5 H  y# @

  8. ; d5 k( m6 P( ?8 g
  9.         int i = 0;: H' ]9 g+ A8 ^3 n
  10.     u8 Scmd[6]={0x55,0xaa,0x00,0x00,0x01,0x00};  //触发超声波与温度测量指令
    ) G6 w2 d0 |% |+ k. ^0 `! k
  11.         u8 Tcmd[6]={0x55,0xaa,0x00,0x00,0x02,0x00};  //超声波测距读取指令6 G$ y: h. G2 G/ y
  12.         //SUM效验和. [+ h+ G' C7 ~/ |2 _
  13.         Scmd[2] = device;               
    " B# a. \( t- N9 O
  14.         Tcmd[2] = device;
      S$ V1 I  ~+ s" l6 T7 _0 @6 K: ]! }  Y  _
  15.         Scmd[5] = Scmd[0]+Scmd[1]+Scmd[2]+Scmd[3]+Scmd[4];  //SUM校验和' K! Q. s- ^# Q% d8 o7 j, `" p
  16.     Tcmd[5] = Tcmd[0]+Tcmd[1]+Tcmd[2]+Tcmd[3]+Tcmd[4];  //SUM校验和% u2 J0 C: `; T
  17.         // 触发距离测量。
    % `3 o( t) y: Y: A' M( C4 e: H1 K
  18.   for(i=0; i<6; i++)
    % y6 e! F, |& c# d( g/ S) x
  19.         {
    - s3 m$ d8 l- [) r* @, f" B& r  |1 g- w
  20.         USART_SendData(USART1, Scmd<i>);. v6 V- W, A5 {$ C2 J, |
  21.                 while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET);//等待发送结束% D* y0 f; @6 \+ `2 J) b6 `
  22. 2 o; z: L" U" Y2 T# E1 n6 _
  23.   }
    ) z5 U' T& S& L/ Q3 x" |
  24.   delay_ms(30);                  //延时30ms  
    # j3 O' Z$ Z% y2 x3 t3 `
  25.         4 m6 E  G' y1 v1 I! T, b
  26.   //  发送命令读取测量距离
    2 h2 N( D' F1 Q% L" S5 V  h/ J/ B
  27.   for(i=0; i<6; i++)
    * t# x& @2 o2 ]% y8 k2 w
  28.         {
    5 \; @1 Q( ^6 A; n/ J$ G
  29.         USART_SendData(USART1, Tcmd<i>);
    9 J" I. L' D; b0 Q! @/ _% _" y
  30.                 while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET);//等待发送结束; x% d5 D/ @& V3 Y: L, p& \

  31.   A, E  K* Y9 Q5 k4 L
  32.   }  
    9 C3 b  ?2 T4 u4 Q% Z
  33.   delay_ms(3);8 g1 l9 Y4 c, T& c6 N
  34. }6 H& k8 n  G  W' y$ k. v/ T
  35. </i></i>
复制代码
- }, J- p$ m8 J/ j  y
发送温度就是将Tcmd[4]改为0x03   自行修改即可7 l5 u5 T. H; ]: {" X% H( `

5 x7 W$ `: L8 B9 X+ I! C/ B超声波ID改变
& \# k7 T& j8 v# ]
/*!
, z$ ?# }& Q# j8 [*  @brief      超声地址改变
; |* _- Y$ c- ] *  @since      v1.0' O. T7 A; \( [1 u" S: ^5 n( ]% h
*  @param  device   超声波地址
9 T  T: Q- L8 X6 s4 C" C8 K1 j *  @return 1 表示成功 0表示失败6 ~; \4 c. L% o* H3 U1 e
*  @author     Z小旋* X4 f/ D) j4 h3 p) U, r
*/! ~. x8 J3 s! p
int ID_Change(u8 device) {
4 D  f& l& j( o& d6 a
2 {9 y8 z2 t4 V* Q. ~3 {) t' H        int i = 0;
! {$ `. [) _# ?' q7 t        u8 data[8];) N! q+ p! M) E; J$ b/ l% N$ T
    u8 Scmd[7]={0x55,0xaa,0xAB,0x01,0x55,0x11,0x00};  //触发超声波与温度测量指令- G) ]# W3 W2 D) S& z' h# R* g& Z- E
        
0 w* \: {# W* X, C        Scmd[5] = device;  
, F; j; u/ {% _1 r0 |6 S# |        
  ]9 Y" y: d3 \. o5 U! g& h
$ u& f3 W- Y1 w, U% z  for(i=0; i<7; i++)   l7 s9 ?" Z3 B/ S0 ]
  {. @  T5 D% L/ i
    USART_SendData(USART1, Scmd);* k( X- B3 r3 Z- o
        while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET);//等待发送结束* E- P& ?: i  D! V6 v8 m
    Scmd[6] += Scmd;
+ \9 C8 O, T5 {  }
6 p0 T  i2 h! r9 j( k6 q  delay_ms(20);   
2 {; a" _: D$ S( y5 Z  for(i=0; i<10; i++) //获取十位返回数据,检测是否含有0x01
1 H1 Y$ P4 a% c  \- P/ s' I% A8 f  {* r4 }; {3 I  V8 u" D, _
     if(USART_RX_BUF==0x01) 4 y: O2 c8 S" M* ~
        {* I0 _, k# y9 t& ?, w; h
                return 1;$ C6 j9 D: x0 Q% s# j& ?
        }  & C2 A3 V# U. I. i
  }
" v( o2 H2 p* d* L3 l" P% I6 d0 A
. t8 V* v/ f5 D# S  F" b; l5 Z% }        return 0;
" j; `& e# R& N: [: Y% Z- b}
6 V$ }6 E3 q; d; J0 }; |6 i
5 A0 U3 j" o. p: [; V5 Y8 i1 V: g' N; F4 j! j, l  }- n. G1 _7 l

$ V( O- e6 s' n% h" w超声波接收数据
/ P4 f& B; s  p/*! ' `+ Z" w: @$ a9 @2 b& L
*  @brief      URM04v2超声波传感器返回测量的距离或温度
  ?+ j% g7 {, n/ R *  @since      v1.0; o* L4 r4 R! P0 K" }3 G
*  @param  None
0 d8 l* d3 u- E9 u0 p% w7 Z$ I% u *  @return     测量距离  -1表示上次测量超出范围或不成功
5 @* W8 \! K/ }9 _ *  @author     Z小旋, `* @6 Z" x, o7 h) ?4 J' k
*/9 O$ U3 E  H: C% v5 D
) ]$ @) W4 U4 i4 r% E6 [
int ReadDistance() # \+ d& L! c3 }# B& K: h+ K
{7 Y+ z  a6 v! k% }. S; l
        u8 data[8];
$ |7 Z$ q6 L/ e! q1 {3 u% G    unsigned int temp;   
/ _% @: @- S* I$ M  R    int counter = 0;
4 F9 F, ~9 _$ T" J( }    int result = -1;  6 U" c" t0 T6 q. }& |4 F8 d- g
        int i = 0,j = 0;
* w' X6 ~# F3 [+ |" b* W0 U6 i        for(i=0;i<200;i++)   //数据缓存区最大为200 我们就循环200次9 v) `0 f* L  I' E4 \+ }
        {* e* J- T8 z1 }* c. P
        - c; l% X( c# @% B4 R  v1 h
            if(USART_RX_BUF==0x55&&USART_RX_BUF[i+1]==0xAA)  //检测到回复的字头
4 ^2 k+ W3 ?9 J% `) w- T9 T            {                                           % L. \" V0 Y: a% ~
                " b* o) i. [  x+ m! i* v! r
                    for(j=0; j<8; j++) 7 e) O/ F1 R% X; D+ E1 ^9 b
                    {
- }4 _* N+ b$ M                            data[j] = USART_RX_BUF;      //获取返回数据' z3 @* G5 ^' v' M6 P
                            i++;
" A+ F$ _. V- f) k                    }
+ s, A6 W5 I: L6 j  {* }                                
0 {, V2 a  n7 R+ f) w. F. S                    if(data[3] == 2 && data[4] == 2)    //如果为距离   桢长度为2 命令字为20 G% B' o7 K& i5 R1 K; `8 L
                {! x* }5 ]5 ?* E/ @) i
                           
  W1 H( y- m+ e: Q1 u# i               //  result = (((unsigned int)data[5])<<8))|data[6];   数据合并  如果需要测到255以上用这个" N( {# ?# `- T, a% U. W
                result =  data[6];    //返回所测距离  最大255
4 H: \: i: G' q; V0 q( H7 {                    } * t- i1 m- ?! a
                    if(data[3] == 2 && data[4] == 3)     //如果为温度    桢长度为2 命令字为39 J9 @; H% i# \2 i7 C* t3 g
                    {6 `! u1 v. O8 y* r4 h/ b3 u7 j4 e5 U+ v
                            if(data[5]>=0xf0)   //高四位都为1 温度为正8 u/ k* r  v; L: D2 G) W1 |
                            {
; R& @; e5 z" a: W                    // result= ((data[5]-0xf0)*256-data[6])/10;                 //返回所测温度- b8 ?" ?& Y& q  R
                                    result= ((unsigned int)(data[5]-0xf0)+data[6])/10;  //返回所测温度  
# c" t4 u4 k1 E/ g                            }
* c" D, s8 M: ~! V; m7 s3 _                            else   温度为负
& _5 B& @4 M0 A9 U9 k8 ^% ?                            { # e! \6 T5 Z2 n' F
                                      //result= ((data[5])*256-data[6])/10;                 //返回所测温度
, r. c; X! R% Z& g4 C1 u7 L                      result= ((unsigned int)(data[5]<<4))|data[6];  //返回所测温度3 |; U" m' A9 b
                            }: d& z6 }9 l; X9 |' x  Z
                    }
0 d3 y5 P8 }8 Z7 b) P$ Z                    USART_RX_STA=0;. B" P( g7 ^( t. F$ q
                    return result;
6 G) X. P+ g7 w            }
0 ]6 S! X3 R. r4 e3 G0 {8 c            else % u: q, {4 Z1 p' O+ E
            {
0 u" T2 I- ~2 r9 r4 \9 N                    delay_us(250);: Y% }+ ]  ^+ S! g6 m
                    counter++;
) s4 t+ x9 d* W1 P% k                    if(counter==200) //如果50ms还没有数据返回,退出测量并返回-1  l; o7 }* ]0 b% u2 V* f3 c5 V- f
                    {
7 E9 c% \, u! l9 s                            return result;2 D$ X; L! i* a6 h
                    }
; o9 T( D* e  A4 b2 q            }        8 t  {6 u2 x# C& |! b1 N) [; A
    }
& C  {* F. ^9 P: y% `+ Y' q}
9 p! a: ]. L+ `3 X5 T, }
; H3 o$ ~/ {  t9 o! y; V$ s8 p# s% n& t3 n3 X) U
; t) x. t4 Z9 e$ y" u' T
这里只接收低八位,保证最大能到2.55米 ,如果需要测得远用注释的那行就行,还有很多事,本来想写一套完整库,但是没很多时间,就到这里吧,没有心情去继续完善这个了,万分抱歉,很您可以参考一下,希望能有一点用 ,不足的就是接收数据,需要修改UATR的接收中断的数据处理,我改的不满意,就不上传了* x- G2 o8 y) P. j2 ]5 ]

$ K8 m; s0 X3 i5 X. a( a您可以自行修改,还有要注意检测不到数据需要及时退出,不要死等,单片机里最好不要有可能是死循环的存在' k: Z' g2 P! _
void distance()$ p0 M. j" }$ ]# ^. v) }. ?
{        ; V* g  m2 M, G% F7 _# M. [
  int Distance=0;/ ~: O& w$ |3 D/ d+ ^
  MeasureDistance(0x11);) z4 V0 h- h; |1 p4 p* L6 Y9 j
  Distance = ReadDistance();8 i' p7 O& q  B& ~! X- ~( M6 T
  delay_ms(1000);, Q5 [! u- \: o2 d. w# ^: l
}
! _: M$ t. r8 X7 z" f$ {4 @; K1 S0 j$ E* V8 q
8 Y3 G! ~; r* P6 A' ~
1 l/ {' ^" |1 b- m
赞 收藏 评论0 发布时间:2022-3-25 13:34

举报

0个回答

所属标签

相似技术帖

官网相关资源

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