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);
    }
}
相关推荐
三佛科技-1341638421215 分钟前
KP32511SGA固定12V输出小家电电源芯片 典型应用电路
单片机·嵌入式硬件
xingzhemengyou141 分钟前
STM32启动流程
stm32·单片机·嵌入式硬件
aduzhe42 分钟前
int32 - int32MAX 出现异常
c语言·stm32
youcans_1 小时前
【动手学STM32G4】(4)STM32G431之ADC与DAC
stm32·单片机·嵌入式硬件·数据采集·串口通信
boneStudent4 小时前
Day32:SPI 配置与使用
stm32·单片机·嵌入式硬件
逆小舟5 小时前
【RTOS】处理中断
单片机·嵌入式硬件
ACP广源盛139246256736 小时前
GSV1015@ACP#1015/2015产品规格详解及产品应用分享
单片机·嵌入式硬件·音视频
三品吉他手会点灯6 小时前
STM32F103学习笔记-19-SysTick-系统定时器(第1节)-功能框图讲解和优先级配置
笔记·stm32·单片机·嵌入式硬件·学习
风哥在风中6 小时前
与防静电腕带完全不同性质:电烙铁必须硬接地,而且良好接地
单片机·嵌入式硬件·智能硬件·esd防护·iot硬件
时空自由民.7 小时前
stm32FXX系列MCU汇编启动文件分析
汇编·stm32·单片机