前言
本文章介绍了基于STM32F103的HAL库,完成对HC_SR04超声波模块测距的基本思路和工程案例。
环境
- STM32F103C6T6系统板,72MHz主频
- 基于STM32CubeMX生成的HAL库代码
- 硬件连接:
- PB12 — Echo(HC_SR04),PB13 — Trig(HC_SR04)
- PB9 — SDA(OLED),PB8 — SCL(OLED)
- HC_SR04模块供电一般3.3V~5V行
思路
外设配置,配置tim2分频后为1us状态,PB12配置为上升沿中断模式,且使能引脚中断的NVIC管理,PB13,PB9,PB8配置为输出模式。
总体思路,通过在PB13连接的HC_SR04的Trig引脚发出高电平脉冲后,等待一些时间后,声波返回,通过PB12连接的Echo引脚的外部中断(上升沿模式),进入外部中断事件后,在重置定时器的计数值为0后,开启定时器,判断下降沿的到来,到来后则停止定时器计数,然后获取计数值,通过运算后得到距离值。
流程
-
去RCC使能使用外部高速晶振,在去时钟配置中,将主频提到72MHz。
-
配置tim2分频后为1us状态,也就是计数器每加1,相当与过了1us(主频72M/72=1000000,每秒计数)。计数周期给到最大。
-
PB12引脚配置,左图找到引脚左键选择GPIO_EXTI模式,然后配置GPIO mode为上升沿触发模式,然后记得在NVIC中使能线路中断。
-
其余三个GPIO引脚默认输出模式即可。
代码
-
代码方面除了上述配置生成的,还导入OLED(IIC)的库,和编写的HC_SR04的库,反正没几行我就直接粘贴出来了。我在计算距离时用了整型来获得结果,想要提高精度的话可以改成浮点型的。
-
HC_SR04库代码
HC_SR04.h
#ifndef __HC_SR04_H__ #define __HC_SR04_H__ void HCSR04_Trigger(void); void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin); unsigned int HCSR04_ReValue(void); #endif
HC_SR04.c
#include "main.h" #include "tim.h" #include "gpio.h" /** * @描述:使用HC_SR04测量距离。 * @前置:在STM32CubeMX上完成tim2,gpio13,12的相关配置。 * tim2,完成定时器2的主频/分频系数=1us,配置好PB12,PB13的相关模式。 */ unsigned int Value=0; unsigned int Length=0; /** * @描述:触发函数,给予一定时间的高电平脉冲 * @返回:无 */ void HCSR04_Trigger(void) { //触发引脚 HAL_GPIO_WritePin(GPIOB, GPIO_PIN_13, GPIO_PIN_SET); //理论有10us间隔,我这里没加 HAL_GPIO_WritePin(GPIOB, GPIO_PIN_13, GPIO_PIN_RESET); } /** * @描述:该函数为,重写引脚外部中断回调函数 * @返回:无 */ void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) { if(GPIO_Pin & GPIO_PIN_12) { //计数返回脉冲长度 __HAL_TIM_SET_COUNTER(&htim2,0); //计数值归零 HAL_TIM_Base_Start(&htim2); while(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_12)); HAL_TIM_Base_Stop(&htim2); Value=__HAL_TIM_GET_COUNTER(&htim2); //获取计数值 //测试距离=(高电平时间*声速(340M/S))/2 Length=(Value*0.034)/2; } } /** * @描述:该函数为,返回 * @返回:计算好的距离整型,单位cm */ unsigned int HCSR04_ReValue(void) { return Length; }
演示
工程
文章演示工程
链接:https://pan.baidu.com/s/16hKY0LDolT0ADzDrfFdf9w 提取码:1xdv