需要做一个智能车库控制系统的小项目,第一个要完成的就是利用超声波测距来实现报警的功能。本人嵌入式初级学徒,以尽量简单详细的方式,为大家介绍。
设备
1、超声波测距使用的是HC-SR04
2、开发板是普中科技的PZ6808L-F4 (stm32F407ZG芯片)
超声波模块详细介绍
1、管脚
首先看看HC-SR04的四个管脚
VCC:接5V电源
Trig:触发信号输入
Echo:回响信号接收
GND:接地
2、原理
超声波模块触发以后,会向前发射超声波脉冲,超声波脉冲在碰撞到物体以后会反射回来,模块接收到反射信号以后就完成一次测距。计算这个发射到接收的时间,计算这个时间与超声波传播速度的关系,就可以得到距离。
![](https://file.elecfans.com/web2/M00/09/78/pYYBAGD1vRmAMbDSAAClEcV8Quk764.png)
3、驱动步骤
利用stm32给Trig管脚一个超过10us的高电平以后,模块会自动发出脉冲信号,发出信号的同时Echo管脚会持续输出高电平。这个时候利用stm32定时器的计数功能,开始计算Echo管脚为高电平的时间。模块接收到返回的超声波信号以后。Echo输出的高电平结束。定时器停止计数。这时候对定时器的值稍加处理,就可以得到准确的距离了。
![](https://file.elecfans.com/web2/M00/09/74/poYBAGD1vR6ABKtOAAD5fI2HaEM184.png)
具体代码实现
1、代码前的准备
VCC和GND不用多说,接5V电源就好。
Trig接到PF9管脚
Echo接到PF10管脚
使用的是stm32的定时器4
注:代码面向新手,我尽量吧所有的代码用简单易懂的话写到注释里。
2、具体代码
在stm32f4的库函数模板工程以后
首先向工程中新建两个超声波模块的文件ultr.h和ultr.c并添加到工程中。(不会的自己面壁去)
ultr.h中的代码
#ifndef _ultr_H//如果没有_ultr_H#define _ultr_H//创建_ultr_H# include "system.h"//位带操作的文件//函数声明void ultr_Init();void UltrasonicWave_StartMeasure(void);float UltrasonicWave_Measure(void) ;#endif ultr.c中的代码
# include "ultr.h"# include "SysTick.h"//延时函数的头文件//PF9管脚接trig PF10管脚接echavoid ultr_Init()//ultr初始化函数{ GPIO_InitTypeDef GPIO_InitStructure;//定义GPIO初始化结构体变量 TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;//定义定时器结构体 RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF,ENABLE);//使能端口F时钟 RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4,ENABLE);//使能time4时钟 //GOIO初始化 // PF9 trig管脚初始化 GPIO_InitStructure.GPIO_Mode=GPIO_Mode_OUT; //输出模式 GPIO_InitStructure.GPIO_Pin=GPIO_Pin_9|GPIO_Pin_10;//管脚设置 GPIO_InitStructure.GPIO_Speed=GPIO_Speed_100MHz;//速度设置 GPIO_InitStructure.GPIO_OType=GPIO_OType_PP;//推挽输出 GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_UP;//上拉 GPIO_Init(GPIOF,&GPIO_InitStructure); //初始化结构体 GPIO_ResetBits(GPIOF,GPIO_Pin_9);//初始化led为低电平 //PF10 echa管脚初始化 GPIO_InitStructure.GPIO_Pin=GPIO_Pin_10;//GPIOA_10管脚 GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN;//设置为输入模式 GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_DOWN;//下拉 GPIO_Init(GPIOF,&GPIO_InitStructure); //初始化结构体 //定时器4初始化 TIM_TimeBaseInitStructure.TIM_Period=65535;//定时器周期 TIM_TimeBaseInitStructure.TIM_Prescaler=71;//定时预分频器 TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1;//时钟分频 TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up;//计数模式 TIM_TimeBaseInit(TIM4,&TIM_TimeBaseInitStructure);//初始化结构体 TIM_ITConfig(TIM4,TIM_IT_Update,ENABLE);//初始化时钟结构体 TIM_ClearITPendingBit(TIM4,TIM_IT_Update);//中断标志清除}//超声波模块启动函数void UltrasonicWave_StartMeasure(void){ GPIO_SetBits(GPIOF, GPIO_Pin_9); //拉高pf9电平 delay_us(30);//持续30us GPIO_ResetBits(GPIOF, GPIO_Pin_9); //拉低pf9电平}//测距函数 返回定时器计数值float UltrasonicWave_Measure(void) //{ while(GPIO_ReadInputDataBit(GPIOF,GPIO_Pin_10)==1){ }//echo为高电平时,则等待至低电平,才启动超声波 UltrasonicWave_StartMeasure(); //启动超声波 while(GPIO_ReadInputDataBit(GPIOF,GPIO_Pin_10) == 0)//等待echo的高电平到来 { delay_us(20);//持续20us} TIM_SetCounter(TIM4,0); //清零计数器 TIM_Cmd(TIM4, ENABLE); //使能定时器2,开始计数 while(GPIO_ReadInputDataBit(GPIOF,GPIO_Pin_10) == 1)//等待echo的高电平结束{} TIM_Cmd(TIM4, DISABLE); //失能定时器4,截止计数 return (TIM_GetCounter(TIM4)); //返回定时计数器的计数值} main函数中的代码
# include "system.h"# include "beep.h"# include "SysTick.h"# include "usart.h"# include "ultr.h"int main(){ int distance;//距离 ultr_Init();//初始化超声波 USART1_Init(9600);//初始化串口 SysTick_Init(168);//初始化时钟 BEEP_Init();//蜂鸣器初始化 while(1) { distance=0;//初始化距离参数为零 distance = (int)UltrasonicWave_Measure(); //调用测距函数完成测距 delay_ms(60);//建议测量周期为 60ms以上, 以防止发射信号对回响信号的影响。 printf("距离为:%dn",distance);//打印到串口 //判断距离来控制蜂鸣器的开关 if(distance<1041)//距离小于0.5m { beep=0;//蜂鸣器持续开启 }else if(distance>1047&&distance<3249)//距离大于0.5米小于1.5米 { beep=!beep; //蜂鸣器间断开启 }else if(distance>3249)//距离大于1.5米 { beep=1;//关闭蜂鸣器 } } } 结尾
以上就是关于超声波模块的全部内容了。由于项目里不需要实时精确的测量具体距离,只需要测量定点距离计数器的值,用来控制蜂鸣器即可。所以得到计数器的值以后我没有再去计算出具体的距离。
所有内容全部面向新手,觉得有用的点赞鼓励一下,如果还是不会用的同学请在下方留言。需要源码工程的也可以私信我。
后续的智能车库系统项目里还会涉及到步进电机和红外遥控的使用,需要教程关注一下,后续我会再写,谢谢观看。
需要做一个智能车库控制系统的小项目,第一个要完成的就是利用超声波测距来实现报警的功能。本人嵌入式初级学徒,以尽量简单详细的方式,为大家介绍。
设备
1、超声波测距使用的是HC-SR04
2、开发板是普中科技的PZ6808L-F4 (stm32F407ZG芯片)
超声波模块详细介绍
1、管脚
首先看看HC-SR04的四个管脚
VCC:接5V电源
Trig:触发信号输入
Echo:回响信号接收
GND:接地
2、原理
超声波模块触发以后,会向前发射超声波脉冲,超声波脉冲在碰撞到物体以后会反射回来,模块接收到反射信号以后就完成一次测距。计算这个发射到接收的时间,计算这个时间与超声波传播速度的关系,就可以得到距离。
![](https://file.elecfans.com/web2/M00/09/78/pYYBAGD1vRmAMbDSAAClEcV8Quk764.png)
3、驱动步骤
利用stm32给Trig管脚一个超过10us的高电平以后,模块会自动发出脉冲信号,发出信号的同时Echo管脚会持续输出高电平。这个时候利用stm32定时器的计数功能,开始计算Echo管脚为高电平的时间。模块接收到返回的超声波信号以后。Echo输出的高电平结束。定时器停止计数。这时候对定时器的值稍加处理,就可以得到准确的距离了。
![](https://file.elecfans.com/web2/M00/09/74/poYBAGD1vR6ABKtOAAD5fI2HaEM184.png)
具体代码实现
1、代码前的准备
VCC和GND不用多说,接5V电源就好。
Trig接到PF9管脚
Echo接到PF10管脚
使用的是stm32的定时器4
注:代码面向新手,我尽量吧所有的代码用简单易懂的话写到注释里。
2、具体代码
在stm32f4的库函数模板工程以后
首先向工程中新建两个超声波模块的文件ultr.h和ultr.c并添加到工程中。(不会的自己面壁去)
ultr.h中的代码
#ifndef _ultr_H//如果没有_ultr_H#define _ultr_H//创建_ultr_H# include "system.h"//位带操作的文件//函数声明void ultr_Init();void UltrasonicWave_StartMeasure(void);float UltrasonicWave_Measure(void) ;#endif ultr.c中的代码
# include "ultr.h"# include "SysTick.h"//延时函数的头文件//PF9管脚接trig PF10管脚接echavoid ultr_Init()//ultr初始化函数{ GPIO_InitTypeDef GPIO_InitStructure;//定义GPIO初始化结构体变量 TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;//定义定时器结构体 RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF,ENABLE);//使能端口F时钟 RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4,ENABLE);//使能time4时钟 //GOIO初始化 // PF9 trig管脚初始化 GPIO_InitStructure.GPIO_Mode=GPIO_Mode_OUT; //输出模式 GPIO_InitStructure.GPIO_Pin=GPIO_Pin_9|GPIO_Pin_10;//管脚设置 GPIO_InitStructure.GPIO_Speed=GPIO_Speed_100MHz;//速度设置 GPIO_InitStructure.GPIO_OType=GPIO_OType_PP;//推挽输出 GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_UP;//上拉 GPIO_Init(GPIOF,&GPIO_InitStructure); //初始化结构体 GPIO_ResetBits(GPIOF,GPIO_Pin_9);//初始化led为低电平 //PF10 echa管脚初始化 GPIO_InitStructure.GPIO_Pin=GPIO_Pin_10;//GPIOA_10管脚 GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN;//设置为输入模式 GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_DOWN;//下拉 GPIO_Init(GPIOF,&GPIO_InitStructure); //初始化结构体 //定时器4初始化 TIM_TimeBaseInitStructure.TIM_Period=65535;//定时器周期 TIM_TimeBaseInitStructure.TIM_Prescaler=71;//定时预分频器 TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1;//时钟分频 TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up;//计数模式 TIM_TimeBaseInit(TIM4,&TIM_TimeBaseInitStructure);//初始化结构体 TIM_ITConfig(TIM4,TIM_IT_Update,ENABLE);//初始化时钟结构体 TIM_ClearITPendingBit(TIM4,TIM_IT_Update);//中断标志清除}//超声波模块启动函数void UltrasonicWave_StartMeasure(void){ GPIO_SetBits(GPIOF, GPIO_Pin_9); //拉高pf9电平 delay_us(30);//持续30us GPIO_ResetBits(GPIOF, GPIO_Pin_9); //拉低pf9电平}//测距函数 返回定时器计数值float UltrasonicWave_Measure(void) //{ while(GPIO_ReadInputDataBit(GPIOF,GPIO_Pin_10)==1){ }//echo为高电平时,则等待至低电平,才启动超声波 UltrasonicWave_StartMeasure(); //启动超声波 while(GPIO_ReadInputDataBit(GPIOF,GPIO_Pin_10) == 0)//等待echo的高电平到来 { delay_us(20);//持续20us} TIM_SetCounter(TIM4,0); //清零计数器 TIM_Cmd(TIM4, ENABLE); //使能定时器2,开始计数 while(GPIO_ReadInputDataBit(GPIOF,GPIO_Pin_10) == 1)//等待echo的高电平结束{} TIM_Cmd(TIM4, DISABLE); //失能定时器4,截止计数 return (TIM_GetCounter(TIM4)); //返回定时计数器的计数值} main函数中的代码
# include "system.h"# include "beep.h"# include "SysTick.h"# include "usart.h"# include "ultr.h"int main(){ int distance;//距离 ultr_Init();//初始化超声波 USART1_Init(9600);//初始化串口 SysTick_Init(168);//初始化时钟 BEEP_Init();//蜂鸣器初始化 while(1) { distance=0;//初始化距离参数为零 distance = (int)UltrasonicWave_Measure(); //调用测距函数完成测距 delay_ms(60);//建议测量周期为 60ms以上, 以防止发射信号对回响信号的影响。 printf("距离为:%dn",distance);//打印到串口 //判断距离来控制蜂鸣器的开关 if(distance<1041)//距离小于0.5m { beep=0;//蜂鸣器持续开启 }else if(distance>1047&&distance<3249)//距离大于0.5米小于1.5米 { beep=!beep; //蜂鸣器间断开启 }else if(distance>3249)//距离大于1.5米 { beep=1;//关闭蜂鸣器 } } } 结尾
以上就是关于超声波模块的全部内容了。由于项目里不需要实时精确的测量具体距离,只需要测量定点距离计数器的值,用来控制蜂鸣器即可。所以得到计数器的值以后我没有再去计算出具体的距离。
所有内容全部面向新手,觉得有用的点赞鼓励一下,如果还是不会用的同学请在下方留言。需要源码工程的也可以私信我。
后续的智能车库系统项目里还会涉及到步进电机和红外遥控的使用,需要教程关注一下,后续我会再写,谢谢观看。
举报