STM32MINI板写的超声波代码

HC-SR04超声波测距模块可提供2cm-400cm的非接触式距离感测功能,测距精度可达高到3mm;模块包括超声波发射器、接收器与控制电路。像智能小车的测距以及避障,六足机器人等避障,飞行器定高和避障常常会用到。
超市波实物图

1.超声波模块和单片机进行连接。
2.触发信号,给Trig引脚发送一个大于10us的高电平。
3.发送高电平后,模块会循环发送8个40KHZ的脉冲,与此同时Echo引脚会由低电平变成高电平,这时候就需要开启定时器开始计算Echo引脚的高电平时间,
4.模块接收到返回的超声波时,Echo电平会由高电平变成低电平,此时应该关闭定时器,这个时候的算出来的定时器的时间就是Echo持续的高电平,也就是超声波从发射到传回来的总时间。
5.(除去温度的影响)根据声速为340m/s,来计算(高电平时间 * 340m/s) / 2。 计算的时候注意自己使用定时器获得的时间的单位。记得换算。

超声波时序图

下面开始放代码 用的单片机是STM32min板

首先是超声波模块引脚定义以及获取时间和测量距离的长度的代码

#include "sys.h"
#include "us.h"
#include "delay.h"

u16 msTime;

void US_Init(u16 arr,u16 psc)
{
	GPIO_InitTypeDef GPIO_Initsture;
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitsture;
	NVIC_InitTypeDef NVIC_Initsture;
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);   
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);	//使能TIM2时钟 
	
	GPIO_Initsture.GPIO_Pin = GPIO_Pin_0;  //PA0   ECHO  回响信号
	GPIO_Initsture.GPIO_Mode = GPIO_Mode_IN_FLOATING; //浮空输入
	GPIO_Initsture.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_Initsture);
	GPIO_ResetBits(GPIOA,GPIO_Pin_0);
	GPIO_Initsture.GPIO_Pin = GPIO_Pin_1;  //PA1  TRIG 触发信号
	GPIO_Initsture.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_Init(GPIOA,&GPIO_Initsture);
	GPIO_ResetBits(GPIOA,GPIO_Pin_1); 
	
	TIM_DeInit(TIM3);
	
	TIM_TimeBaseInitsture.TIM_Period = arr;  
	TIM_TimeBaseInitsture.TIM_Prescaler = psc;  
	TIM_TimeBaseInitsture.TIM_ClockDivision = TIM_CKD_DIV1;
	TIM_TimeBaseInitsture.TIM_CounterMode = TIM_CounterMode_Up;
	TIM_TimeBaseInit(TIM3, &TIM_TimeBaseInitsture);
	
	TIM_ClearFlag(TIM3,TIM_FLAG_Update);  //清除更新中断
	TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE); //打开定时器更新下个中断
	
	NVIC_Initsture.NVIC_IRQChannel = TIM2_IRQn;
	NVIC_Initsture.NVIC_IRQChannelPreemptionPriority = 0;
	NVIC_Initsture.NVIC_IRQChannelSubPriority = 3;
	NVIC_Initsture.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&NVIC_Initsture);
	
	TIM_Cmd(TIM2,DISABLE);  //使能定时器2
	
}

void openTime(void)  //开启定时器
{
	TIM_SetCounter(TIM2,0);
	msTime = 0;
	TIM_Cmd(TIM2,ENABLE);
}

void TIM2_IRQHandler(void)  //定时器中断
{
	if(TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET)  //检查TIM2更新中断是否发生
		{
		TIM_ClearITPendingBit(TIM2, TIM_IT_Update);  /清除TIM2更新中断
		msTime++;
	}
}


u16 getTime(void)  //获取时间函数
{
	u16 t = 0;
	t = msTime *1000;  //ms转换成us
	t += TIM_GetCounter(TIM2);
	TIM12->CNT = 0;
	delay_ms(50);
	return t;
}


float getLength(void)  //获取测量距离的长度函数
{
	int i = 0;
	float length = 0,time = 0;
	while(i != 5)		//测量5次取一次平均值
	{
		TRIG = 1; //触发信号
		delay_us(20);
		TRIG = 0;
		while(ECHO == 0);
		openTime();//
		i ++;
		while(ECHO == 1);
		TIM_Cmd(TIM2,DISABLE);  //关闭定时器
		time += getTime();
	}
	time = time / 5.0;
	length = time*0.017;
	return length;
}

接下来是定时器2配置代码

#include "sys.h"
#include "time.h"


void Timer_Init(u16 arr,u16 psc)
{
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitsture;
	NVIC_InitTypeDef NVIC_Initsture;
	
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //使能时钟 
	
	TIM_TimeBaseInitsture.TIM_Period = arr;  
	TIM_TimeBaseInitsture.TIM_Prescaler = psc;  
	TIM_TimeBaseInitsture.TIM_ClockDivision = 0;  
	TIM_TimeBaseInitsture.TIM_CounterMode = TIM_CounterMode_Up;   //定时器向上计数
	TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitsture); 
	
	TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE);
	
	NVIC_Initsture.NVIC_IRQChannel = TIM3_IRQn; 
	NVIC_Initsture.NVIC_IRQChannelPreemptionPriority = 0;
	NVIC_Initsture.NVIC_IRQChannelSubPriority = 2;
	NVIC_Initsture.NVIC_IRQChannelCmd = ENABLE;  
	NVIC_Init(&NVIC_Initsture);  //初始化TIM3中断
	
	TIM_Cmd(TIM3,ENABLE);  
	
}

void TIM3_IRQHandler(void)
{
	if(TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET )  
	{
		TIM_ClearITPendingBit(TIM3,TIM_IT_Update); 
	}
}

最后是主函数代码,我用的是串口将测量的数据打印到山外多功能调试助手上。

#include "delay.h"
#include "usart.h"
#include "time.h"
#include "us.h"

int main(void)
{
	float length;
	delay_init();
	uart_init(9600);
	US_Init(999,71); // 1ms
	printf("超声波测试\r\n");
	while(1)
	{
		length = getLength();
		 
		printf("%.2f\n",length);
	}
}

代码自己亲自使用有效,我是学习超声波为了给飞行器定高测距用的,虽然四轴飞行器再飞行的时候桨叶的旋转会对超声波由一定的干扰,但是再3米一下的测量高度,超声波还是不二之选,大于3米的可以利用气压计和超声波一起辅助定高。

使用模块之前还是要检查好,一个引脚插错了这个实验就做不出来了,读出的数据就是错误的了。一定细心,超声波要求是接5V的电源,但是我使用的时候接3V3也是可以使用的,也不耽误事。

  • 6
    点赞
  • 42
    收藏
    觉得还不错? 一键收藏
  • 8
    评论
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值