stm32+超声波测距+蜂鸣器报警或JQ8900模块语音报警

注:文末有完整工程链接(包含引脚连接、代码注释和使用说明),已实测通过,下载打开即用。


前言

本次实验采用的是stm32f103c8t6开发板,是比较基础的一款arm主控芯片;使用超声波传感器HC-SR04来测量距离,当距离小于设定距离时进行报警;报警采用了两种方式,一是无源蜂鸣器,二是JQ8900语音模块,该模块配有小喇叭,可以自行设置报警音(如前方有障碍物/警报,警报/你好,请注意等等),我设置的是“警报,注意安全”。


一、超声波测距

具体的测距程序原理,网上一搜就有,简单来说就是当超声波传感器的Trig引脚拉高大于10us之后触发超声波测距模块,另一个Echo引脚变高电平,随后发出超声波,接收到返回的超声波后Echo引脚再变低电平,因此利用公式:
距离s = 1/2*Echo引脚从高变低的时间t ∗ 声速
来测得距离。大家有兴趣可以查阅资料详细学习,这里直接上程序(注:部分程序注释粘贴后乱码如代码第一段所示,所以这里删去了后面的注释。文末有完整工程,实在想看注释可以下载工程打开查看,两个工程超声波测距部分程序是一样的,下载一个即可)。
HC-SR04传感器,该图片来自淘宝Zave旗舰店产品介绍:
在这里插入图片描述
此模块有四个引脚:VCC接5V或者3.3V(具体接几伏要看你买的传感器介绍),GND接地,Trig和Echo引脚是IO引脚,可以接开发板上对应的GPIO引脚,这里接的是PB11和PB10。

超声波测距程序:

#include "hc.h"
#include "delay.h"
#include "sys.h"
#include "usart.h"	
#include "led.h"
#include "key.h"
#include "beep.h"

//³¬Éù²¨Ó²¼þ½Ó¿Ú¶¨Òå
#define HCSR04_PORT     GPIOB  
#define HCSR04_CLK      RCC_APB2Periph_GPIOB     
#define HCSR04_TRIG     GPIO_Pin_11   //trig½ÓPB11
#define HCSR04_ECHO     GPIO_Pin_10   //echo½ÓPB10

u16 msHcCount = 0;

void hcsr04_NVIC()
{
	NVIC_InitTypeDef NVIC_InitStructure;
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
			
	NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn;             
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;  
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;         
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;       
	NVIC_Init(&NVIC_InitStructure);
}

void Hcsr04Init()
{  
    TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;   
    GPIO_InitTypeDef GPIO_InitStructure;
    RCC_APB2PeriphClockCmd(HCSR04_CLK, ENABLE);
   
    GPIO_InitStructure.GPIO_Pin =HCSR04_TRIG;      
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_Init(HCSR04_PORT, &GPIO_InitStructure);
    GPIO_ResetBits(HCSR04_PORT,HCSR04_TRIG);
     
    GPIO_InitStructure.GPIO_Pin =   HCSR04_ECHO;     
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_Init(HCSR04_PORT, &GPIO_InitStructure);  
    GPIO_ResetBits(HCSR04_PORT,HCSR04_ECHO);    
           
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);   
     
    TIM_DeInit(TIM2);
    TIM_TimeBaseStructure.TIM_Period = (1000-1); 
    TIM_TimeBaseStructure.TIM_Prescaler =(72-1); 
    TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  
    TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure);          
        
    TIM_ClearFlag(TIM4, TIM_FLAG_Update);  
    TIM_ITConfig(TIM4,TIM_IT_Update,ENABLE);    
    hcsr04_NVIC();
    TIM_Cmd(TIM4,DISABLE);     
}

static void OpenTimerForHc()  
{
   TIM_SetCounter(TIM4,0);
   msHcCount = 0;
   TIM_Cmd(TIM4, ENABLE); 
}

static void CloseTimerForHc()    
{
   TIM_Cmd(TIM4, DISABLE); 
}

void TIM4_IRQHandler(void)  
{
   if (TIM_GetITStatus(TIM4, TIM_IT_Update) != RESET)  
   {
       TIM_ClearITPendingBit(TIM4, TIM_IT_Update  ); 
       msHcCount++;
   }
}
 
u32 GetEchoTimer(void)
{
   u32 t = 0;
   t = msHcCount*1000;
   t += TIM_GetCounter(TIM4);
   TIM4->CNT = 0;  
   delay_ms(50);
   return t;
}
 
float Hcsr04GetLength(void )
{
   u32 t = 0;
   int i = 0;
   float lengthTemp = 0;
   float sum = 0;
   while(i!=5)
   {
      TRIG_Send = 1;      
      delay_us(20);
      TRIG_Send = 0;
      while(ECHO_Reci == 0);      
      OpenTimerForHc();        
      i = i + 1;
      while(ECHO_Reci == 1);
      CloseTimerForHc();        
      t = GetEchoTimer();        
      lengthTemp = ((float)t/58.0);   //(1/2)*340*(t/10^6)*100 = t/58 cm 
      sum = lengthTemp + sum ;
        
    }
    lengthTemp = sum/5.0;  
    return lengthTemp;
}

串口距离显示:
在这里插入图片描述

二、短距报警模块

1.使用无源蜂鸣器进行报警

注:对应的文末工程链接1。
这里使用的是无源蜂鸣器,有三个引脚:VCC接5V,GND接地,IO脚接单片机IO脚(本实验接的是PA11)。

蜂鸣器报警对应代码如下:

#include "beep.h"
#include "delay.h"

int melody[] = {50, 50, 50, 50, 200, 200, 200, 400, 400, 500, 500, 500};
 
void BEEP_Init(void)
{ 
 GPIO_InitTypeDef  GPIO_InitStructure; 
 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);   
 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;  
 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 
 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
 GPIO_Init(GPIOA, &GPIO_InitStructure);
 GPIO_ResetBits(GPIOA,GPIO_Pin_11);
    
}

void Sound(u16 frq)
{
    u32 time;
    if(frq != 1000)
    {
        time = 200000/((u32)frq);
        BEEP = 1;
        delay_us(time);
        BEEP = 0;
        delay_us(time);
    }else
        delay_us(1000);
}
void Sound2(u16 time)
{
    BEEP = 1;
    delay_ms(time);
    BEEP = 0;
    delay_ms(time);
}

void play_successful(void)
{
    int id=0;
    for(id = 0 ;id < 12 ;id++)
    {
        Sound2(melody[id]);
    }
}
void play_failed(void)
{
    int id=0;
    for(id = 11 ;id >=0 ;id--)
    {
        Sound2(melody[id]);
    }
}
void play_music(void)
{    
                 
    uc16 tone[] ={250,262,294,330,350,393,441,495,525,589,661,700,786,882,990}; //??        
    u8 music[]={5,5,6,5,8,7,5,5,6,5,9,8,5,5,12,10,8,7,6,11,
                  11,10,8,9,8,5,5,8,5,5,12,10,8,7,6,11,11,10,8,9,8    //????
    };     
        u8 time[] = {1,2,2,2,2,4,1,2,2,2,2,4,1,2,2,2,1,4,
                      4,1,2,2,2,2,4,1,2,4,1,2,2,2,1,4, 4,1,2,2,2,2,4,4        //????
        }; 
                    
    u32 yanshi;
    u16 i,e;
    yanshi = 10;
    for(i=0;i<sizeof(music)/sizeof(music[0]);i++){
        for(e=0;e<((u16)time[i])*tone[music[i]]/yanshi;e++){
            Sound((u32)tone[music[i]]);
        }    
    }
}

2.使用JQ8900语音模块报警

JQ8900有三种通信模式,即两线串口通信方式、一线串口通信方式和IO口按键触发模式,本实验中使用的是一线串口通信方式,因为查阅资料后发现一线串口通信方式程序编写更加简便,因此最后采用这种方式编写了短距语音报警程序,对应文末工程链接2。
JQ8900模块,此图片来自语音产品商城产品介绍:
在这里插入图片描述
JQ8900语音模块:VPP接PB11(这个必须接PB11,因为PB11是SDA口,因为trig也接了PB11,所以我用了一块面包板。当然,也可以改变超声波的连接引脚,trig接PB7,echo接PB6也是可以的,实测过,就是需要改程序里的引脚设置);GND接地,DC接5V,SPK+和SPK-接小喇叭正负极。
在这里插入图片描述

JQ8900模块程序(部分):

#include "oneuart.h"
#include "delay.h"
#include "stm32f10x.h"
 
void OnUart_GPIO(void)
{
	GPIO_InitTypeDef  GPIO_InitStructure;
 
		RCC->APB2ENR|=1<<3;   //GPIOB
		//GPIOB.12
		GPIOB->CRH&=0xFFFF0FFF;     
		GPIOB->CRH|=0x00003000;    
		GPIOB->ODR=~(1<<12);      
}

void SendData ( u8 addr )
{
    u8 i;
    SDA = 1;
    delay_us ( 1000 );
    SDA = 0; 
    delay_us ( 3200 );
    for ( i = 0; i < 8; i++ ) 
    {
        SDA = 1;
			if ( addr & 0x01 ) 
        {
            delay_us ( 600 );
            SDA = 0;
            delay_us ( 200 );
        }
        else             
        {
            delay_us ( 200 );
            SDA = 0;
            delay_us ( 600 );
        }
        addr >>= 1;
    }
    SDA = 1;
    
		
}

void delay_1us(u32 nTimer)
{
	u32 i=0;
	for(i=0;i<nTimer;i++)
	{
		__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
		__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
		__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
		__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
		__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
		
	}	
	}

对应的main.c程序部分:

//²âÊÔÖ÷º¯Êý
int main(void)
 {	 
	 float length;
	 OnUart_GPIO();
	 delay_init();	    	 	  
	 NVIC_Configuration(); 	 
	 uart_init(9600);	 	
	 Hcsr04Init();
	 //printf("´®¿Ú²âÊÔ\r\n");  
   Hcsr04Init();    
   //printf("³¬Éù²¨³õʼ»¯³É¹¦!\n");
   while(1) 
	 {		 
     length = Hcsr04GetLength();
     printf(":%.2fcm\n",length);
		 if(length<10)
		 {
				SendData(0x0a);
				SendData(0x01);
				SendData(0x0b);
				delay_ms(1000);
		 }
		 
		 delay_ms(1000);  

		 
	}			
 }


三、完整工程链接

1.stm32+超声波测距+短距蜂鸣器报警:
https://download.csdn.net/download/m0_52152690/85930149
2.stm32+超声波测距+JQ8900语音报警+小喇叭放大声音
https://download.csdn.net/download/m0_52152690/85930472

  • 15
    点赞
  • 191
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 8
    评论
### 回答1: STM32是一种微控制器,可以用于进行超声波测距,并通过连接蜂鸣器实现报警功能。 超声波测距是利用超声波的特性进行测量距离的技术。STM32可以通过超声波传感器接收到来自物体的回波信号,并计算出物体与传感器之间的距离。通过编程控制,可以设置报警阈值,当测量到的距离超过设定的阈值时,触发蜂鸣器进行报警。 首先,需要连接超声波传感器到STM32的输入引脚,以接收超声波回波信号。然后,编写程序来控制超声波传感器的工作方式,包括发射超声波信号和接收回波信号的时间间隔。 接下来,在程序中设置一个距离阈值,当测量到的距离超过这个阈值时,就触发蜂鸣器报警。可以通过PWM(脉冲宽度调制)信号驱动蜂鸣器,通过调整PWM信号的频率和占空比,可以产生不同的声音和音调。 在程序中,可以加入相关的保护措施,如设置报警延迟时间,避免频繁触发报警和持续响铃。还可以加入其他功能,如显示测量距离的LCD屏幕或LED指示灯。 总之,通过使用STM32微控制器、超声波传感器和蜂鸣器,可以实现超声波测距报警功能,可以广泛应用于安防、自动化控制等领域。同时,根据实际需求,还可以对程序进行优化和扩展,以适应不同场景和应用。 ### 回答2: 在STM32超声波测距中,蜂鸣器报警通常是通过控制STM32的IO口来实现的。 首先,超声波测距模块会通过IO口与STM32连接,将检测到的距离信息传输给STM32。 接着,在编程中,我们可以设置一个阈值,当测得的距离超过这个阈值时,触发蜂鸣器报警功能。通过编程设置IO口的输出,可以给蜂鸣器供电,使其发出声音。 具体实现方式有很多种,以下是一种简单的示例: 1. 首先,初始化超声波测距模块蜂鸣器所用的IO口; 2. 在主循环中,从超声波模块读取当前测得的距离; 3. 判断当前测得的距离是否超过预设的阈值; 4. 如果超过阈值,将蜂鸣器所用IO口输出高电平,使蜂鸣器发出声音; 5. 如果未超过阈值,将蜂鸣器所用IO口输出低电平,关闭蜂鸣器。 通过以上步骤,我们就可以实现当测得的距离超过设定的阈值时,蜂鸣器发出报警声音的功能。这样就可以利用STM32超声波测距模块蜂鸣器实现相应的报警功能。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

莫跖

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值