STM32F103驱动HCSR04超声波测距显示
超声波模块在电子DIY作品中实现小车避障测距等方面均应用广泛,在大学生智能车DIY爱好者中尤为显眼。
HC-SR04超声波测距模块可提供2cm-400cm的非接触式距离感测功能,测距精度可达3mm,包括发射器、接收器与控制电路,它是一种压电式传感器,利用电致伸缩现象而制成。
| 电气参数 | HCSR04超声波模块 |
|---|---|
| 工作电压 | DC5V |
| 工作电流 | 15mA |
| 工作频率 | 40KHz |
| 最远射程 | 4M |
| 最近射程 | 2cm |
| 测量角度 | 15° |
| 输入触发信号 | 10us的TTL脉冲 |
| 输出回响信号 | 输出TTL电平信号,与射程成比例 |
首先我们可以看下面的一张超声波的时序图:

图中我们可以大致看出,要使用HCSR04这个超声波模组,我们必须先给超声波发送一个触发信号,引导超声波内部循环发出8个40Khz的脉冲然后输出回响信号引脚上拉为高电平,然后我们利用超声波回响信号引脚的高电平所得计数时间经过相关运算就可以得到对应的距离,具体公式如下:
测试距离 = (高电平时间声速(340M/S)/2)= ((float)t/58.0)
这个公式的具体换算过程,大家可以用以前学过的知识进行还算下,最后得到的距离单位是厘米。
下面放一张超声波的引脚功能示意图,能更好的理解HCSR04的具体使用和接线在代码中:

之前写过用51单片机驱动HCSR04在LCD1602上的驱动代码,这篇文章我使用STM32驱动HCSR04在0.96OLED(使用人数较多并且开源初始化代码方便移植)上面使用的驱动代码。
时钟和GPIO以及中断相关配置:
void HCSR04_Init(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; //定义定时器结构体
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
//IO 初始化
GPIO_InitStructure.GPIO_Pin = HCSR04_TRIG; //发送高点平引脚
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
GPIO_Init(HCSR04_PORT, &GPIO_InitStructure);
GPIO_ResetBits(HCSR04_PORT,HCSR04_TRIG);
GPIO_InitStructure.GPIO_Pin = HCSR04_ECHO; //返回电平引脚
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;
GPIO_Init(HCSR04_PORT, &GPIO_InitStructure);
GPIO_ResetBits(HCSR04_PORT,HCSR04_ECHO);
//定时器初始化使用基本定时器3
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //打开TIM3定时器时钟
TIM_DeInit(TIM3);
TIM_TimeBaseStructure.TIM_Period = 65535; //(1000-1); //设置在下一个更新时间装入活动的自动重装载寄存器周期的值 计数到1000为1ms
TIM_TimeBaseStructure.TIM_Prescaler =(72-1); //设置用来作为TIMx时钟频率除数的预分频 1M的计时频率 1US计数
TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1; //不分频
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //向上计数模式
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位
TIM_ClearFlag(TIM3, TIM_FLAG_Update); //清除更新中断避免立即产生更新中断
TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE); //启用计时器更新中断
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn; //设置中断服务
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //主优先级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //次优先级
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //启用中断
NVIC_Init(&NVIC_InitStructure);
TIM_Cmd(TIM3,DISABLE);
}
//定时器中断服务程序
void TIM3_IRQHandler(void) //TIM3中斷
{
if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET) //检查TIM更新中断是否发生
{
TIM_ClearITPendingBit(TIM3, TIM_IT_Update); //清除TIM更新中断标志位
msHcCount++;
}
}
下面展示写根据超声波时序图可以写出下面的驱动代码:
//开始计数
static void StartTimer() //打开定时器
{
TIM_SetCounter(TIM3,0); //清除计数
msHcCount = 0;
TIM_Cmd(TIM3, ENABLE); //启用TIM3外设
}
static void StopTimer() //关闭定时器外设
{
TIM_Cmd(TIM3, DISABLE); //关闭TIM定时器外设
}
//获取计时器时间
float GetEchoTimer(void)
{
u32 t = 0;
t = msHcCount*1000; //得到ms
t += TIM_GetCounter(TIM3); //得到us
TIM3->CNT = 0; //将TIM3定时计数器的寄存器清零
delay_ms(50);
return t;
}
//取五次数据平均值,为了使测距所得到的值更加精确可采取多次测距的平均值来使用应用中
float HCSR04GetLength(void)
{
u32 t = 0;
int i = 0;
float lengthTemp = 0;
float sum = 0;
float distance;
for(i=0;i<5;i++){
TRIG_SEND = 1; //发送高电平输出
delay_us(20);
TRIG_SEND = 0;
while(ECHO_RECEIVE == 0); //等待接收高电平输出
StartTimer(); //打开计时器
while(ECHO_RECEIVE == 1);
StopTimer(); //关闭计时器
t = GetEchoTimer(); //获取时间,解析度为1US
lengthTemp = ((float)t/58.2); //cm
sum = lengthTemp + sum ;
}
distance = 100*sum/5.0;
return distance;
}
本次使用OLED屏幕显示超声波所测距离并显示如下图所示:

文章中使用的显示方式为0.96寸OLED模块显示,驱动MCU使用的为STM32F103C8T6,在使用HCSR04的过程中也可以自己根据HCSR04的驱动代码所得到的距离值去做其他的接口应用,例如做小车,或者其他测距案例均可移植使用,需要完整工程的可下方留言邮箱获取。
按照目前的情况,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visitthehelpcenter指导。关闭10年前。问题1)我想知道rubyonrails是否有功能类似于primefaces的gem。我问的原因是如果您使用primefaces(http://www.primefaces.org/showcase-labs/ui/home.jsf),开发人员无需担心javascript或jquery的东西。据我所知,JSF是一个规范,基于规范的各种可用实现,prim
本教程将在Unity3D中混合Optitrack与数据手套的数据流,在人体运动的基础上,添加双手手指部分的运动。双手手背的角度仍由Optitrack提供,数据手套提供双手手指的角度。 01 客户端软件分别安装MotiveBody与MotionVenus并校准人体与数据手套。MotiveBodyMotionVenus数据手套使用、校准流程参照:https://gitee.com/foheart_1/foheart-h1-data-summary.git02 数据转发打开MotiveBody软件的Streaming,开始向Unity3D广播数据;MotionVenus中设置->选项选择Unit
文章目录1.开发板选择*用到的资源2.串口通信(个人理解)3.代码分析(注释比较详细)1.主函数2.串口1配置3.串口2配置以及中断函数4.注意问题5.源码链接1.开发板选择我用的是STM32F103RCT6的板子,不过代码大概在F103系列的板子上都可以运行,我试过在野火103的霸道板上也可以,主要看一下串口对应的引脚一不一样就行了,不一样的就更改一下。*用到的资源keil5软件这里用到了两个串口资源,采集数据一个,串口通信一个,板子对应引脚如下:串口1,TX:PA9,RX:PA10串口2,TX:PA2,RX:PA32.串口通信(个人理解)我就从串口采集传感器数据这个过程说一下我自己的理解,
LL库和HAL库简介LL:Low-Layer,底层库HAL:HardwareAbstractionLayer,硬件抽象层库LL库和hal库对比,很精简,这实际上是一个精简的库。LL库的配置选择如下:在STM32CUBEMX中,点击菜单的“ProjectManager”–>“AdvancedSettings”,在下面的界面中选择“AdvancedSettings”,然后在每个模块后面选择使用的库总结:1、如果使用的MCU是小容量的,那么STM32CubeLL将是最佳选择;2、如果结合可移植性和优化,使用STM32CubeHAL并使用特定的优化实现替换一些调用,可保持最大的可移植性。另外HAL和L
我使用的是最新版本的Chrome(32.0.1700.107)和Chrome驱动程序(V2.8)。但是当我在Ruby中使用以下代码运行示例测试时:require'selenium-webdriver'WAIT=Selenium::WebDriver::Wait.new(timeout:100)$driver=Selenium::WebDriver.for:chrome$driver.manage.window.maximize$driver.navigate.to'https://www.google.co.in'defapps_hoverele_hover=$driver.find_
按照目前的情况,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visitthehelpcenter指导。关闭9年前。多年来,我一直在使用多种语言进行编程,并且认为自己总体上相当擅长。但是,我从未编写过任何自动化测试:没有单元测试,没有TDD,没有BDD,什么都没有。我已经尝试开始为我的项目编写适当的测试套件。我可以看到在进行任何更改后能够自动测试项目中所有代码的理论值(value)。我可以看到像RSpec和Mocha这样的测试框架应该如何使设置和运行所述测试变得相当容易
如果我在功能规范中调用url_for,它会返回一个以http://www.example.com/开头的绝对URL.Capybara会很乐意尝试加载该站点上的页面,但这与我的应用程序无关。以下是重现该问题的最少步骤:从这个Gemfile开始:source'https://rubygems.org'gem"sqlite3"gem"jquery-rails"gem"draper"gem"rails",'4.1.0'gem"therubyracer"gem"uglifier"gem"rspec-rails"gem"capybara"gem"poltergeist"gem"launchy"运行
在笔者前面有一篇文章《驱动开发:断链隐藏驱动程序自身》通过摘除驱动的链表实现了断链隐藏自身的目的,但此方法恢复时会触发PG会蓝屏,偶然间在网上找到了一个作者介绍的一种方法,觉得有必要详细分析一下他是如何实现的进程隐藏的,总体来说作者的思路是最终寻找到MiProcessLoaderEntry的入口地址,该函数的作用是将驱动信息加入链表和移除链表,运用这个函数即可动态处理驱动的添加和移除问题。MiProcessLoaderEntry(pDriverObject->DriverSection,1)添加MiProcessLoaderEntry(pDriverObject->DriverSection,
我有一个适用于事件/监听器模型的应用程序。发布了几种不同类型的数据(事件),然后许多不同的事情可能需要也可能不需要对该数据(监听器)采取行动。监听器的发生没有特定的顺序,每个监听器将决定是否需要对事件采取行动。Rails应用程序有哪些工具可以完成此任务?我希望自己不必这样做(尽管我可以。这没什么大不了的。)编辑:观察者模式可能是更好的选择 最佳答案 查看EventMachine.它是一个非常流行的Ruby事件处理库。它看起来相当不错,而且很多其他库似乎都在利用它(Cramp)。这是一个很好的介绍:http://rubylearnin
本文代码使用HAL库。文章目录前言一、MCP4017的重要特性二、MCP4017计算RBW阻值三、MCP4017地址四、MCP4017读写函数五、CubeMX创建工程(利用ADC测量MCP4017电压)、对应代码:总结前言一、MCP4017的重要特性蓝桥杯板子上的是MCP4017T-104ELT,如图1。MCP4017是一个可编程电阻,通过写入的数值可以改变电阻的大小。重点在于6引脚(W),5引脚(B