基于STM32的超声波距离检测

在这里插入图片描述这是一个本科课程设计,涉及单片机硬件和软件,适合初学Stm32自己独立完成的一个小项目。

  1. 功能

    使用STM32F103C8T6做主控,连接超声波传感器、蓝牙模块、0.96寸OLED、蜂鸣器等模块,实现一定距离的测量,设计报警距离范围,满足报警条件后,蜂鸣器报警。报警距离可调,蜂鸣器报警可以选择开启或者关闭,OLED屏可以选择开启或者熄灭。

2.函数
main.c
主函数

#include "LED.h"
#include "usart.h"	  
#include "hcsr04.h"
#include "oled_2.h"
#include "beep.h"
/****************************************************
*引脚:OLED    SCLK  PB6            SDA   PB7       
*     超声波   TRIG  PB11           ECHO  PB10          
*     蓝牙串口 TX    PA9            RX    PA10
*     蜂鸣器   BEEP  PB12
****************************************************/
extern float  LEN=20;
extern float  ReportDistence=20;
extern char   BeepCmd;
void BeepOn_Off(void);
int main()
{  
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);  //中断优先级分组 分2组
    OLED_Init();
    delay_init();
    uart_init(9600);
    BEEP_Init();
    Hcsr04Init();
    Map1();
    while(1)
    {
      
      OLED_Showdecimal(60,3,LEN,3,1,16);
      //BeepOn_Off();
      
      printf("%f",LEN);
      delay_ms(1000);  
    }
}

void BeepOn_Off(void)
{
    if(BeepCmd==1)
    {
      if(LEN<ReportDistence)
          TIM_Cmd(TIM2, ENABLE); 
      else
      {
          TIM_Cmd(TIM2, DISABLE); 
          BEEP=0;
      }
    }
}

hcsr04.c
超声波模块

#include "hcsr04.h"
extern float  LEN;
//超声波计数
u16 msHcCount = 0;


//IO口初始化 及其他初始化
void Hcsr04Init()
{  
      
    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);    
     
      
    TIM3_Int_Init(1000-1,72-1);//定时器1000*(1/10^6)=1ms
    TIM4_Int_Init(3000-1,7200-1);//0.1s
}

//打开定时器3
static void OpenTimerForHc()  
{
   TIM_SetCounter(TIM3,0);
   msHcCount = 0;
   TIM_Cmd(TIM3, ENABLE); 
}


//关闭定时器3
static void CloseTimerForHc()    
{
   TIM_Cmd(TIM3, DISABLE); 
}


//定时器3终中断
//1ms计数器+1
void TIM3_IRQHandler(void)  
{
   if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET)  
   {
       TIM_ClearITPendingBit(TIM3, TIM_IT_Update); 
       msHcCount++;
   }
}
void TIM4_IRQHandler()
{
	if(TIM_GetITStatus(TIM4 , TIM_IT_Update) != RESET) //检查指定的TIM4中断发生与否:TIM 中断源 
	{
		TIM_ClearITPendingBit(TIM4 , TIM_IT_Update  );  //清除TIM4的中断待处理位:TIM 中断源 
		LEN= Hcsr04GetLength();
        BeepOn_Off();
	}
} 


//获取定时器3计数器总的值
u32 GetEchoTimer(void)
{
   u32 t = 0;
   t = msHcCount*1000;
   t += TIM_GetCounter(TIM3);
   TIM3->CNT = 0;  
   delay_ms(50);
   return t;
}
 
//通过定时器3计数器值推算距离
float Hcsr04GetLength(void)
{
   u32 t = 0;
   int i = 0;
   float lengthTemp = 0;
   float sum = 0;
   while(i!=5)
   {
      Trig_H;      
      delay_us(20);
      Trig_L;
      while(ECHO_Reci == 0);      
      OpenTimerForHc();        
      i = i + 1;
      while(ECHO_Reci == 1);
      CloseTimerForHc();        
      t = GetEchoTimer();        
      lengthTemp = ((float)t/58.8);//cm  (t/10^6)*(340/2)*100
      sum = lengthTemp + sum ;
    }
    lengthTemp = sum/5.0;
    return lengthTemp;
}

超声波模块头文件
hcsr04.h

#ifndef __HCSR04_H
#define __HCSR04_H
#include "sys.h"
#include "delay.h"
#include "time.h"
#include "timer.h"
#include "usart.h"
/***************************
*使用定时器3
*TRIG B11
*ECHO B10
***************************/
#define HCSR04_PORT     GPIOB
#define HCSR04_CLK      RCC_APB2Periph_GPIOB
#define HCSR04_TRIG     GPIO_Pin_11
#define HCSR04_ECHO     GPIO_Pin_12

#define Trig_H  GPIO_SetBits(GPIOB, GPIO_Pin_11)
#define Trig_L  GPIO_ResetBits(GPIOB, GPIO_Pin_11)
#define ECHO_Reci GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_12)


float Hcsr04GetLength(void);
void Hcsr04Init(void);
#endif

串口中断服务函数

	if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)  /*返回值是 SET,说明是串口发送完成中断生。
                                                            函数返回值为SET或RESET,
                                                            即还能判断是否发生了中断。*/    
     {             
         Res= USART_ReceiveData(USART1); 	 
         USART_SendData(USART1,Res);  	
         if(Res=='2')
            ReportDistence+=1;
         if(Res=='8')
            ReportDistence-=1;
         OLED_Float(0,66,ReportDistence,1); 
         if(Res=='1')
             {
                 if(flag1)
                    OLED_Display_Off();
                 else
                     OLED_Display_On();
                 flag1=!flag1;
             }
         if(Res=='4')
             {
                 if(flag2)
                 {
                    OLED_ShowCHinese16x16(70,6,7,ziku); 
                    //TIM_Cmd(TIM2, DISABLE); 
                     BeepCmd=0;
                     BEEP=0;
                     
                 }
                 else
                 {
                    OLED_ShowCHinese16x16(70,6,6,ziku); 
                    //TIM_Cmd(TIM2, ENABLE); 
                    BeepCmd=1;
                 }
                 flag2=!flag2;
             }    
                 
     } 
  1. 现象

    测量距离显示在OLED屏上,同时通过蓝牙发送到手机上。手机端可以修改报警距离,可以使能是否需要报警。
    在这里插入图片描述
    PCB有源文件
    在这里插入图片描述

工程源文件和pcb源文件当然直接拿,当然点个关注更好咯
链接:https://pan.baidu.com/s/1Ih9DljKzPnPdFHgIIh9G-w?pwd=ohn0 
提取码:ohn0
  • 1
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值