STM32传感器外设集详解:超声波模块(HC-SR04)

目录

1.器件介绍

1.1.参数

1.2.测量范围

1.3.计算公式

1.4.优点

2.1.原理

3.代码编写

3.1.接线图

3.2.代码

3.2.1.HC_SR04.h

3.2.2.HC_SR04.c

3.2.3.timer.h

3.2.4.timer.c

 3.2.5.main.c


1.器件介绍

1.1.参数

  • 5根引脚
  • 工作电压5v
  • 工作电流15mA
  • 工作频率40Hz
  • 1.2.测量范围

  • 最近距离 2cm
  • 最远距离 4m
  • 测量角度 15度
  • 1.3.计算公式

    测试距离=(高电平时间*声速(340M/S))/2

    1.4.优点

  • 性能稳定
  • 测度距离精确
  • 模块高精度
  • 盲区小
  • 易于使用
  • 2.使用原理

    2.1.原理

    使用stm32的定时器测量反射波的返回时间,再根据计算公式求出物体的相对距离,

    3.代码编写

    3.1.接线图

    3.2.代码

    3.2.1.HC_SR04.h

    #ifndef __HC_SR04_H
    #define __HC_SR04_H	 
    #include "sys.h"
    
    
    #define SR04_Trlg PBout(12)// PB12
    #define SR04_Echo PBin(13)// PB13	
    
    void HC_SR04_IO_Init(void);
    u16  Get_SR04_Distance(void);
    
    
    
    	 				    
    #endif
    

    3.2.2.HC_SR04.c

    #include "HC_SR04.h"
    #include "timer.h"
    #include "delay.h"
    
    //	 
    
    void HC_SR04_IO_Init(void)
    {
     
     GPIO_InitTypeDef  GPIO_InitStructure;
     	
     RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);	 //使能PB端口时钟
    	
     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;				 // 端口配置
     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; 		 //推挽输出
     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;		 //IO口速度为50MHz
     GPIO_Init(GPIOB, &GPIO_InitStructure);					 //根据设定参数初始化GPIOB.12
    	
     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;				 // 端口配置
     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 		
     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;		 //IO口速度为50MHz
     GPIO_Init(GPIOB, &GPIO_InitStructure);					 //根据设定参数初始化GPIOB.13
    	
    }
    
    u16 TIM2_UPDATA = 0;
    u32 temp = 0;
    u16  Get_SR04_Distance(void)
    {
    
       SR04_Trlg=1;       //触发信号是高电平脉冲,宽度大于10us
       delay_us(20);
       SR04_Trlg=0;
       while(!SR04_Echo); //等待高电平
    	 TIM_SetCounter(TIM2,0);  //重填计数器值
    	 TIM2_UPDATA = 0;         //溢出次数清零
       while(SR04_Echo);  //等待低电平
    	 TIM_Cmd(TIM2,DISABLE);  //暂时关闭定时器,保证数据正确性
       temp = (int)(((double)(TIM_GetCounter(TIM2) + (7200* TIM2_UPDATA)))/72/2);  //得到高电平总时间,单位us(定时器的计数值加上溢出的值才是高电平的时间),除以2是计算单程的时间
    	 //(7200* TIM2_UPDATA这里为溢出的时间us,可以转换为100* TIM2_UPDATA,因为在公式后面除以了72。可最终理解为TIM2_UPDATA个100us)
    	 TIM_Cmd(TIM2,ENABLE);
    	 return temp;
    }
     
    
    
    

    3.2.3.timer.h

    #ifndef __TIMER_H
    #define __TIMER_H
    #include "sys.h"
    
    
    void TIM2_Init(u16 arr,u16 psc);
    
    #endif
    

    3.2.4.timer.c

    #include "timer.h"
    #include "delay.h"
    #include "sys.h"
    
    
    void TIM2_Init(u16 arr,u16 psc)
    {	 
    	TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
      NVIC_InitTypeDef NVIC_InitStructure;
    
    	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);	//使能TIM2时钟
    	
    	//初始化定时器2	 
    	TIM_TimeBaseStructure.TIM_Period = arr; //设定计数器自动重装值 
    	TIM_TimeBaseStructure.TIM_Prescaler =psc; 	//预分频器   
    	TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //设置时钟分割:TDTS = Tck_tim
    	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数模式
    	TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位
      
    
    	
    	//中断分组初始化
    	NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;  //TIM3中断
    	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3;  //先占优先级2级
    	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;  //从优先级0级
    	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
    	NVIC_Init(&NVIC_InitStructure);  //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器 
    	
    	TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);//允许更新中断 ,
    	
      TIM_Cmd(TIM2,ENABLE ); 	//使能定时器2
    
    }
    //定时器2中断服务程序	               主要记录溢出次数
    
    extern u16 TIM2_UPDATA;
    extern u8 state_machine;
    void TIM2_IRQHandler(void)
    { 
    				if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET) //检查指定的TIM中断发生与否:TIM 中断源 
    				{
    					  TIM2_UPDATA++;//当回响信号很长时,记录溢出次数,每加一次代表加100us
    						TIM_ClearITPendingBit(TIM2, TIM_IT_Update); //清除中断标志位
    			  }
    }
    

     3.2.5.main.c

    int main(void)
    {
    
    	u16 time=0;
        delay_init();	    //延时函数初始化
    	 uart_init(115200);
        HC_SR04_IO_Init();  //超声波模块GPIO初始化
        delay_ms(500);       //上电瞬间加入一定延时在初始化
        TIM2_Init(7199,0);    //以10KHz计数,定时100us
    		HC05_Role_Show();
    		delay_ms(100);	
        while(1)
        {
    			time++ ;
    
    				Distance = (Get_SR04_Distance() * 331) * 1.0/1000;   //Get_SR04_Distance()返回单程声波传输时间 us,转换为秒=时间*10^(-6);331m/s等于331000mm/s,
    			 //最终换算为Distance =Get_SR04_Distance()*10^(-6)*331000=(Get_SR04_Distance() * 331) * 1.0/1000;
    			
    			 delay_ms(10);
    			 if(time==300) {
    				 printf("%.1f\n",Distance);
    				 HC05_Sta_Show();
    				 time=0;
    			 }	
    
        }
        
    }
    物联沃分享整理
    物联沃-IOTWORD物联网 » STM32传感器外设集详解:超声波模块(HC-SR04)

    发表评论