STM32
直播中

张玉兰

7年用户 1299经验值
私信 关注
[问答]

怎样去设计一种基于HC-SR04模块的智能车库控制系统

如何利用超声波测距来实现智能车报警的功能呢?
怎样去设计一种基于HC-SR04模块的智能车库控制系统?

回帖(1)

张健

2021-10-18 11:44:42
  需要做一个智能车库控制系统的小项目,第一个要完成的就是利用超声波测距来实现报警的功能。本人嵌入式初级学徒,以尽量简单详细的方式,为大家介绍。
  设备
  1、超声波测距使用的是HC-SR04
  2、开发板是普中科技的PZ6808L-F4 (stm32F407ZG芯片)
  超声波模块详细介绍
  1、管脚
  首先看看HC-SR04的四个管脚
  VCC:接5V电源
  Trig:触发信号输入
  Echo:回响信号接收
  GND:接地
  2、原理
  超声波模块触发以后,会向前发射超声波脉冲,超声波脉冲在碰撞到物体以后会反射回来,模块接收到反射信号以后就完成一次测距。计算这个发射到接收的时间,计算这个时间与超声波传播速度的关系,就可以得到距离。
  
  3、驱动步骤
  利用stm32给Trig管脚一个超过10us的高电平以后,模块会自动发出脉冲信号,发出信号的同时Echo管脚会持续输出高电平。这个时候利用stm32定时器的计数功能,开始计算Echo管脚为高电平的时间。模块接收到返回的超声波信号以后。Echo输出的高电平结束。定时器停止计数。这时候对定时器的值稍加处理,就可以得到准确的距离了。
  
  具体代码实现
  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;//关闭蜂鸣器                        }                        }        }    结尾
  以上就是关于超声波模块的全部内容了。由于项目里不需要实时精确的测量具体距离,只需要测量定点距离计数器的值,用来控制蜂鸣器即可。所以得到计数器的值以后我没有再去计算出具体的距离。
  所有内容全部面向新手,觉得有用的点赞鼓励一下,如果还是不会用的同学请在下方留言。需要源码工程的也可以私信我。
  后续的智能车库系统项目里还会涉及到步进电机和红外遥控的使用,需要教程关注一下,后续我会再写,谢谢观看。
举报

更多回帖

发帖
×
20
完善资料,
赚取积分