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);
    }
}
相关推荐
江山如画,佳人北望3 小时前
stm32-c8t6实现语音识别(LD3320)
stm32·单片机·嵌入式硬件
baowxz3 小时前
航芯MCU使用IAR+Jlink调试
单片机·嵌入式硬件
wangxinwei20003 小时前
stm32_LAN8720驱动
stm32·单片机·嵌入式硬件
大叔带刺3 小时前
AUTOSAR实战教程--DoIP_01_配置项解释
单片机·嵌入式硬件
小胖同学~3 小时前
Linux--vsFTP配置篇
stm32·单片机·嵌入式硬件
小智学长 | 嵌入式4 小时前
SOC-ESP32S3部分:36-适配自己的板卡
单片机·物联网·esp32
Neil今天也要学习7 小时前
永磁同步电机参数辨识算法--IPMSM拓展卡尔曼滤波全参数辨识
单片机·嵌入式硬件·算法
知识噬元兽10 小时前
【工具使用】STM32CubeMX-FreeRTOS操作系统-信号标志、互斥锁、信号量篇
stm32·单片机·嵌入式硬件
Flag- L11 小时前
STM32标准库-TIM定时器
stm32·单片机·嵌入式硬件
2301_7756023812 小时前
STM32什么是寄存器
stm32·单片机·嵌入式硬件