HC-SR04(超声波)应急使用方案

一、设计描述

核心硬件

主控单元:采用STM32F103C8T6单片机,凭借其强大的处理能力和丰富的外设接口,为系统提供了坚实的硬件基础。

软件平台

开发工具:利用STM32CUBEMX + Keil5这一直观易用的集成开发环境,极大地提升了软件编程与调试的效率,确保了系统软件的稳定可靠。

系统应用场景

此方案适合短期内要求实现利用超声波避障,对测距精度要求不高的情况。

二、硬件连接

HC-SR04

|------|-----|
| VCC | 5V |
| Trig | PB0 |
| Echo | PB1 |
| Gnd | GND |
[HC-SR04连线表格]

STM32F103C8T6

|-----|------|------|
| PB0 | Trig | 触发信号 |
| PB1 | Echo | 回响信号 |
[STM32F103C8T6连线表格]

三、STM32CUBEMX配置

了解工作原理

由图表可知,我们只需要处理触发信号和回响信号即可。

STM32CUBEMX配置

四、软件编写

1. 初始化HC-SR04

初始化原理就是保持触发信号低电平

void HC_SR04_Init(void)
{
	HAL_GPIO_WritePin(TRIG_GPIOX, TRIG_GPIO_PIN_X, GPIO_PIN_RESET); 
}

2. 等待回响信号

如果直接while() 将可能进入死循环,所以加上总体计数来做预防

while(HAL_GPIO_ReadPin(ECHO_GPIOX,ECHO_GPIO_PIN_X) == GPIO_PIN_RESET){
	all_time++;
    if(all_time >= MaxCnt) return false;
}

3. 计算回响数据高电平

while(HAL_GPIO_ReadPin(ECHO_GPIOX,ECHO_GPIO_PIN_X) == GPIO_PIN_SET){
	cnt++;
	all_time++;
	if(all_time >= MaxCnt) return false;
}

4. 综合获取计数

bool HcSr04_Echo(int *time_cnt)	// ????????
{
		int cnt = 0;
	  long int all_time = 0;
		while(HAL_GPIO_ReadPin(ECHO_GPIOX,ECHO_GPIO_PIN_X) == GPIO_PIN_RESET){
			all_time++;
			if(all_time >= MaxCnt) return false;
		}
		while(HAL_GPIO_ReadPin(ECHO_GPIOX,ECHO_GPIO_PIN_X) == GPIO_PIN_SET){
			cnt++;
			all_time++;
			if(all_time >= MaxCnt) return false;
		}
		*time_cnt = cnt;
		return true;
		
		//printf("%d\r\n",cnt);
}

5. 获取距离

此距离不准确,但通过计算差不多得出的距离distance以毫米(mm)为单位,足以应对5cm以上2m以下的避障处理。

bool Get_HcSr04_distance(float *distance, int *timecnt)	// ?????????(CM???)
{
	
	HC_SR04_Init();
	HcSr04_Trig();
	if(HcSr04_Echo(timecnt)){
		*distance = (*timecnt)/2.35;
		return true;
	}
	return false;
}

6. 串口重定义

//重写标准输出函数
int __io_putchar(int ch)
{
	HAL_UART_Transmit(&huart4, (uint8_t *)&ch, 1, 10);
	return ch;
}

五、总代码

hcsr04.h

#ifndef  __HCSR04_H
#define __HCSR04_H

#include "stdbool.h"

#include "usart.h"
		/*
		float distance = 0; int timecnt = 0;
		if(Get_HcSr04_distance(&distance,&timecnt) == true){
			printf(" distance = %f;  timecnt = %d\r\n",distance,timecnt);
		}
		*/
		
		
			//printf(" distance = %f;  timecnt = %d\r\n",distance,timecnt);
#define TRIG_delay 	1					// ·¢ËÍÐźÅʱ¼ä (ms)
#define MaxCnt			2000000		// ¼ÆÊý·¶Î§

#define TRIG_GPIOX									
#define ECHO_GPIOX						GPIOB		


#define TRIG_GPIO_PIN_X				GPIO_PIN_0	 
#define ECHO_GPIO_PIN_X				GPIO_PIN_1



void HC_SR04_Init(void);

bool HcSr04_Trig(void)		;

float Get_InitDistance(void);

bool HcSr04_Echo(int *time_cnt)	;

bool Get_HcSr04_distance(float *distance, int *timecnt)	;
#endif

hcsr04.c

#include "hcsr04.h" 
#include "gpio.h"
#include "tim.h"
#include "stdio.h"
#include "usart.h"
float init_distance = 0;
// int TF1C = 0;

void HC_SR04_Init(void)
{
	HAL_GPIO_WritePin(TRIG_GPIOX, TRIG_GPIO_PIN_X, GPIO_PIN_RESET);
	/*
	if(TF1C == 0){
		HAL_Delay(10);
		TF1C = 1;
		float distance = 0; int timecnt = 0;
		int cnt = 0;int i = 0;
		while(cnt == 0){
			init_distance = 0;
			for(i = 0;i<50;i++){
				if(Get_HcSr04_distance(&distance,&timecnt) == true && i >= 2){
						 cnt = cnt + 1;
							printf("initing -- >init_distance:%2f;distance:%2f;timecnt:%d;\r\n",init_distance,distance, timecnt);
						init_distance = init_distance + distance;
				}	
			}
		}
		if(cnt == 0) return;
		init_distance = init_distance / cnt;
		init_distance = init_distance / 2;
	}
	*/
	
}

float Get_InitDistance(void){
	return init_distance;
}

bool HcSr04_Trig(void)			// ?????????
{
	
		HAL_GPIO_WritePin(TRIG_GPIOX, TRIG_GPIO_PIN_X, GPIO_PIN_SET);
		HAL_Delay(TRIG_delay);		
		HAL_GPIO_WritePin(TRIG_GPIOX, TRIG_GPIO_PIN_X, GPIO_PIN_RESET);
		return true;
}


bool HcSr04_Echo(int *time_cnt)	// ????????
{
		int cnt = 0;
	  long int all_time = 0;
		while(HAL_GPIO_ReadPin(ECHO_GPIOX,ECHO_GPIO_PIN_X) == GPIO_PIN_RESET){
			all_time++;
			if(all_time >= MaxCnt) return false;
		}
		while(HAL_GPIO_ReadPin(ECHO_GPIOX,ECHO_GPIO_PIN_X) == GPIO_PIN_SET){
			cnt++;
			all_time++;
			if(all_time >= MaxCnt) return false;
		}
		*time_cnt = cnt;
		return true;
		
		//printf("%d\r\n",cnt);
}

bool Get_HcSr04_distance(float *distance, int *timecnt)	// ?????????(CM???)
{
	
	HC_SR04_Init();
	HcSr04_Trig();
	if(HcSr04_Echo(timecnt)){
		*distance = (*timecnt)/2.35;
		return true;
	}
	return false;
}

main.c

HC_SR04_Init();
float distance = 0; int timecnt = 0 ;
while(1){
	if(Get_HcSr04_distance(&distance,&timecnt) == true){
        printf("distance:%f;  timecnt:%d;\r\n",  distance, timecnt);
    }
}
相关推荐
ltwoxc2 小时前
01-51单片机LED与独立按键
单片机·嵌入式硬件·51单片机
忘尘8252 小时前
STM32小实验2
单片机·嵌入式硬件
DS小龙哥3 小时前
基于STM32设计的仓库环境监测与预警系统
stm32·单片机·嵌入式硬件
深圳市青牛科技实业有限公司 小芋圆8 小时前
GC8872 是一款带故障报告功能的刷式直流电机驱动芯片, 适用于打印机、电器、工业设备以及其他小型机器。
人工智能·科技·stm32·单片机·嵌入式硬件·机器人
可喜~可乐10 小时前
CAN总线入门指南:从原理到实践
c++·stm32·单片机·硬件工程
冰糖雪莲IO13 小时前
【江协STM32】9-4/5 USART串口数据包、串口收发HEX数据包&串口收发文本数据包
网络·stm32·嵌入式硬件
无聊到发博客的菜鸟13 小时前
STM32中的MCO
stm32·单片机·嵌入式硬件
Echo_cy_13 小时前
STM32 I2C通信外设
stm32·单片机·嵌入式硬件
半个番茄13 小时前
STM32 : PWM 基本结构
stm32·单片机·嵌入式硬件