完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
URM04简介:
性能描述:
1触发超声波与温度测量指令 发送指令后,超声波开始测量,温度开始测量,无返回值 2延时30MS 超声波最大测距5米,反射路径10米,声速度331米/秒) 10/331=0.03021 //30MS3超声波测距读取指令 测量完一次之后,数据会被存储在ATmega8芯片中,只有发送读取指令,才会有数据返回 返回值: 测量成功返回16位距离数据,两字节0XFF表示测量失败 4温度读取指令: 与超声波只有命令字节不同 返回值: 调试经验: 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, 6 UATR接收数据的中断要改!!可以自己根据返回的数据特征做相应处理,或者接受8个字节直接退出 话不多说我们直接看代码: 超声波数据测量 /*! * @brief 超声波数据测量 * @since v1.0 * @param device 超声波地址 * @author Z小旋 */ void MeasureDistance(u8 device) { int i = 0; u8 Scmd[6]={0x55,0xaa,0x00,0x00,0x01,0x00}; //触发超声波与温度测量指令 u8 Tcmd[6]={0x55,0xaa,0x00,0x00,0x02,0x00}; //超声波测距读取指令 //SUM效验和 Scmd[2] = device; Tcmd[2] = device; Scmd[5] = Scmd[0]+Scmd[1]+Scmd[2]+Scmd[3]+Scmd[4]; //SUM校验和 Tcmd[5] = Tcmd[0]+Tcmd[1]+Tcmd[2]+Tcmd[3]+Tcmd[4]; //SUM校验和 // 触发距离测量。 for(i=0; i<6; i++) { USART_SendData(USART1, Scmd); while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET);//等待发送结束 } delay_ms(30); //延时30ms // 发送命令读取测量距离 for(i=0; i<6; i++) { USART_SendData(USART1, Tcmd); while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET);//等待发送结束 } delay_ms(3); } 发送温度就是将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); } 直接调用即可。 |
|
|
|
只有小组成员才能发言,加入小组>>
3314 浏览 9 评论
2995 浏览 16 评论
3494 浏览 1 评论
9059 浏览 16 评论
4088 浏览 18 评论
1180浏览 3评论
605浏览 2评论
const uint16_t Tab[10]={0}; const uint16_t *p; p = Tab;//报错是怎么回事?
599浏览 2评论
用NUC131单片机UART3作为打印口,但printf没有输出东西是什么原因?
2335浏览 2评论
NUC980DK61YC启动随机性出现Err-DDR是为什么?
1896浏览 2评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-23 17:15 , Processed in 0.938416 second(s), Total 46, Slave 38 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号