HC-SR04多通道超声波测距原理详解

 

目录

一、 HC-SR04简介

 二、工作原理

三、多通道超声波


一、 HC-SR04简介

 超声波测距原理是在超声波发射装置发出超声波,在发射超声波的同时开始计时,超声波在空气中传播,在传播的时刻碰到障碍物,就会返回一个信号给超声波接收器,超声波接收器接收到信号后立即停止计时,这时候会有一个时间t,而超声波在空气中传播的速度为340m/s,通过公式s=340 x t / 200,即可计算出待测距离是多少。

 二、工作原理

 

Step1:通过IO口给Trig接口周期不小于10us的脉冲信号。
Step2:HC-SR04接收到单片机发来的脉冲信号后自动发送8个频率为40KHz的方波,自动检测是否有信号返回。
Step3:若有信号返回,则通过Echo接口向单片机相连的IO口发送一个高电平,高电平持续时间就是超声波从发射到返回的总时间。
距离计算:假设高电平持续时间为T,声速为V(一般为340m/s),时间T是从发射到返回的时间,超声波测距模块到障碍物时间为T的一半。

                        距离S=(T*V)/2。

三、多通道超声波

整体流程:

1.使用定时器1定时对全部超声波模块进行轮询工作,定时器2为高电平计时时间,外部中断为高电平开始和结束用来使能或失能定时器2。

2.将HC-SR04引脚对应的Tirg引脚设置为推挽输出,将echo引脚设置为上升下降沿的外部中断,一个外部中断服务函数对应一个超声波模块。

三个超声波对应的Tirg引脚分别为D3、D4、D7;echo引脚分别是C0、C1、C3;

超声波初始化

void sr04_init(void)
{
	GPIO_InitTypeDef  GPIO_InitStructure;

  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD, ENABLE);	 
	
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_7|GPIO_Pin_14;	  
	
	GPIO_Init(GPIOD, &GPIO_InitStructure);
	GPIO_ResetBits(GPIOD,GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_7|GPIO_Pin_14); 	  
}

外部中断初始化

void exti_Configure(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;    
    EXTI_InitTypeDef EXTI_InitStructure;
	NVIC_InitTypeDef NVIC_InitStructure;
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
	
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;
    GPIO_Init(GPIOC, &GPIO_InitStructure);
	GPIO_ResetBits(GPIOC, GPIO_Pin_0);
	
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;                   
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;         
    GPIO_Init(GPIOC, &GPIO_InitStructure); 
    GPIO_ResetBits(GPIOC, GPIO_Pin_1);
	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;                   
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;         
    GPIO_Init(GPIOC, &GPIO_InitStructure); 
    GPIO_ResetBits(GPIOC, GPIO_Pin_2);
	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;                   
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;         
    GPIO_Init(GPIOC, &GPIO_InitStructure); 
    GPIO_ResetBits(GPIOC, GPIO_Pin_3);
		
    GPIO_EXTILineConfig(GPIO_PortSourceGPIOC, GPIO_PinSource0);  
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_3);//中断优先级分组使能
    EXTI_InitStructure.EXTI_Line = EXTI_Line0;
    EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; 
    EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling;
    EXTI_InitStructure.EXTI_LineCmd = ENABLE;
    EXTI_Init(&EXTI_InitStructure);    
		
	GPIO_EXTILineConfig(GPIO_PortSourceGPIOC, GPIO_PinSource1);
    EXTI_InitStructure.EXTI_Line = EXTI_Line1;
    EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; 
    EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling;
    EXTI_InitStructure.EXTI_LineCmd = ENABLE;
    EXTI_Init(&EXTI_InitStructure); 
		
	GPIO_EXTILineConfig(GPIO_PortSourceGPIOC, GPIO_PinSource2);
	EXTI_InitStructure.EXTI_Line = EXTI_Line2;
    EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; 
    EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling;
    EXTI_InitStructure.EXTI_LineCmd = ENABLE;
    EXTI_Init(&EXTI_InitStructure); 
		
	GPIO_EXTILineConfig(GPIO_PortSourceGPIOC, GPIO_PinSource3);
	EXTI_InitStructure.EXTI_Line = EXTI_Line3;
    EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; 
    EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling;
    EXTI_InitStructure.EXTI_LineCmd = ENABLE;
    EXTI_Init(&EXTI_InitStructure);
		
	NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;         
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;  
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;                   
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                             
    NVIC_Init(&NVIC_InitStructure);       
	
    NVIC_InitStructure.NVIC_IRQChannel = EXTI1_IRQn;          
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority =1;   
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;                 
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                           
    NVIC_Init(&NVIC_InitStructure);       
		
		
	NVIC_InitStructure.NVIC_IRQChannel = EXTI2_IRQn;          
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;  
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;              
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                         
    NVIC_Init(&NVIC_InitStructure);     

   
	EXTI_ClearITPendingBit(EXTI_Line0);
	EXTI_ClearITPendingBit(EXTI_Line1);
	EXTI_ClearITPendingBit(EXTI_Line2);
}

其中一个中断服务函数

void EXTI0_IRQHandler(void)
{
	if (EXTI_GetITStatus(EXTI_Line0) != RESET) {
if (GPIO_ReadInputDataBit(GPIOC, GPIO_Pin_0) != 0) { 
            TIM_Cmd(TIM2, ENABLE);  
        } else {
            TIM_Cmd(TIM2, DISABLE);  
            measurement[0] = TIM_GetCounter(TIM2);
            TIM_SetCounter(TIM2, 0); 
			distance[0]= (count*65536+measurement[0])/1.0/10000*340;
        }
    }
    EXTI_ClearITPendingBit(EXTI_Line0);
}

定时器的中断服务函数


void TIM2_IRQHandler(void)		/
{	
	if(TIM_GetITStatus(TIM2,TIM_IT_Update)!=RESET)
	{
		count++;
		TIM_ClearITPendingBit(TIM2,TIM_IT_Update);
		
	}
}

void TIM3_IRQHandler(void)		
{	
	
	if(TIM_GetITStatus(TIM3,TIM_IT_Update)!=RESET)
	{
		sr04_1();
        sr04_2();
        sr04_3();
		TIM_SetCounter(TIM3, 0); 
		TIM_ClearITPendingBit(TIM3,TIM_IT_Update);
		
	}
}

启动第一个超声波模块测距

#define  tri1           PDout(3)  

void sr04_1(void)
{   
    count=0;
	tri1=1;
	Delay_us(15);
}

distance[i]为测距结果。

物联沃分享整理
物联沃-IOTWORD物联网 » HC-SR04多通道超声波测距原理详解

发表评论