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);
    }
}
相关推荐
兆龙电子单片机设计5 小时前
【STM32项目开源】STM32单片机智能台灯系统
stm32·单片机·物联网·开源·毕业设计
sheepwjl6 小时前
《嵌入式硬件(十七):基于IMX6ULL的温度传感器LM75a操作》
单片机·嵌入式硬件·imx6ull·lm75a
liujing102329296 小时前
stm32_基于 STM32U575 的飞行器姿态实时监控系统
stm32
jmlinux11 小时前
stm32与串口屏双向通讯官方例程
c语言·stm32·单片机·嵌入式硬件·物联网
GilgameshJSS15 小时前
STM32H742-ARM例程32-LCD
c语言·arm开发·stm32·单片机·嵌入式硬件·计算机外设
weixin_5168652618 小时前
STM32H750寄存器操作(硬件I2C)
stm32·1024程序员节
heisd_118 小时前
什么是状态机编程和模块化编程
单片机·嵌入式硬件
liujing1023292919 小时前
stm32_关于乐鑫ESP8266-07S WIFI模组烧录安信可科技的MQTT固件流程
科技·stm32·嵌入式硬件
zzz海羊21 小时前
江科大stm32 | OLED显示汉字
stm32·单片机·嵌入式硬件
Jack1530276827921 小时前
误接电容正负极的风险与注意事项
单片机·嵌入式硬件·逆变器·摇头机·电动工具·dc/dc变换器