HCSR04原理图
电路接线
1号Pin:接VCC电源(直流3V-5.5V)。
2号Pin:接外部电路的Trig端,向此管脚输入一个10uS以上的高电平,可触发模块测距。
3号Pin:接外部电路的Echo端,当测距结束时,此管脚会输出一个高电平,电平宽度为超声波往返时间之和。
4号Pin:接外部电路的地。
模块测距工作原理
只需要在Trig管脚输入一个10US以上的高电平,系统便可发出8个40KHZ的超声波脉冲,然后检测回波信号。当检测到回波信号后,通过Echo管脚输出。
Echo管脚输出高电平的持续时间可以计算距离值。即距离值为:(高电平时间*340m/s)/2。
当测量距离超过HC-SR04的测量范围时,仍会通过Echo管脚输出高电平的信号,高电平的宽度约为66ms。
测量周期:当接收到HC-SR04通过Echo管脚输出的高电平脉冲后,便可进行下一次测量,所以测量周期取决于测量距离,当距离被测物体很近时,Echo返回的脉冲宽度较窄,测量周期就很短;当距离被测物体比较远时,Echo返回的脉冲宽度较宽,测量周期也就相应的变长。
程序部分
#include "stm32f10x.h" // Device header
#include "Delay.h"
uint8_t Count = 0;
void HCSR04_Init(void )
{
RCC_APB2PeriphClockCmd (RCC_APB2Periph_GPIOA ,ENABLE );
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure .GPIO_Mode = GPIO_Mode_Out_PP ; //推挽输出
GPIO_InitStructure .GPIO_Pin = GPIO_Pin_6 ;
GPIO_InitStructure .GPIO_Speed = GPIO_Speed_50MHz ;
GPIO_Init (GPIOA ,&GPIO_InitStructure );
GPIO_ResetBits (GPIOA ,GPIO_Pin_6 );
GPIO_InitStructure .GPIO_Mode = GPIO_Mode_IN_FLOATING ; //浮空输入
GPIO_InitStructure .GPIO_Pin = GPIO_Pin_7 ;
GPIO_InitStructure .GPIO_Speed = GPIO_Speed_50MHz ;
GPIO_Init (GPIOA ,&GPIO_InitStructure );
GPIO_ResetBits (GPIOA ,GPIO_Pin_7 );
RCC_APB1PeriphClockCmd (RCC_APB1Periph_TIM3 ,ENABLE );
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
TIM_TimeBaseInitStructure .TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseInitStructure .TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInitStructure .TIM_Period = 1000-1;
TIM_TimeBaseInitStructure .TIM_Prescaler = 72-1;
TIM_TimeBaseInitStructure .TIM_RepetitionCounter = 0;
TIM_TimeBaseInit (TIM3 ,&TIM_TimeBaseInitStructure );
TIM_ClearFlag (TIM3,TIM_FLAG_Update ); //清除标志位
TIM_ITConfig (TIM3 ,TIM_IT_Update ,ENABLE );
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2 );
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure .NVIC_IRQChannel = TIM3_IRQn;
NVIC_InitStructure .NVIC_IRQChannelCmd = ENABLE;
NVIC_InitStructure .NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure .NVIC_IRQChannelSubPriority = 1;
NVIC_Init (&NVIC_InitStructure);
TIM_Cmd (TIM3 ,ENABLE );
}
void Set_Counter(void ) //设置定时器存储值
{
TIM_SetCounter (TIM3,0);
Count = 0;
TIM_Cmd (TIM3,ENABLE );
}
void Exit_Counter(void )
{
TIM_Cmd (TIM3,DISABLE);
}
void TIM3_IRQHandler(void )
{
if(TIM_GetITStatus (TIM3,TIM_IT_Update) == 1)
{
TIM_ClearITPendingBit(TIM3 ,TIM_IT_Update );
Count ++;
}
}
uint16_t Get_Counter(void)
{
uint32_t Num = 0;
Num = Count * 1000;
Num += TIM_GetCounter (TIM3);
TIM3->CNT = 0;
Delay_ms (50);
return Num;
}
float Get_Length(void )
{
uint8_t i = 0;
uint32_t t;
float L;
float S;
while(i != 5)
{
GPIO_SetBits (GPIOA ,GPIO_Pin_6);
Delay_us (12);
GPIO_ResetBits (GPIOA ,GPIO_Pin_6 );
if(GPIO_ReadInputDataBit (GPIOA ,GPIO_Pin_7 ) == 1)
{
Set_Counter ();
i = i+1;
while(GPIO_ReadInputDataBit (GPIOA ,GPIO_Pin_7 ) == 1 );
Exit_Counter ();
t = Get_Counter();
L = ((float )t/58.0);
S = L + S;
L = S /5.0;
}
}
return L;
}