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超声波测距模块使用
下一篇:STM32f407驱动hc-sr04超声波测距模块
推荐帖子
- 电路板上用fill和铺铜是一样吗?
- 没用过fill,高手指点下,用fill和铺铜是一样吗?以前听说如果对电源铺铜会造成板子短路,用信号会不会呢?用fill就安全吗?电路板上用fill和铺铜是一样吗?没人知道吗?顶一下回复:电路板上用fill和铺铜是一样吗?恩,你先解释一下什么叫铺铜?回复:电路板上用fill和铺铜是一样吗?铺铜连接某一网络,且按设置的距离自动避开其它网络.fill却填到哪里连接哪里.回复:电路板上用fill和铺铜是一样吗?可以用fill来覆铜的。但使用时要注意网络属性的设定。回复:电路板上用fil
- cyp1982 PCB设计
- 智能车载座椅加热器——作品提交
- 智能车载座椅加热器作者:蓝色天使 作品简介 智能车载座椅加热器: 1为蓝牙模块负责采集数据向手机端发送。 2NTC温度传感器负责对座椅温度的感知。 3STM32Demo板负责采集温度传感器的数据并转化为温度,将实时温度通过串口经过蓝牙模块上传至手机APP,同时根据温度值控制座椅加热。 4座椅加热状态指示,为了更好展现加热过程控制速度。用LED灯来指示方便观察效果。 产品功能:北方冬天室外停车,早上座椅方向盘特别冷,为了提升用户驾驶体验,该系统就
- 蓝色天使 DigiKey得捷技术专区
- 想做毕业设计求助。。
- 小妹是本科大四学生,要做个毕业设计,想做zigbee的,但是不知道能做什么东西,希望能有人给点意见呀!~谢谢各位。想做毕业设计求助。。哇,女生也上论坛?可惜帮不了你啊!论坛里有zigbee专区,可以去看看,找找灵感回复楼主skatingjuno的帖子QQ:1194744946可以联系我,交流交流有看啊,好多不懂啊,感觉完全外行啊。。。回复板凳soso的帖子嗯,毕设需要啊回复沙发lcofjp的帖子https://bbs.eeworld.com.cn/forum
- skatingjuno RF/无线
- 【micropython】ESP8266更新了APA102的教程
- MicroPython官方文档中更新了对APA102的教程。APA102和WS2812类似,也是一种多级彩灯控制,但是APA102使用2个信号线,有更高的信号速率,视觉效果更好。【micropython】ESP8266更新了APA102的教程老哥真有时间啊,可以时刻关注新东西你是光看不做:lol
- dcexpert MicroPython开源版块
- STM32掉电擦除
- 在什么地方能更改设置STM32掉电瞬间的峰值电压过高使其擦出内部flash我在关掉电源后发现内部flash的内容自动全部被擦除了开始我以为是自己的程序在RAM中运行的但是我特别的验证了一次我用三个板子做实验其中一个是在电源不稳定时候关电的内嵌flash全部被擦除剩下两个板子在一个比较稳定的电源供电时我拔掉电结果内嵌flash没有影响这样的现象在哪里可以更改或者设置?STM32掉电擦除
- duzhiming stm32/stm8
- L4990
- 电源管理器件PowerManagementL4990
- lorant 嵌入式系统
设计资源 培训 开发板 精华推荐
- 基于PD85050S的RF电源模块,用于移动无线电应用
- AD8604DRUZ-REEL 高端运算放大器电流监视器的典型应用
- NCP301LSN25T1 2.5V 窗口电压检测器的典型应用
- 【实物已做】极简清爽USB HUB集线器_基于SL2.1A
- AM1/4S-1209SH30Z 9V 0.25 瓦 DC-DC 转换器的典型应用
- 使用 Analog Devices 的 LTC2621CDD-1 的参考设计
- LT3758EMSE 演示板,SEPIC,输入电压:18V 至 72V,输出电压:24V/1A,(3x3 QFN)
- ADP7104RDZ-REDYKIT、ADP7104RD-EVALZ SOIC RedyKits 适用于 ADP7104 1.5V 低压差 (LDO) 线性稳压器
- 使用 ROHM Semiconductor 的 BA15BC0FP-E2 的参考设计
- LT4276CIUFD 38.7W LTPoE++ 电源在具有 5V、7A 输出的反激模式下的典型应用电路