超声波测距模块HC_SR04(基于STM32) 工作原理/代码

产品说明

产品特点

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就是最终测距结果
	
  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值