文章目录
前言
本文章主要介绍超声波测距模块HC-SR04的使用方法,并通过CubeMX配置STM32F4来测量距离
一、CubeMX配置
1、打开CubeMX新建工程,选择外部高速时钟并配置时钟树,这里时钟主频选择72Mhz
2、配置模块启动IO口,这里配置PA2为Output模式并下拉
3、配置定时器,打开输入捕获并开启中断,这里使用TIME5
二、代码
1、模块.c文件
#include "hc-sr04.h"
/*
* 采用IO口TRIG触发测距,给至少10us的高电平信号来启动模块
* 模块自动发送8个40khz的方波,自动检测是否有信号返回
* 如果有信号返回,通过IO口ECHO输出一个高电平,高电平持续的时间就是超声波从发射到返回的时间
* 通过公式计算测试距离=(高电平时间*声速(340M/S))/2
*/
RUN_STATE state; //定义状态枚举常量
uint16_t buf[2]={0};//用于捕获CNT值
//读取距离
float read_len(void)
{
static float len;
TRIG_RESET;
if(state == HCSR04_RESET){
TRIG_SET;
HAL_Delay(1);
TRIG_RESET;
__HAL_TIM_SET_CAPTUREPOLARITY(&htim5, TIM_CHANNEL_1,
TIM_INPUTCHANNELPOLARITY_RISING);//设置上升沿捕获
HAL_TIM_IC_Start_IT(&htim5, TIM_CHANNEL_1); //使能输入捕获中断
state = RISING; //设置标志为上升沿,等待高电平
}
if(state == OVER){
len = (float)(buf[1]- buf[0])*0.017f; //定时器每1us计数一次
state = HCSR04_RESET;//状态标志重置
}
return len;
}
//TIME5中断回调函数
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)//定时器捕获到指定电平的回调函数
{
if(TIM5 == htim->Instance){
if(state == RISING){
__HAL_TIM_SET_COUNTER(&htim5,0); //设置CNT值为0
buf[0] = __HAL_TIM_GetCounter(&htim5); //获取当前CNT值
//设置为下降沿捕获
__HAL_TIM_SET_CAPTUREPOLARITY(&htim5,TIM_CHANNEL_1,TIM_ICPOLARITY_FALLING);
state=FALLING;//设置标志为下降沿
}
else if(state == FALLING){
buf[1] = __HAL_TIM_GetCounter(&htim5); //获取下降沿时的CNT值
state=OVER; //设置标志为完成
}
}
}
2、模块.h文件
#ifndef _HCSR04_H
#define _HCSR04_H
#include "tim.h"
#define TRIG_SET HAL_GPIO_WritePin(GPIOA,GPIO_PIN_2,GPIO_PIN_SET);
#define TRIG_RESET HAL_GPIO_WritePin(GPIOA,GPIO_PIN_2,GPIO_PIN_RESET);
extern void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim);
typedef enum run_state
{
HCSR04_RESET=0,
RISING,
FALLING,
OVER
}RUN_STATE;
float read_len(void);
#endif
三、BUG记录
笔者在使用过程中遇到了一个很神奇的bug
在使用stm32f103c8t6的过程中,代码烧录进去后,超声波测得的数据能够通过串口打印出来,然后当稍微修改了一下代码,整体部分没动,比如,加了个没用if语句,其它无用的代码也是这样
然后烧录进去,串口直接不打印输出了,重点来了!!!
这个时候我们将给超声波模块供电的5V引脚拔掉重新插上后,又可以打印输出了。。。
其实之前在国产的CH32上使用超声波也遇到过这种情况,后来也是通过重新上电解决的,具体原因还是不知道,若有大佬知道咋回事,麻烦告知一下了!!万分感谢!
总结
在其它文件里进行调用read_len()函数就能实现你想要进行的操作啦,最后,如有不正确的地方欢迎在评论区里对笔者进行更正。
注:该文章仅用于学习,如有侵权,告知必删