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

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

[复制链接]
STMCU小助手 发布时间:2022-3-25 13:34
URM04简介:
URM04采用了RS485串行通信总线的架构,支持多传感器的并行工作,有着两个RS-485接口,最多支持32个超声波的并联,
内置温度传感器辅助校正距离值,同时支持温度的测量
应用场合:移动机器人,停车场,安全检测,超声波空间定位。

20190802212451324.png

性能描述:
工作电源:+5V
接口方式:RS485  RS485总线通讯,
超声波距离测量:
最大距离4cm―500cm
测量范围角度: 60度
芯片型号:Atmel公司的ATmega8芯片  MAX202 MAX485 ST温度测量芯片
测量流程:
1触发超声波与温度测量指令


20190803083618883.png

发送指令后,超声波开始测量,温度开始测量,无返回值

2延时30MS

超声波最大测距5米,反射路径10米,声速度331米/秒)  10/331=0.03021  //30MS

3超声波测距读取指令

20190803084139157.png

测量完一次之后,数据会被存储在ATmega8芯片中,只有发送读取指令,才会有数据返回

返回值:

20190803085236823.png

测量成功返回16位距离数据,两字节0XFF表示测量失败

4温度读取指令:


20190803085701601.png

与超声波只有命令字节不同

返回值:

20190803085807113.png

调试经验:
1注意超声波要接的是5V,不是3.3V,使用下载器时一般都是3.3V供电,这就导致在线调试没有数据,应该给板子供上电,下载器不供电,超声波接到5V电源口,并且检测下是不是5V.

2.测距时不要距离太近,会导致数据不准确     PS:  太近超声波会有回波干扰

3.超声波测距的性能与被测物表面材料有很大关系,如毛料、布料对超声波 的反射率很小,会严重影响测量结果。

4.测距等待一定的时间,如果超时后依然没有数据返回,就放弃,而进行下一次测量。

4.URM04 V2.0 如果与主板有数据交流,其上的LED灯会一闪一闪的

5.URM04 V2.0 的波特率为固定值19200。或115200

关于这个找了半天发现是在10年七月之后买的都是19200 之前买的都是115200,

20190803092813633.png

6 UATR接收数据的中断要改!!可以自己根据返回的数据特征做相应处理,或者接受8个字节直接退出


话不多说我们直接看代码:

超声波数据测量

  1. /*!
  2. *  @brief      超声波数据测量
  3. *  @since      v1.0
  4. *  @param  device   超声波地址
  5. *  @author     Z小旋
  6. */
  7. void MeasureDistance(u8 device) {

  8.         int i = 0;
  9.     u8 Scmd[6]={0x55,0xaa,0x00,0x00,0x01,0x00};  //触发超声波与温度测量指令
  10.         u8 Tcmd[6]={0x55,0xaa,0x00,0x00,0x02,0x00};  //超声波测距读取指令
  11.         //SUM效验和
  12.         Scmd[2] = device;               
  13.         Tcmd[2] = device;
  14.         Scmd[5] = Scmd[0]+Scmd[1]+Scmd[2]+Scmd[3]+Scmd[4];  //SUM校验和
  15.     Tcmd[5] = Tcmd[0]+Tcmd[1]+Tcmd[2]+Tcmd[3]+Tcmd[4];  //SUM校验和
  16.         // 触发距离测量。
  17.   for(i=0; i<6; i++)
  18.         {
  19.         USART_SendData(USART1, Scmd<i>);
  20.                 while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET);//等待发送结束

  21.   }
  22.   delay_ms(30);                  //延时30ms  
  23.         
  24.   //  发送命令读取测量距离
  25.   for(i=0; i<6; i++)
  26.         {
  27.         USART_SendData(USART1, Tcmd<i>);
  28.                 while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET);//等待发送结束

  29.   }  
  30.   delay_ms(3);
  31. }
  32. </i></i>
复制代码

发送温度就是将Tcmd[4]改为0x03   自行修改即可

超声波ID改变

/*!
*  @brief      超声地址改变
*  @since      v1.0
*  @param  device   超声波地址
*  @return 1 表示成功 0表示失败
*  @author     Z小旋
*/
int ID_Change(u8 device) {

        int i = 0;
        u8 data[8];
    u8 Scmd[7]={0x55,0xaa,0xAB,0x01,0x55,0x11,0x00};  //触发超声波与温度测量指令
        
        Scmd[5] = device;  
        

  for(i=0; i<7; i++)
  {
    USART_SendData(USART1, Scmd);
        while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET);//等待发送结束
    Scmd[6] += Scmd;
  }
  delay_ms(20);   
  for(i=0; i<10; i++) //获取十位返回数据,检测是否含有0x01
  {
     if(USART_RX_BUF==0x01)
        {
                return 1;
        }  
  }

        return 0;
}



超声波接收数据
/*!
*  @brief      URM04v2超声波传感器返回测量的距离或温度
*  @since      v1.0
*  @param  None
*  @return     测量距离  -1表示上次测量超出范围或不成功
*  @author     Z小旋
*/

int ReadDistance()
{
        u8 data[8];
    unsigned int temp;   
    int counter = 0;
    int result = -1;  
        int i = 0,j = 0;
        for(i=0;i<200;i++)   //数据缓存区最大为200 我们就循环200次
        {
        
            if(USART_RX_BUF==0x55&&USART_RX_BUF[i+1]==0xAA)  //检测到回复的字头
            {                                          
               
                    for(j=0; j<8; j++)
                    {
                            data[j] = USART_RX_BUF;      //获取返回数据
                            i++;
                    }
                                
                    if(data[3] == 2 && data[4] == 2)    //如果为距离   桢长度为2 命令字为2
                {
                           
               //  result = (((unsigned int)data[5])<<8))|data[6];   数据合并  如果需要测到255以上用这个
                result =  data[6];    //返回所测距离  最大255
                    }
                    if(data[3] == 2 && data[4] == 3)     //如果为温度    桢长度为2 命令字为3
                    {
                            if(data[5]>=0xf0)   //高四位都为1 温度为正
                            {
                    // result= ((data[5]-0xf0)*256-data[6])/10;                 //返回所测温度
                                    result= ((unsigned int)(data[5]-0xf0)+data[6])/10;  //返回所测温度  
                            }
                            else   温度为负
                            {
                                      //result= ((data[5])*256-data[6])/10;                 //返回所测温度
                      result= ((unsigned int)(data[5]<<4))|data[6];  //返回所测温度
                            }
                    }
                    USART_RX_STA=0;
                    return result;
            }
            else
            {
                    delay_us(250);
                    counter++;
                    if(counter==200) //如果50ms还没有数据返回,退出测量并返回-1
                    {
                            return result;
                    }
            }        
    }
}



这里只接收低八位,保证最大能到2.55米 ,如果需要测得远用注释的那行就行,还有很多事,本来想写一套完整库,但是没很多时间,就到这里吧,没有心情去继续完善这个了,万分抱歉,很您可以参考一下,希望能有一点用 ,不足的就是接收数据,需要修改UATR的接收中断的数据处理,我改的不满意,就不上传了

您可以自行修改,还有要注意检测不到数据需要及时退出,不要死等,单片机里最好不要有可能是死循环的存在
void distance()
{        
  int Distance=0;
  MeasureDistance(0x11);
  Distance = ReadDistance();
  delay_ms(1000);
}



收藏 评论0 发布时间:2022-3-25 13:34

举报

0个回答

所属标签

相似技术帖

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版