HY-SRF05 五针超声波测距模块 在stm32f4上实现 附代码 个人经验
测距原理
HC-SRF05超声波测距模块可提供2cm-400cm的非接触式距离感测功能,测距精度可达高到3mm;模块包括超声波发射器、接收器与控制电路。像智能小车的测距以及转向,或是一些项目中,常常会用到。智能小车测距可以及时发现前方的障碍物,使智能小车可以及时转向,避开障碍物。
原理:
1.给超声波模块接入电源和地;
2.给脉冲触发引脚(trig)输入一个长为20us的高电平方波;
3.输入方波后,模块会自动发射8个40KHz的声波,与此同时回波引脚(echo)端的电平会由0变为1;(此时应该启动定时器计时);
4.当超声波返回被模块接收到时,回波引 脚端的电平会由1变为0;(此时应该停止定时器计数),定时器记下的这个时间即为超声波由发射到返回的总时长;
5.根据声音在空气中的速度为344米/秒,即可计算出所测的距离。
时序图表明你只需要提供一个10us以上脉冲信号,该模块内部将发出8个40kHz周期电平并检测回波。一旦检测到有回波信号则输出回响信号。回响信号的脉冲宽度与所测的距离成正比。由此通过发射信号到收到的回响信号时间间隔可以计算得到距离。
个人经验
上面的理论大可不必了解,这个东西无非就是通过声波测距,重点还是在代码上,搞了将近两周,踩了一些坑,和大家分享下:
1、5v的电压一定要接好,不然串口就会返回一个固定的值!
2、如果使用一般的延时来计时的话,配置好定时器就好了;但如果选择输入捕获来完成,注意配置时通道要对应好,否则串口会返回0或者很大的数。
3、如果使用不同定时器进行则分别配置,如使用同一个定时器的不同通道,则注意逻辑:不能接到上升/下降沿就关闭定时器,会相互影响。
4、注意定时器时32位还是16位,可能存在数据位数导致的错误。
代码
我使用的是stm32f4,两个定时器,两路超声波,如果需要一个定时器稍稍改一下逻辑即可:
初始化定时器:(正点原子例程也有):
TIM_ICInitTypeDef TIM3_ICInitStructure;GPIO_InitTypeDef GPIO_InitStructure;TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;NVIC_InitTypeDef NVIC_InitStructure;
//定时器3通道4,定时器9通道1输入捕获配置
void HC_Reci_TIM3_Init(u16 arr,u16 psc)
{GPIO_InitTypeDef GPIO_InitStructure;TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;NVIC_InitTypeDef NVIC_InitStructure;RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE); //TIM3时钟使能 RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE); //使能PORTB时钟 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;//PB1定时器3通道4GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;//复用功能GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; //速度100MHzGPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //推挽复用输出GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN; //下拉GPIO_Init(GPIOB,&GPIO_InitStructure); //初始化PB1GPIO_PinAFConfig(GPIOB,GPIO_PinSource1,GPIO_AF_TIM3); //PB1复用位定时器3TIM_TimeBaseStructure.TIM_Prescaler=psc; //定时器分频TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up; //向上计数模式TIM_TimeBaseStructure.TIM_Period=arr; //自动重装载值TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1; TIM_TimeBaseInit(TIM3,&TIM_TimeBaseStructure);//初始化TIM3通道4输入捕获参数TIM3_ICInitStructure.TIM_Channel = TIM_Channel_4; //CC1S=01 选择输入端 IC4映射到TI4上TIM3_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising; //上升沿捕获TIM3_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; //映射到TI1上TIM3_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1; //配置输入分频,不分频 TIM3_ICInitStructure.TIM_ICFilter = 0x00;//IC1F=0000 配置输入滤波器 不滤波TIM_ICInit(TIM3, &TIM3_ICInitStructure);//允许更新中断,触发方式中断TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE);TIM_ITConfig(TIM3,TIM_IT_Trigger,ENABLE);NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3;//抢占优先级3NVIC_InitStructure.NVIC_IRQChannelSubPriority =0; //子优先级0NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化VIC寄存器、TIM_ITConfig(TIM3,TIM_IT_Update|TIM_IT_CC4,ENABLE);//允许更新中断 ,允许CC1IE捕获中断 TIM_Cmd(TIM3,ENABLE ); //使能定时器3
}
输入捕获:
void TIM3_IRQHandler(void)//TIM3通道4
{if((HC_1.sta&0X80)==0)//还未成功捕获 {if(TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET)//溢出{ Send_sound(GPIOB,GPIO_Pin_0); if(HC_1.sta&0X40)//已经捕获到高电平了{if((HC_1.sta&0X3F)==0X3F)//高电平太长了{HC_1.sta|=0X80; //标记成功捕获了一次HC_1.val=0XFFFF;}else HC_1.sta++;} }if(TIM_GetITStatus(TIM3, TIM_IT_CC4) != RESET)//捕获1发生捕获事件{ if(HC_1.sta&0X40) //捕获到一个下降沿 { HC_1.sta|=0X80; //标记成功捕获到一次高电平脉宽HC_1.val=(u16)TIM_GetCapture4(TIM3);//获取当前的捕获值.HC_1.temp=HC_1.sta&0X3F; HC_1.temp*=0XFFFF; //溢出时间总和HC_1.temp+=HC_1.val; //得到总的高电平时间HC_1.Distance=HC_1.temp*172/10000;//cmHC_1.sta=0; //开启下一次捕获printf("HC1: %d\n",HC_1.Distance);TIM_OC4PolarityConfig(TIM3,TIM_ICPolarity_Rising); //CC1P=0 设置为上升沿捕获
// Send_sound(GPIOB,GPIO_Pin_0);}else //还未开始,第一次捕获上升沿{HC_1.sta=0; //清空HC_1.val=0;HC_1.sta|=0X40; //标记捕获到了上升沿TIM_Cmd(TIM3,DISABLE ); //关闭定时器3TIM_SetCounter(TIM3,0);TIM_OC4PolarityConfig(TIM3,TIM_ICPolarity_Falling); //CC1P=1 设置为下降沿捕获TIM_Cmd(TIM3,ENABLE ); //使能定时器3} } }TIM_ClearITPendingBit(TIM3, TIM_IT_CC4|TIM_IT_Update);
}
发送高电平:
void Send_sound(GPIO_TypeDef* GPIOx,uint16_t Pinx)
{GPIO_SetBits(GPIOx,Pinx);delay_us(20);GPIO_ResetBits(GPIOx,Pinx);
}
那么任务函数就很简洁了:
void sentry_ultrasonic ()
{HC_ult_send();HC_Reci_TIM3_Init(0XFFFF,84-1); //以1Mhz的频率计数 1us计数HC_Reci_TIM9_Init(0XFFFF,84-1);while(1){ task_delay_ms(50);}
}
以上代码已经经过串口验证无误,超声波测距正常。搞了快两周的测距模块终于差不多了,尽管踩坑无数。
萌新初来报道,多多包涵,大家凑合看哈。拜谢支持。
HY-SRF05 五针超声波测距模块 在stm32f4上实现 附代码 个人经验相关推荐
- STM32F103超声波HCSR04模块串口输出距离(附代码)
1. 接线 VCC-5V; GDN-GND; TRIG-PB6; ECOH-PB9 也可自行选择不冲突引脚 2. 代码部分 csb.c //.c文件 #include "delay.h&qu ...
- arduino UNO 与 超声波测距模块 实验详情
US-015 超声波测距模块 超声波传感器 US-020升级版 送全套资料 资料下载地址:http://pan.baidu.com/s/1c0AfkIG US-015超声波测距模块 1. 概述 US- ...
- STM32单片机基于HAL库开发HC-SR04 超声波测距模块(终极版)
参考: 某宝HC-SR04 超声波测距模块商品详情页 STM32L051C8T6 HAL库 输入捕获进行超声波测距 案例 STM32CubeMX学习笔记3--TIM2输入捕获(SR-04测距) cub ...
- STM32——超声波测距模块(HAL库CubeMx)
超声波测距 1. 超声波测距模块原理 2. CubeMx配置 3. 代码的编写 3.1 定时器计时的计算 3.2 接口函数 1. 超声波测距模块原理 (2021/11/28 16:25编辑) 超声波测 ...
- US-016超声波测距模块
1. 概述 US-016超声波测距模块可实现2cm~3m的非接触测距功能,供电电压为5V,工作电流为3.8mA,支持模拟电压输出,工作稳定可靠.本模块根据不同应用场景可设置成不同的量程(大测量距离分 ...
- 51单片机:HCSR04超声波测距模块及1602显示—C51程序(超详细)
测试完成于STC89C516单片机,晶振12MHZ.超声波模块Echo=P1^0.Trig=P1^1,1602液晶8位数据口=P0.E=P2^7.RS=P2^6.RW=P2^5.. 程序文件分为4部分 ...
- stm32控制超声波测距模块HC-SR04
引脚:PB15 TRIG,PB0 ECHO: 不同距离,LED对应不良.闪烁.亮状态,并通过串口发送到PC; TIM3定时中断,测出脉宽长度,没有像野火一样使用捕捉功能: 1.HS-SR04模块实物图 ...
- 【mcuclub】超声波测距模块HC-SR04
一.实物图 二.原理图 编号 名称 功能 1 VCC 电源正 2 TRIG 触发控制信号输入 3 ECHO 回响信号输出 4 GND 电源地 三.简介 由于超声波指向性强,能量消耗缓慢,在介质中传播的 ...
- STM32智能小车------超声波测距模块
文章目录 一.原理讲解 1.实物图 2.工作原理: 3.接线: 二.软件驱动代码 1.接口定义 2.驱动函数 总结 最终效果 大家好哇!我是小光,嵌入式爱好者,一个想要成为系统架构师的普通大学生. 进 ...
- 通过串口打印--超声波测距模块测得距离
通过串口打印--超声波测距模块测得距离 原理 超声波测距模块 串口传输 实战代码 原理 超声波测距模块 在这里首先需要了解超声波测距模块的原理.在我的这篇博客有很多介绍.超声波模块介绍 串口传输 串口 ...
最新文章
- python下载文件的11种方式_Python 中常见的几种下载文件方法
- 修复迁移后Net Standard项目中的错误
- mysql typeindex_explain mysql的type字段,索引的类型
- mac下查看redis安装路径_干货!win10环境下Redis安装、启动教程
- C# 编程规范 (coding standard)
- 【干货】腾讯人力资源与组织管理体系.pptx(附下载链接)
- 在Recyclerview使用GlideAPP加载大量图片导致内存溢出(oom)
- iOS开发那些事-iOS应用本地化-资源文件本地化
- 使用lex与yacc词法语法工具进行简单的SQL语义检查
- Android——获取实时的手机屏幕四个点经纬度(百度地图)
- ReadHub android版
- 使用python将excel单元格中指定文字加粗标红
- 饥荒服务器不显示管理员,饥荒联机版管理员怎么添加_饥荒联机版管理员介绍与添加方法详解_玩游戏网...
- 解读Seele元一子链协议 产业公链底层框架非常完美!
- Android ListView下拉刷新
- 路径中的'.'和'..'还有'./'和'../'都是什么意思
- IT风云15年的那些人、那些事(一)
- C#制作activeX控件
- 一文详解东数西算下绿色数据中心节能减排十大技术、智算中心八大趋势
- 计算机无法启动硬盘损坏,如果无法打开计算机硬盘分区该怎么办? chkdsk方法修复损坏的磁盘...
热门文章
- Peeking into the Future: Predicting Future Person Activities and Locations in Videos 翻译
- 论文阅读笔记--Predicting Human Eye Fixations via an LSTM-based Saliency Attentive Model
- 数据结构——数组以及n维数组
- AopAutoConfiguration matched的异常
- 瀑布模型(waterfall model)需求明确+严格顺序执行
- 曲婉婷-----没有什么不同
- 使用开源文档工具docsify,用写博客的姿势写文档
- 大文件异步分片上传到Seaweed服务器
- 从云到「链」,京东云成为中国第四朵云背后
- Ubuntu系统中如何删除一个用户