基于STM32的超声波HC-SR04详解

最新更新时间:2021-10-14来源: eefocus关键字:STM32  超声波  HC-SR04 手机看文章 扫描二维码
随时随地手机看文章

HC-SR04基本工作原理:

(1)采用IO口TRIG触发测距,给最少10us的高电平信呈。

(2)模块自动发送8个40khz的方波,自动检测是否有信号返回;

(3)有信号返回, 通过IO口ECHO输出一个高电平, 高电平持续的时间就是超声波从发射到返回的时间。


测试距离=(高电平时间*声速(340M/S))/2。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

程序编写思路是:

1、配置好使用到的GPIO以及定时器;

2、给模块TRIG端口发送大于10us的高电平信号,当收、收到ECHO回响信号是,打开定时器开始定时;

3、当回响信号消失,关闭定时器;

4、通过定时器定时时间来确定距离。


连线

1.这里,HC-SR04模块必须使用5V供电,不能是3.3V (若接3.3V,则数据出错)

2.Trig引脚我这里接GPIOB6

3.Echo引脚我这里接GPIOB7


相关代码

main.c

#include "led.h"

#include "delay.h"

#include "key.h"

#include "sys.h"

#include "usart.h"

#include "timer.h"


float Distance_Calculate(u32 count)

{

//单位cm

//v = 340m/s = 34000cm/s = 34000cm/10^6us = 0.034cm/us

//s = vt/2 = t*0.034/2 = t*0.017 ≈ t/58

    float Distance = 0;

    Distance = ((float)count / 58));

    return Distance;


}


int main(void)

{

u32 count = 0;

float Distance = 0;

delay_init();     //延时函数初始化   

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级

uart_init(115200); //串口初始化为115200

LED_Init();      //LED端口初始化

Ultrasonic_Config(); //引脚初始化

Timer2_Config(); //定时器2初始化

GPIO_SetBits(GPIOB,GPIO_Pin_5); //一开始我给它亮

LED0 = 0; //小灯指示用途

LED1 = 0;

printf("Test startn");

while(1)

{

//拉高Trig引脚10us

GPIO_ResetBits(GPIOB, GPIO_Pin_6);//预先拉低Trig引脚

GPIO_SetBits(GPIOB, GPIO_Pin_6);

delay_us(10);

GPIO_ResetBits(GPIOB, GPIO_Pin_6);//发出10us的脉冲

TIM2->CNT = 0; //计数器的值为0

while(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_7) == 0); //等待高电平

TIM_Cmd(TIM2, ENABLE); //开启定时器

while(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_7) == 1){} //等待低电平

TIM_Cmd(TIM2, DISABLE); //关闭定时器

count = TIM2->CNT; //获取定时器的值

printf("count = %drn",count);

//count是计数器,单位是us,可根据上图转换一下即可。

Distance = Distance_Calculate(count); //计算距离

printf("Distance = %f.", Distance);

delay_ms(500);

LED0 = !LED0;

LED1 = !LED1;

}  

}  


命名问题,不需要配置led


led.h

#ifndef __LED_H

#define __LED_H  

#include "sys.h"


void Timer2_Config(void);

void Ultrasonic_Config(void);


led.c

void Ultrasonic_Config(void){

GPIO_InitTypeDef GPIO_InitStructure;

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6; //Trig

//GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //复用推挽输出

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_Init(GPIOB,&GPIO_InitStructure);


GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7; //ECHO,输入

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;

//GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; //设为输入

GPIO_Init(GPIOB,&GPIO_InitStructure);

}

void Timer2_Config(void){

TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;

RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);

TIM_TimeBaseInitStructure.TIM_Prescaler = 71;

TIM_TimeBaseInitStructure.TIM_Period = 49999; //72*50000/72 = 50000us = 500ms.

TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;

TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;

TIM_TimeBaseInit(TIM2,&TIM_TimeBaseInitStructure);

TIM_ClearFlag(TIM2,TIM_FLAG_Update); //更新产生中断

}


usart.c

void uart_init(u32 bound){

  //GPIO端口设置

GPIO_InitTypeDef GPIO_InitStructure;

USART_InitTypeDef USART_InitStructure;

NVIC_InitTypeDef NVIC_InitStructure;

RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA, ENABLE); //使能USART1,GPIOA时钟

//USART1_TX   GPIOA.9

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PA.9

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出

GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.9

//USART1_RX   GPIOA.10初始化

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;//PA10

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入

GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.10  

//Usart1 NVIC 配置

NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3 ;//抢占优先级3

NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //子优先级3

NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能

NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化VIC寄存器

//USART 初始化设置

USART_InitStructure.USART_BaudRate = bound;//串口波特率

USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长为8位数据格式

USART_InitStructure.USART_StopBits = USART_StopBits_1;//一个停止位

USART_InitStructure.USART_Parity = USART_Parity_No;//无奇偶校验位

USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//无硬件数据流控制

USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //收发模式

USART_Init(USART1, &USART_InitStructure); //初始化串口1

USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//开启串口接受中断

USART_Cmd(USART1, ENABLE);                    //使能串口1 

}


实验结果

在这里插入图片描述

说明:count是计数器

v = 340m/s,v = 0.034cm/us.

t = s/v = 400cm/0.034cm/us = 11764us

而我设置计数50000次,也就是50000us,因此,是能够测量最大距离的。

关键字:STM32  超声波  HC-SR04 编辑:什么鱼 引用地址:http://news.eeworld.com.cn/mcu/ic547677.html

上一篇:基于stm32的HC-SR04超声波测距模块使用
下一篇:STM32f407驱动hc-sr04超声波测距模块

推荐阅读

STM32外设之GPIO
一、GPIO是什么?全称:General-purpose input/output(通用型输入输出)操作要点:1. 使能 GPIO 端口时钟。2. 初始化 GPIO 目标引脚为推挽输出模式。3. 编写简单测试程序,控制 GPIO 引脚输出高、低电平。二、使用步骤1.GPIO功能与模式1.输入浮空 :输入模式施密特触发器打开及GPIO端口内部上下拉开关打开, 并且状态不确定。2.输入上拉:输入模式施密特触发器打开及GPIO端口内部上拉开关关闭,默认为高电平。3.输入下拉 :输入模式施密特触发器打开及GPIO端口内部下拉开关关闭,默认为低电平。4.模拟输入 : 模拟输入施密特触发器关闭─,输入数据寄存器禁止,实现模拟信号采集。5.开漏输
发表于 2022-09-27
<font color='red'>STM32</font>外设之GPIO
STM32外设之ADC
一、ADC是什么?ADC,Analog-to-Digital Converter的缩写,指模/数转换器或者模拟/数字转换器。是指将连续变量的模拟信号转换为离散的数字信号的器件。那么就有人要问了,什么是模拟信号,什么是数字信号。模拟信号:指的是连续变化的物理量,如温度,压力,湿度。而数字信号可以简单的理解为0和1两种状态。12位ADC是一种逐次逼近型模拟数字转换器。它有多达18个通道,可测量16个外部和2个内部 信号源。各通道的A/D转换可以单次、连续、扫描或间断模式执行。ADC的结果可以左对齐或右 对齐方式存储在16位数据寄存器中二、ADC的基本使用1.ADC的主要特征●12位分辨率 //0-4095● 转换结束、注入转换结束和发
发表于 2022-09-27
<font color='red'>STM32</font>外设之ADC
STM32外设之USART
前言本章进行初识STM32F103串口,讲解通信方式,主要了解串口相应寄存器,串口的库函数编程方法,串口结构体的初始化。一、USART是什么?USART:(Universal Synchronous/Asynchronous Receiver/Transmitter)首先来认识英文全拼对我们理解颇有裨益。翻译为通用同步/异步串行接收/发送器。区别于USART的有一个UART裁剪掉了同步,同步通信和异步通信指的是设备是否可以同步发送与接收,常见的同步通信有SPI RS232,通常同步通信伴有时钟线CLK,而异步通信不可以同步收发,通常由两根线组成。二、使用步骤1.功能框图1.功能引脚TX:发送引脚。RX:接收引脚。 (一般互相通信时T
发表于 2022-09-27
<font color='red'>STM32</font>外设之USART
stm32相关位操作
stm32 >>,<<,l=与&=~操作0x0000 0001 >>4//右移四位=0x0000 10000x0000 1000<<4//左移四位=0x0000 0001l=操作0xxxx xxxx l= 0x0000 0001=0xxxxx xxx1 //保留数据置1的位&=~操作0xxxxx xxxx &=~ 0x000 0001=0xxxxx xxxx &=01111 1110 //先取反再相与=0xxxxx xxx0 //使原来置1的位置0,也就是取反
发表于 2022-09-27
STM32GPIO的八种输入输出模式
上拉电阻:把不确定的信号通过电阻连接到高电平,电信号初始化为高电平。下拉电阻:把不确定的信号通过电阻连接到低电平,电信号初始化为低电平。输入1.上拉输入:输入信号通过上拉电阻被初始化为高电平,再通过TTL施密特触发器从模拟信号9V、3.3V、1.9V转为数字信号0、1后存入输入寄存器中。2.下拉输入:同上拉输入一样,区别只在通过下拉电阻初始化为低电平。3.浮空输入:即信号输入既不连接上拉也不连接下拉,输入信号电压值不确定,通过TTL施密特触发器从模拟信号9V、3.3V、1.9V转为数字信号0、1后存入输入寄存器中。通常用于IIC、串口USART中。4.模拟输入:不通过上下拉电阻,也不通过TTL施密特触发器,直接与单片机片上外设的模拟
发表于 2022-09-27
STM32串口USART配置、发送与接收
一、配置时钟:GPIO时钟、串口时钟、复用引脚时钟二、配置GPIO结构体三、配置串口结构体//串口初始化示例void usart_init(void){ //创建结构体 GPIO_InitTypeDef gpioinitStructure; USART_InitTypeDef usartinitStructure; NVIC_InitTypeDef NVICinitStructure; NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1); //设置时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE );RCC_APB2
发表于 2022-09-27
<font color='red'>STM32</font>串口USART配置、发送与接收

推荐帖子

艾睿电子携手ADI与您探讨:无需光耦的flyback隔离电源设计
点击报名>>>直播时间:2020年10月20日(周二)上午10:00-11:30 直播主题:无需光耦的flyback隔离电源设计 直播介绍: 介绍与传统Flyback构架不同的无需光耦的隔离电源技术,很好的输出稳定性,高效率,极简系统设计。演讲嘉宾:杜发春(FrankDU) 电源产品应用系统工程师 2018-至今担任ADI电源产品应用系统工程师,主要负责ADI电源的推广,解决客户应用问题。 2012-2018在TI工作6年,从事电源FAE的工作,主要负
dancerzj 电源技术
LM3150输出电压3.8V
原理图是这样的。 输入电压为24V,LM3150输出电压设计为10V。 空载,上电后,LM3150电压输出由10V降到3.8V左右,不知道什么原因。 感觉LM3150好像进入某种状态。 \0\0\0eeworldpostqqLM3150输出电压3.8V
xiaochen 模拟与混合信号
知道timestool的请进(一个实时调度模拟与分析工具)!!!
请教了解瑞典的乌普萨拉(Uppsala)大学开发的times的大侠,还有什么工具与times的功能差不多??? 小弟在此先谢过了!知道timestool的请进(一个实时调度模拟与分析工具)!!!
冬冬瓜 嵌入式系统
TI C6678多核DSP的架构
TMS320C6678是KeyStone架构的8核DSP处理器,每个CorePac核的频率最高为1.25GHz,提供强大的定点和浮点运算能力,同时芯片内部集成了MulticoreNavigator、RapidIO、千兆以太网和EDMA等外设,由于芯片处理能力强,外设功能丰富,而且片内集成了大量的硬件加速器,例如PacketAccelerator、MulticoreNavigator等,可以广泛地应用在通信、雷达、声纳、火控、电子对抗等领域。从目前的情况看,由于C6678的以上优异的特性,
fish001 DSP 与 ARM 处理器
【转】 我没有基础 能学电子吗
我听到过很多人,向我咨询这个问题:“我没有基础,能学电子吗?”。 我告你“能学”,你是否相信? 我前几年说的一句话很有道理:任何一个行业,最牛逼的人都是基础最好的人。这句话我和很多人讲过,不知道他们有没有完全理解。不过,你越活就会越觉的有道理的。结合你的行业,和你知道的行业,想想看是不是?例子就不给你举了。 如果你理解上一段写的那句话,你现在就应该明白了,学电子,其实就是学电子基础。从开始接触,到成为高手,整个过程,都是在学基础,技巧是在学基础的过程中总结出来然后为基础服务的。大家肯定听到
dontium 模拟电子
问一下WINCE下的BOOTLOADER和LINUX下的BOOTLOADER是一样的吗?
如题目问一下WINCE下的BOOTLOADER和LINUX下的BOOTLOADER是一样的吗?
heima3041 Linux与安卓
小广播
设计资源 培训 开发板 精华推荐

何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2022 EEWORLD.com.cn, Inc. All rights reserved