STM32--超声波模块(HC—SR04)(标准库+HAL库)

一、HC-SR04工作原理

1)采用IO触发测距,给至少10us的高电平信号。

2)模块自动发送8个40KHz的方波,自动检测是否有信号返回。

3)有信号返回,通过IO输出一高电平,高电平持续时间就是超声波从发射到返回的时间声波从发

射到返回的时间。

4)HC-SR04超声波测距模块提供2cm~400cm的测距功能,精度达3mm。

二、实物介绍

以下图片截取自深圳市捷深科技有限公司的《HC-SR04超声波测距模块说明书》:

VCC 3.3-5V供电(推荐5V供电)

GND 接地

Trig 外部触发信号输入,输入一个高于10μs的高电平即可触发模块测距

Echo回响信号输出,测距结束时此管脚输出一个低电平,电平宽度反映超声波往返时间之和

三、工作说明

1、触发信号Trig直接通过IO输出和延时给一个大于10us的高电平即可触发。

2、Echo引脚需要接收并记录高电平的持续时间。

3、在发送触发信号后,Echo响应后(上升沿)触发外部中断,开启定时器计时直到Echo变为低电

平,关闭定时器记录下计时时间。

4、实际应用,如果需要精确距离值,必需要考虑温度影响,做温度补偿。

distance = time * 0.017

距离=T*C/2(C 为声速)

声速温度公式:c=(330.45+0.61t/℃)m/s-1 (其中330.45是在0℃)

0℃声速:330.45m/s20℃声速:342. 62m/s40℃声速:354.85M/S

四、标准库工作代码

我一般使用标准库较少,使用代码时请注意检查

使用OLED显示,OLED使用可以看:

STM32--SPI&IIC使用OLED-CSDN博客

uint32_t distance;
while(1)
{
   distance = 0;
   for(int i=0;i<10;++i)
   {  //每次取10次测距数据,取平均值减少误差
      GPIO_SetBits(GPIOA,GPIO_Pin_6);
      Delay_us(15);               //需要提供至少10us的高电平
      GPIO_ResetBits(GPIOA,GPIO_Pin_6);
      Delay_ms(70);              //每个周期至少需要等待60ms
      distance+=(times/5.8);     //获取单位为mm的距离
   }
   distance/=10;
   OLED_ShowNum(2,1,distance,4);    //使用OLED显示
}

//定时器中断函数
//72MHz/72/100=1000,每秒定时器计数1000个,因此每个计数为100us
void TIM2_IRQHandler(void)
{
   if(SET==TIM_GetITStatus(TIM2,TIM_FLAG_Update))
   {
      number++; //每次中断将次数++
      TIM_ClearITPendingBit(TIM2,TIM_FLAG_Update);
   }
}
 
//外部中断函数,利用外部中断检测高低电平变化来控制定时器开关
void EXTI9_5_IRQHandler(void)
{
   if(SET==EXTI_GetITStatus(EXTI_Line7))
   {
      if(flag==0)
      {	
         //上升沿即回响电平开始,打开计数器
         number=0;flag=1;
         TIM_SetCounter(TIM2,0);
         TIM_Cmd(TIM2,ENABLE);
      }
      else
      {	
         //下降沿即回响电平结束,统计高电平持续时长
         TIM_Cmd(TIM2,DISABLE);
         flag=0;
         times=number*100+TIM_GetCounter(TIM2);  //得到回响的高电平持续的us
      }
      EXTI_ClearITPendingBit(EXTI_Line7);
   }
}

五(1)、HAL--CubeMX配置

GPIO配置(Trig端口):设置PA1为触发端(可更改为其他GPIO口)。单击芯片的PA1引脚会跳

出选择项,选择GPIO_Output,即为GPIO输出。

****定时器配置(Echo端口)********:****为方便计算定时器的分频系数和定时周期,将APB1设置为50MHz。

先设置TIM2的通道1位直接模式输入捕获,在参数设置中设置预分频为71,通过计算分频器输出的

时钟信号频率为1000kHz,通过换算得到1us,极性为上升沿触发。设置完成后自动引出PA0引

脚,即为接收端引脚Echo,使能NVIC中断。

USART1配置:串口输出显示结果,设置为异步模式,波特率为115200Bits/s,

RX--PA10//TX--PA9

五(2)、HAL库工作代码

1、HCSR04.h

#ifndef __HCSR04_H
#define __HCSR04_H

#include "main.h"
//#include "tim.h"
#include "stdio.h"
 
#define TRIG_H  HAL_GPIO_WritePin(Trig_GPIO_Port,Trig_Pin,GPIO_PIN_SET)
#define TRIG_L  HAL_GPIO_WritePin(Trig_GPIO_Port,Trig_Pin,GPIO_PIN_RESET)
 
void delay_us(uint32_t us);
void HCSR04_GetData(void);
 
#endif

2、HCSR04.c

#include "HCSR04.h"
 
float distance;      //测量距离
uint32_t Buf[3] = {0};   //存放定时器计数值的数组
uint8_t  Cnt = 0;    //状态标志位
uint32_t high_time;   //超声波模块返回的高电平时间

//读取距离
void HCSR04_GetData(void)
{
   switch(Cnt)
   {
      case 0:
         TRIG_H;    //发送信号
         delay_us(30);
         TRIG_L;
       
         Cnt++;    //标志位为1
         __HAL_TIM_SET_CAPTUREPOLARITY(&htim2,TIM_CHANNEL_1, TIM_INPUTCHANNELPOLARITY_RISING);
         HAL_TIM_IC_Start_IT(&htim2, TIM_CHANNEL_1);    //开启TIM2    
         //启动输入捕获或者:__HAL_TIM_ENABLE(&htim5);                                                                                    		
      break;
      case 3:
         high_time = Buf[1]- Buf[0];    //计算高电平时间
         printf("
----高电平时间-%d-us----
",high_time);    //串口打印时间						
         distance=(high_time*0.034)/2;  //计算距离单位cm
         printf("
-检测距离为-%.2f-cm-
",distance);         //串口打印距离     
         Cnt = 0;  //清空标志位
         TIM2->CNT=0;     //清空计时器计数
      break;	
	}
}

//中断回调函数
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{
	if(TIM2 == htim->Instance)// 判断触发的中断的定时器为TIM2
	{
		switch(Cnt)
        {
			case 1:
                //获取当前的捕获值
				Buf[0] = HAL_TIM_ReadCapturedValue(&htim2,TIM_CHANNEL_1);
                //设置为下降沿捕获!!!
              __HAL_TIM_SET_CAPTUREPOLARITY(&htim2,TIM_CHANNEL_1,TIM_ICPOLARITY_FALLING);  													
				Cnt++;                                            
			break;              
			case 2:
                //获取当前的捕获值
				Buf[1] = HAL_TIM_ReadCapturedValue(&htim2,TIM_CHANNEL_1);
				HAL_TIM_IC_Stop_IT(&htim2,TIM_CHANNEL_1); 
                //停止捕获或者: __HAL_TIM_DISABLE(&htim5);
				Cnt++;      //此时标志位为3
        break;
		}
	}
}
相关推荐
派阿喵搞电子18 分钟前
STM32的APB1和APB2的区别
stm32·单片机·嵌入式硬件
Archie_IT2 小时前
江协科技/江科大-51单片机入门教程——P[5-1] 模块化编程 & P[5-2] LCD1602调试工具
单片机·嵌入式硬件·mcu·51单片机
电气_空空4 小时前
基于单片机及传感器的机器人设计与实现
单片机·嵌入式硬件·机器人·毕业设计·毕设
木燚垚5 小时前
基于STM32物联网水质监测系统的设计与实现/基于STM32的水产养殖云监控系统设计
stm32·单片机·嵌入式硬件·物联网·智能家居
QQ12971579407 小时前
51单片机 矩阵
单片机·嵌入式硬件·深度学习·算法·硬件工程·集成学习
Moonnnn.7 小时前
51单片机——汇编工程建立、仿真、调试全过程
汇编·笔记·嵌入式硬件·学习·51单片机
森焱森8 小时前
AArch64架构及其编译器
linux·c语言·单片机·架构
想要成为糕手。8 小时前
stm32-RTC时实时钟
stm32·嵌入式硬件·实时音视频
Czzzzlq10 小时前
STM32基础教程——对射式红外传感器计数实验
c语言·stm32·单片机·嵌入式硬件·mcu
集大周杰伦10 小时前
ARM Cortex-M 内存映射详解:如何基于寄存器直接读写 寄存器映射方式编码程序 直接操作硬件寄存器来控制 MCU
arm开发·stm32·单片机·内存映射·arm cortex-m·地址映射·寄存器编码