【单片机项目】制作一辆基于STM32的智能小车——HC-SR04超声波模块

HC-SR04超声波避障模块

HC-SR04 超声波测距模块可提供 2cm-400cm 的非接触式距离感测功能, 测距精度可达高到 3mm;模块包括超声波发射器、接收器与控制电路。 基本工作原理: 
(1)采用IO口TRIG触发测距,给至少10us的高电平信号;
(2)模块自动发送8个40khz的方波,自动检测是否有信号返回;
(3)有信号返回,通过IO口ECHO输出一个高电平,高电平持续的时间就是超声波从发射到返回的时间。
测试距离=(高电平时间*声速(340M/S))/2;

由于可使用用IO有限,本次我只使用了两个HC-SR04。

以下为粗略的流程图,由于缺少一个超声波,流程比较鸡肋,但逻辑上没有问题。
由于缺少一个超声波,流程比较鸡肋,但逻辑上没有问题。

ultrasonic.h

#ifndef __ULTRASONIC_H
#define __ULTRASONIC_H	 
#include "sys.h"


void ulsonic0_config(void);
void ulsonic1_config(void);
u16 sonictest_forth(void);
u16 sonictest_right(void);
float changefunction(u16 count1);

#endif

ultrasonic.c

#include "ultrasonic.h"
#include "delay.h"

void ulsonic0_config()		//前向
{
    GPIO_InitTypeDef GPIO_InitStructure;
    
	  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);  //开启IO口对应的时钟
	  
	  GPIO_InitStructure.GPIO_Pin=GPIO_Pin_2;			//ECHO PA2
 GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPD
	  GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING;   
	  GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
	  GPIO_Init(GPIOA,&GPIO_InitStructure);
	
	  GPIO_InitStructure.GPIO_Pin=GPIO_Pin_3;			//TRIG PA3
	  GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;
      GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
	  GPIO_Init(GPIOA,&GPIO_InitStructure);
}

void ulsonic1_config()		//右侧
{
		GPIO_InitTypeDef GPIO_InitStructure;
    
		RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);  //开启IO口对应的时钟
		RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
	
	  GPIO_InitStructure.GPIO_Pin=GPIO_Pin_11;			//**************ECHO A11
 GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPD
	  GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING;   
	  GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
	  GPIO_Init(GPIOA,&GPIO_InitStructure);
	
	  GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0;			//**************TRIG B0
	  GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;
      GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
	  GPIO_Init(GPIOB,&GPIO_InitStructure);

}

u16 sonictest_forth(void)			//前路测试
{
		u16 res;
			GPIO_SetBits(GPIOA,GPIO_Pin_3);
			delay_us(20);
			GPIO_ResetBits(GPIOA,GPIO_Pin_3); 		//触发TRIG
			while(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_2) == 0);//等待ECHO高电平
			TIM_SetCounter(TIM3,0);
			TIM_Cmd(TIM3,ENABLE); //运行TIM3进行计时
			while(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_2)==1); 
			TIM_Cmd(TIM3,DISABLE);//关闭定时器
			res=TIM3->CNT;
	return res;
}


u16 sonictest_right(void)			//右路测试
{
		u16 res;
			GPIO_SetBits(GPIOB,GPIO_Pin_0);
			delay_us(30);
			GPIO_ResetBits(GPIOB,GPIO_Pin_0); 		//触发TRIG
			while(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_11) == 0);//等待ECHO高电平
			TIM_SetCounter(TIM3,0);
			TIM_Cmd(TIM3,ENABLE); //运行TIM3进行计时
			while(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_11)==1); 
			TIM_Cmd(TIM3,DISABLE);//关闭定时器
			res=TIM3->CNT;
	return res;



}

float changefunction(u16 count1)	//count->distance
{
		float distance1;
		distance1=count1*0.017;		//单位厘米cm
		return distance1;
}

main.c

#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "motor.h"
#include "timer.h"
#include "tick_ulsonic.h"
#include "ultrasonic.h"
/*********************************
可接超声波数量有限,故程序比较累赘
***************************************/

//count定时器数值
//float容错次数 减小超声波互扰因素

int main(void)
 {	
	//float distance;	 
	u16 count;
	u8 fault=0;	
	SystemInit();
	delay_init();	    //延时函数初始化	  nms<=1864  
	uart_init(115200);
	LED_Init();		  	//初始化与LED连接的硬件接口
	pwm_init(899,0); 
	delay_ms(1000);
	delay_ms(1800);
	Tim3_Config();
	ulsonic0_config();		//  ECHO PA2        TRIG PA3
	ulsonic1_config();		//  ECHO PA11        TRIG PB0

	while(1)
	{	
		LED=1;
		fault=2;
		motor_forth();		//前进
		count=sonictest_forth();
																							//		printf("count=%d\t\n",count);
																							//			distance=changefunction(count);
																							//				printf(" 当前距离为:%f\t\n",distance); 
		if(count<800){
		count=sonictest_forth();fault--;}
		if(count<800){
		count=sonictest_forth();fault--;}
		
		if(!fault)
		{		
			LED=0;
			motor_stop();
			delay_ms(1000);
			count = sonictest_right();
				if(count<1000)			//右侧不通,左转 
				{
					motor_left();
					delay_ms(500);
					count=sonictest_forth();
					if(count<800)
					{
						motor_left();
						delay_ms(500);
					}
				}else{
					motor_right();
					delay_ms(500);
				}
		
	
				}
		
		}   
	}

前方和右侧装有超声波模块的小车
前方和右侧装有超声波模块的小车

鉴于实践中超声波测量数值偶有波动,猜测是先后发出的超声波产生干扰,故引入fault变量,增加容错率。

  • 3
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值