博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
HC_SR04超声波模块的应用
阅读量:1834 次
发布时间:2019-04-25

本文共 3894 字,大约阅读时间需要 12 分钟。

1 简介

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rmL6K1rd-1622357456357)(5D1EE850E8DC4CAAB01D5ECF89315CEC)]

HC-SR04 超声波测距模块可提供 2cm-400cm 的非接触式距离感测功能,测 距精度可达高到 3mm ;模块包括超声波发射器、接收器与控制电路。

电气参数 HC-SR04 超声波模块
工作电压 DC 5 V
工作电流 15mA
工作频率 40kHz
最远射程 4m
最近射程 2cm
测量角度 15 度
输入触发信号 10uS 的 TTL 脉冲
输出回响信号 输出 TTL 电平信号,与射程成比例
规格尺寸 45X20X15mm

2 时序图

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zMZER3MN-1622357456359)(6BDAC968DC7D497290B1C03ECD9D55E7)]

简单来说

  • 提供一个 10uS 以上脉冲触发信号,该模块内部将发出 8 个 40kHz 周期电平并检测回波。
  • 一旦检测到有回波信号则输出回响信号。回响信号的脉冲宽度与所测的距离成正比。
  • 由此通过发射信号到收到的回响信号时间间隔可以计算得到距离。

测算公式:距离=高电平时间*声速(340M/S)/2。

声速与温度有关,如果环境温度变化显著,必须考虑温度补偿问题。空气中声速与温度的关系可以表示为

在这里插入图片描述

几点注意事项

  • 建议测量周期为 60ms 以上,以防止发射信号对回响信号的影响。
  • 此模块不宜带电连接,若要带电连接, 则先让模块的 GND 端先连接,否则会影响模块的正常工作。
  • 测距时,被测物体的面积不少于 0.5 平方米且平面尽量要求平整,否则影响测量的结果。

3 程序设计(stm32)

思路:测量的距离与高电平的时间有关,而且高电平时间不超过60ms,那我们可以利用定时器来获取高电平的时间。将定时器设置为720分频,自动重装载值为 7000,则每70ms进入一次中断(如果进入了中断说明距离超出最大测量范围), 记一次数是10us。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-e96TQfQd-1622357456364)(BBBD738FA60646F29523B10CEE4F5809)]

3.1 测量函数

u8 sr04_over_flag; //当高电平时间大于70ms,说明超出最大测量范围/* * 函数功能:发送触发信号 */void  SendTrigSign(void){	Trig=1;	delay_us(15);	Trig=0;}/* * 函数功能:计算距离 * 返 回 值:Distance 距离   */float distance_Count(void) 	{    	u8 time = 0;	float Speed;	float  Distance;		time = TIM_GetCounter(TIM4);	TIM_SetCounter(TIM4,0);//计数器值清零	Speed = 331.4 + 0.607 * Temp;//计算声速,Temp是当前温度值	Distance = (time*Speed)/2;    //距离测算		return Distance;}/* * 函数功能:控制定时器,测量高电平时间 * 返 回 值: f 距离 */float Ultrasound_Measure(void){	float f = 0.0 ;	sr04_over_flag = 0 ; 		SendTrigSign() ;	while(!Echo);  //当回响信号为零时等待	TIM_ITConfig(TIM4,TIM_IT_Update,ENABLE);//使能或者失能指定的TIM中断	TIM_Cmd(TIM4,ENABLE);//使能TIM4外设	while(Echo);	TIM_ITConfig(TIM4,TIM_IT_Update,DISABLE);//使能或者失能指定的TIM中断	TIM_Cmd(TIM4,DISABLE);//失能TIM4外设	  	    if(sr04_over_flag==1)	{		 f = 400 ;//最大距离,高电平时间持续大于70ms了	}	else    	{		f = distance_Count();	}	return f ;}

3.2 初始化函数

/* * 函数功能:初始化超声波模块的两个管脚 * Trig    触发信号控制输入-----PC9配置成推挽输出 * Echo    回响信号输出---------PC8配置成上拉输入 */void Ultrasonic_IO_Init(void){	GPIO_InitTypeDef  GPIO_InitStructure;	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);	 //使能PC端口时钟	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;			//Trig-->PC.9 端口配置	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; ; 	//上拉输入	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;	//IO口速度为50MHz	GPIO_Init(GPIOC, &GPIO_InitStructure);				//根据设定参数初始化GPIOC.9	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;	    		//Echo-->PC.8 端口配置, 推挽输出	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 	//推挽输出	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;	//IO口速度为50MHz	GPIO_Init(GPIOC, &GPIO_InitStructure);	  			//推挽输出 ,IO口速度为50MHz		GPIO_ResetBits(GPIOC,GPIO_Pin_9); 						 //PC.9 输出低}/* * 函数功能:通用定时器4初始化 * 形    参:arr:自动重装值 *           psc:时钟预分频数 */void TIM4_time_init(u16 arr,u16 psc ){	TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;	NVIC_InitTypeDef NVIC_InitStructure;		RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE); //时钟使能	TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值	 	TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值  	TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_tim	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数模式	TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位	    	NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn;  //TIM4中断	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;  //先占优先级0级	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;  //从优先级3级	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能	NVIC_Init(&NVIC_InitStructure);  //根据NVIC_InitStruct中指定的参数初始化外设}

3.3 定时器中断服务函数

void TIM4_IRQHandler(void)   //TIM4中断{	if (TIM_GetITStatus(TIM4, TIM_IT_Update) != RESET) //检查指定的TIM中断发生与否:TIM 中断源 	{		TIM_ClearITPendingBit(TIM4, TIM_IT_Update);  //清除TIMx的中断待处理位:TIM 中断源 		sr04_over_flag = 1;		}}

3.4 main.c

int main(void){		float dis;		delay_init();	    	 //延时函数初始化	  	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);	//设置NVIC中断分组2:2位抢占优先级,2位响应优先级	uart_init(9600);	Ultrasonic_IO_Init();	TIM4_time_init(6999,719);//定时器70ms中断一次T = ((719+1)*(6999+1)) /72000 000 =70ms																	while(1)	{		dis = Ultrasound_Measure();		printf("距离为%f\r\n",dis);//单位cm	}

转载地址:http://lkduf.baihongyu.com/

你可能感兴趣的文章
现在做Android开发有前途吗?社招面试心得
查看>>
疯狂涨知识!三年经验Android开发面经总结,醍醐灌顶!
查看>>
白嫖党最爱!面向Android开发者的复习指南!源码+原理+手写框架
查看>>
百度、华为、京东、B站最新面试题汇集,完整PDF
查看>>
ndk开发入门,Android自定义View详解,面试必问
查看>>
ndk开发教程,Android-Binder机制及AIDL使用,实战篇
查看>>
ndk开发流程,Android开发还会吃香吗?绝对干货
查看>>
retrofit教程,Android面试资料集合,大牛最佳总结
查看>>
retrofit解析,你有过迷茫吗?完整版开放下载
查看>>
rxjava面试题,Android热修复原理,吐血整理
查看>>
34岁安卓开发大叔感慨,好文推荐
查看>>
34岁安卓开发大叔感慨,成功入职阿里
查看>>
35岁以后的Android程序员出路在哪里?大牛最佳总结
查看>>
35岁以后的Android程序员出路在哪里?完整PDF
查看>>
4个改变你编程技能的小技巧,深度解析,值得收藏
查看>>
5年老安卓面试竟然被这3道Android基础题难倒了?全网疯传
查看>>
5年老安卓面试竟然被这3道Android基础题难倒了?隔壁都馋哭了
查看>>
6年老Android面经总结,面试必备
查看>>
6年菜鸟开发面试字节跳动安卓研发岗,积累总结
查看>>
7年老Android一次坑爹的面试经历,吊打面试官系列!
查看>>