【Timer】超声波测距
下载例程代码: 下载代码(CubeIDE) 下载代码(keil)
CubeIDE代码请按照 例程使用方法🔗 导入例程,否则下载的可能不是例程而是其他工程。
HC-SR04 超声波模块简介
HC-SR04 工作原理
模块有2个超声波换能器(如图所示),一个发出声波,另一个接收物体反射回来的声波,这中间所经过的时间即声波传播的时间,再结合声速就能计算出:
- 距离 = 声速 * 时间 ÷ 2

如何使用HC-SR04模块
模块具有4个引脚,除了电源外,有TRIG、ECHO两个引脚需要操作:
-
首先,向TRIG引脚发送一个高电平脉冲,来触发模块输出声波
-
记录ECHO引脚输出高电平的时间,即声波的飞行时间
-
距离 = 声速(340m/s) * 声波的飞行时间 ÷ 2

更多资料请查看 资料包 -> 配套模块资料 -> 超声波测距HC-SR04-P
如何使用例程
下载程序,并连接硬件,即可看到效果
硬件连接
- 使用配套TYPE-C数据线,将学习板连接到计算机

-
需要使用:4P杜邦线、超声波模块
-
连接模块时请核对好线序:
| 循迹模块 | 学习板 |
|---|---|
| VCC | VCC |
| TRIG | A11 |
| ECHO | A10 |
| GND | GND |

程序效果
- 直接观察oled即可看到测距结果

-
打开 波特律动 串口助手 (baud-dance.com) 在线串口调试助手,点击“选择串口”,选择USB Single Serial
-
将超声波模块对准一个平面(量程 2 - 400 cm),可以在串口助手看到测距结果

例程讲解
下面介绍了如何自己实现该例程的功能
1、工程配置
- 开启外部晶振:在Pinout&Configuration -> System Core -> RCC 页面,将 High Speed Clock (HSE) 配置为 Crystal/Ceramic Resonator

- 配置时钟频率:在Clock Configuration 页面,将PLL Source 选择为 HSE,将System Clock Mux 选择为 PLLCLK,然后在HCLK (MHz) 输入72并回车,将HCLK频率配置为 72 MHz

-
分配引脚:在Pinout&Configuration页面,将PA11、PA10分别配置为GPIO_Output、TIM1_CH3,并将PA11命名为TRIG
-
配置TIM1:在Pinout&Configuration -> Timers -> TIM1
-
Mode -> Clock Source 设为 Internal Clock,Channel3 设为 Input Capture direct mode,即输入捕获
-
Configuration -> Parameter Settings -> Counter Settings -> Prescaler 设为 72-1,使定时器计数周期刚好为 1 us
-
(可选)开启输入滤波,以提高稳定性:Configuration -> Parameter Settings -> Input Capture Channel 3 -> Input Filter,填写范围0 - 15,数值越大,滤波效果越强
-
Configuration -> NVIC Settings -> 勾选TIM1 capture compare interrupt,开启捕获中断
-

-
打开I²C外设:Pinout&Configuration -> Connectivity -> I2C1,将I2C模式选择为I2C
-
打开串口2外设:Pinout&Configuration -> Connectivity -> USART2,将Mode选择为Asynchronous
-
启用float打印:在cubeIDE菜单栏中,Project Properties -> C/C++ Build -> Settings -> Tool Settings -> MCU Settings,勾选Use float with printf ... -nano
默认情况下,sprintf 函数不能打印小数。因此我们需要配置一下编译器,使其能够打印小数
2、代码
-
引用头文件
- 因为需要打印输出变量,所以应该引用几个头文件:
#include "stdio.h"
#include "string.h"
#include "oled.h" -
定义变量
uint8_t echo_flag = 0; // 捕获标志位
uint16_t rising_cnt = 0, falling_cnt = 0; // 上升沿、下降沿数值
char buf_uart[32] = {0}; // 串口发送字符串
char buf_oled[30] = {0}; // oled显示字符串 -
初始化oled
HAL_Delay(20);
OLED_Init();