产品说明
产品特点
HC-SR04超声波测距模块可提供2cm-400cm
的非接触式距离感测功能,测距精度可达高到
3mm;模块包括超声波发射器、
接收器与控制电路。
基本工作原理
(1)采用IO口TRIG触发测距,给最少10us的高电平信呈。
(2)
模块自动发送8个40khz的方波,自动检测是否有信号返回;
(3)
有信号返回,通过IO口ECHO输出一个高电平,高电平持续的时间就是超声波从发射到返回的时间。测试距离=(高电平时间*声速(340M/S))/2;
实物图
如下图接线,
VCC供5V电源,GND为地线,TRIG触 发 控 制 信 号 输入,ECHO回响信号输出
等四个接口端。
电气参数
时序图
以上时序图表明你只需要提供一个10uS以上脉冲触发信号,该模块内部将发出8个40kHz周期电平并检测回波。一旦检测到有回波信号则输出回响信号。回响信号的脉冲宽度与所测的距离成正比。由此通过发射信号到收到的回响信号时间间隔可以计算得到距离。公式:uS/58=厘米或者uS/148=英寸;或是:距离=高电平时间*声(340M/S)/2;建议测量周期为60ms以上,以防止发射信号对回响信号的影响。
总结是:你只需要发送一个超过10US以上的脉冲触发信号,然后判断是否有回响信号,即判断是否有高电平,有则情况计数开始计时,再通过计时时间长短来计算距离
while(GPIO_ReadInputDataBit(HC_PORT,ECHO)==1);
//不等于1则:
//超过10us的TTL
TRIG_HIGH;
delay_us(20);
TRIG_LOW;
while(GPIO_ReadInputDataBit(HC_PORT,ECHO)==0);
//不等于0,有回响则:
TIM_SetCounter(TIM2,0);//清空计数器
msCount=0;//中断计数清0
TIM_Cmd(TIM2,DISABLE);//打开中断
while(GPIO_ReadInputDataBit(HC_PORT,ECHO)==1);
//回响电平输出结束 则关闭:
TIM_Cmd(TIM2,DISABLE);
使用指导,代码配置
明确IO口,对高低电平进行宏
#define TRIG GPIO_Pin_2//触发
#define ECHO GPIO_Pin_3//回响
#define HC_PORT GPIOA
#define TRIG_HIGH GPIO_SetBits(HC_PORT, TRIG)
#define TRIG_LOW GPIO_ResetBits(HC_PORT, TRIG)```
### 对相应的IO口,中断进行配置使能
```c
void HC_SR04_Config(void){
GPIO_InitTypeDef GPIO_InitStructer;
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructer;
NVIC_InitTypeDef NVIC_InitStructer;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);//TIM2
RCC_APB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE);
GPIO_InitStructer.GPIO_Pin = TRIG;//触发引脚
GPIO_InitStructer.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructer.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructer.GPIO_OType = GPIO_OType_PP;
GPIO_Init( HC_PORT,&GPIO_InitStructer);
GPIO_InitStructer.GPIO_Pin = ECHO;//回响
GPIO_InitStructer.GPIO_Mode = GPIO_Mode_IN;
GPIO_Init( HC_PORT,&GPIO_InitStructer);
TIM_TimeBaseInitStructer.TIM_Period=999;
TIM_TimeBaseInitStructer.TIM_Prescaler=72-1;
TIM_TimeBaseInitStructer.TIM_ClockDivision=TIM_CKD_DIV1;
TIM_TimeBaseInitStructer.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInitStructer.TIM_RepetitionCounter= DISABLE;
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStructer);
TIM_ClearFlag(TIM2,TIM_FLAG_Update);
TIM_ITConfig(TIM2,TIM_IT_Update|TIM_IT_Trigger,ENABLE);
TIM_Cmd(TIM2,DISABLE);
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
NVIC_InitStructer.NVIC_IRQChannel= TIM2_IRQn;
NVIC_InitStructer.NVIC_IRQChannelPreemptionPriority =0;
NVIC_InitStructer.NVIC_IRQChannelSubPriority=0;
NVIC_InitStructer.NVIC_IRQChannelCmd = ENABLE;
}
中断处理
通过中断服务函数来进行计数。
void TIM2_IRQHandler(void)
{
if(TIM_GetITStatus(TIM2,TIM_IT_Update)!=RESET)
{
TIM_ClearITPendingBit(TIM2,TIM_IT_Update);
msCount++;
}
}
模块功能函数
void HC_SR04(uint16_t *dataA,uint16_t *dataB)
{
uint32_t Count=0;
while(GPIO_ReadInputDataBit(HC_PORT,ECHO)==1);
TRIG_HIGH;
delay_us(20);
TRIG_LOW;
while(GPIO_ReadInputDataBit(HC_PORT,ECHO)==0);
TIM_SetCounter(TIM2,0);//清空计数器
msCount=0;//中断计数清0
TIM_Cmd(TIM2,DISABLE);//打开中断
while(GPIO_ReadInputDataBit(HC_PORT,ECHO)==1);
TIM_Cmd(TIM2,DISABLE);
Count = msCount*1000;
Count=Count+TIM_GetCounter(TIM2);
*dataA = Count / 58;
*dataB = Count / 0.017;
}
测距平衡修复
使用时只用调用这个函数即可
void HC_SR04_Banlance(uint8_t mode)
{
uint16_t dataA=0,dataB=0;uint32_t data=0;
HC_SR04(&dataA,&dataB);
if(mode)
{
for(uint8_t i=0;i<5;i++)
{
data=data+dataA;
}
}
else
{
for(uint8_t i=0;i<5;i++)
data= data+dataB;
}
//此时的data就是最终测距结果