STM32 | HC-SR04 超声波传感器测距

模块:HC-SR04

感应角度:不大于15度

探测距离:2cm-450cm

高精度:可达0.3cm

Trig: 触发信号,接收MCU发送的控制脉冲,MCU对应GPIO 设置为输出

Echo: 反馈信号,向MCU发送数据脉冲, MCU对应GPIO 设置为输入

VCC:3.3V~5V

超声波测距原理:

  1. 超声波发射装置向某一方向发出超声波,并开始计时
  2. 超声波在空气中传播,途中碰到障碍物就立即返回来
  3. 接收器接收到超声波的时间差,就停止计时
  4. 根据超声波在空气中传播速度(340m/s),再根据计时器记录的时间t,可以算出距离(s)

似乎有多种模式,本文只使用GPIO模式:

单片机操作步骤:

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

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

(3)有信号返回, 超声波模块通过ECHO引脚输出一个高电平(ECHO输出的高电平持续时间,就是处理的结果), 高电平持续的时间就是超声波从发射到返回的时间。

代码

UltraSonic_Init()

  1. 配置 GPIOG 的 14 脚为 Trig 输出,15 脚为 Echo 输入
  2. 配置 TIM4 定时器为 1MHz 计数频率 (1us / 计数)
  3. 设置最大测量时间为 50ms (50000 计数)
cpp 复制代码
void UltraSonic_Init(void)
{
    GPIO_InitTypeDef  GPIO_InitStructure;
    TIM_TimeBaseInitTypeDef  	TIM_TimeBaseInitStruct;

    // UlatrSonic-->PG14,PG15
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOG, ENABLE);	 //使能PG端口时钟
        
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14;               // Trig
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 		 //推挽输出
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;		 //IO口速度为50MHz
    GPIO_Init(GPIOG, &GPIO_InitStructure);					 //根据设定参数初始化

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15;	    		 // Echo
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;            //设置成上拉输入
    GPIO_Init(GPIOG, &GPIO_InitStructure);	  				 //推挽输出 ,IO口速度为50MHz



    // 设置一个定时器,1us计数1个数,不用中断,且开始时不使能定时器
    //1、能定时器时钟。
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4,ENABLE);

    TIM_TimeBaseInitStruct.TIM_Prescaler	= 84-1;	            //84MHZ/8400 = 10000HZ  Prescaler范围1~65536 
    TIM_TimeBaseInitStruct.TIM_Period		= 50000-1;		    //在10000HZ时钟频率下,用时1ms 自动重装载寄存器值
    TIM_TimeBaseInitStruct.TIM_CounterMode	= TIM_CounterMode_Up;//向上计数
    TIM_TimeBaseInitStruct.TIM_ClockDivision= TIM_CKD_DIV1;  	 //分频因子
    //2、初始化定时器
    TIM_TimeBaseInit(TIM4,&TIM_TimeBaseInitStruct);

    //【不使能定时器】
    TIM_Cmd(TIM4, DISABLE);
}

UltraSonic_GetDistance()

  1. 发送 15us 的高电平触发信号,然后拉低引脚
  2. 等待模块返回的 Echo 信号(高电平)
  3. 高电平来了,开始定时器计时,目的是测量 Echo 高电平持续时间
  4. 低电平来了,停止定时器计时,得到 Echo 高电平持续时间
  5. 根据超声波在空气中的传播速度 (340m/s) 计算距离
cpp 复制代码
float UltraSonic_GetDistance()
{
    float distance_cm = 0;
    u32 time_us = 0;
    //**************************************
    //启动超声波模块 也就是要发送启动信号
    GPIO_ResetBits(GPIOG, GPIO_Pin_14);
    delay_us(5);

    //高电平需要10us以上---【启动信号】
    GPIO_SetBits(GPIOG, GPIO_Pin_14);
    delay_us(15);
    GPIO_ResetBits(GPIOG, GPIO_Pin_14);
    
    //*********************************
    //设置定时器的CNT值为0,设置初值
    TIM_SetCounter(TIM4,0);

    //等待ECHO的高电平到来
    while(GPIO_ReadInputDataBit(GPIOG, GPIO_Pin_15)==Bit_RESET);

    //**************************
    //【高电平来了】-------启动定时器
    TIM_Cmd(TIM4,ENABLE);
    
    //等待ECHO的低电平到来
    while(GPIO_ReadInputDataBit(GPIOG, GPIO_Pin_15)==Bit_SET);

    //****************************
    //【低电平来了】------读时间数据,关定时器
    //取出CNT的值-----定时器的当前值
    time_us = TIM_GetCounter(TIM4);    // 微秒 (μs)。
    //关闭定时器
    TIM_Cmd(TIM4, DISABLE);
    
    //**************************************
    //【通过公式】: 
    // distance (m) * 2 = time * 10(-6) * 340m/s
    // distance (m)     = time * 10(-6) * 340m/s / 2
    // distance (cm)    = time * 10(-6) * 340m/s / 2 * 100 = time * 10(-3) * 17
    distance_cm = time_us * 0.017;   // distance = time / 58;

    return distance_cm;
}

调用程序:

cpp 复制代码
void ULTRA_SONIC_task(void *pvParameters)
{
	float distance_cm = 0;
	
	while(1)
	{
		printf("ULTRA_SONIC_task \r\n");
		distance_cm = UltraSonic_GetDistance();
		printf("distance = %f  (cm) \r\n",distance_cm);
		delay_ms(3000);
	}
}

输出结果:

相关推荐
蜡笔小电芯1 小时前
【STM32】const 变量存储学习笔记
笔记·stm32·学习
几个几个n6 小时前
STM32-第五节-TIM定时器-1(定时器中断)
stm32·单片机·嵌入式硬件
EutoCool7 小时前
Qt窗口:QToolBar、QStatusBar、QDockWidget、QDialog
开发语言·数据库·c++·嵌入式硬件·qt·前端框架
国科安芯8 小时前
车规级ASM1042芯片在汽车无线充电模块中的应用探索
人工智能·单片机·嵌入式硬件·物联网·安全·汽车
学不动CV了10 小时前
深入理解C语言内存空间、函数指针(三)(重点是函数指针)
c语言·arm开发·数据库·stm32·单片机·嵌入式硬件·c#
学不动CV了19 小时前
C语言32个关键字
c语言·开发语言·arm开发·单片机·算法
姜暮儿19 小时前
U盘直接拔出不在电脑上弹出有何影响
stm32·单片机·嵌入式硬件
O。o.尊都假都21 小时前
STM32之LVGL移植
stm32·单片机·嵌入式硬件·freertos·lvgl
学不动CV了21 小时前
ARM单片机OTA解析(一)
c语言·arm开发·stm32·单片机·嵌入式硬件·51单片机