纯操作教程,最大限度保证代码上手容易度,伸手党福音(记得给个赞)
1.配置GPIO引脚
打开CubeMX,每个模块要配置两个GPIO,一个输出脚接Trig,一个输入脚接Echo,有几个超声波模块就配几对脚,我这里PE2和PD2给第一个模块用,PE3和PD3给第二个用。(参数和选项全部保持默认)
2.配置定时器
随便挑一个TIM,把预分频系数设为71,其它的保持默认。因为只需要计时所以尽量选低端的基本定时器,别浪费通用定时器和高级定时器。
不过考虑到屏幕前的你可能用的是经典F103C8T6,没有基本定时器,这里用通用定时器TIM2来演示。
3.上面两步配置好了点generate code生成就好。
4.上驱动代码
HC-SR04++.c
/*■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■*/
//HC-SR04的HAL库驱动代码
/*■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■*/
//支持接多个超声波模块
//无论接了几个,调用一次函数就可以直接取得指定模块的读数
//每个模块要接两个GPIO,要配置一个接Trig的输出脚和一个接Echo的输入脚
//同时需要一个配置一个只负责计时的定时器,预分频设成71就行
//自己在CubeMX里配好
/*■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■*/
//by 枞树菌
/*■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■*/
#include <HC-SR04++.h>
#define SR04_TIM &htim6//这里改成你配的定时器
/***基于系统时钟的微秒级延时***/
void SR04_RCC_Delay_us(uint32_t us)
{
uint32_t delay = (HAL_RCC_GetHCLKFreq() / 4000000 * us);
while(delay>0)
{
delay--;
}
}
/***从某一超声波模块中读取数据***/
float SR04_GetData(GPIO_TypeDef* Trig_GPIO,uint16_t Trig_PIN,GPIO_TypeDef* Echo_GPIO,uint16_t Echo_PIN)
{
/*向模块的Trig脚发送开始命令(一个不短于10微秒的高电平)*/
HAL_GPIO_WritePin(Trig_GPIO, Trig_PIN, GPIO_PIN_SET);
/*保持高电平至少10微秒*/
SR04_RCC_Delay_us(10);
/*完毕,将Trig脚拉回低电平*/
HAL_GPIO_WritePin(Trig_GPIO, Trig_PIN, GPIO_PIN_RESET);
/*等待模块的Echo脚向单片机输出高电平*/
while(HAL_GPIO_ReadPin(Echo_GPIO,Echo_PIN) == GPIO_PIN_RESET);
/*模块传来了高电平,开始计时*/
HAL_TIM_Base_Start(SR04_TIM);
__HAL_TIM_SET_COUNTER(SR04_TIM, 0);
/*等待这个传来的高电平变回低电平后结束计时*/
while(HAL_GPIO_ReadPin(Echo_GPIO,Echo_PIN) == GPIO_PIN_SET);
HAL_TIM_Base_Stop(SR04_TIM);
/*此时定时器的计数值反映了刚刚那个高电平的持续时间,可将其换算成测得的距离*/
uint32_t pulseTime = __HAL_TIM_GET_COUNTER(SR04_TIM);
float distance = (pulseTime / 58.0);
SR04_RCC_Delay_us(10000);//这里如果不加延时多个超声波模块之间会相互干扰
return distance;//返回测得的距离
}
/*读取数据函使用说明:*/
/*
x=SR04_GetData(GPIOA,GPIO_PIN_4,GPIOB,GPIO_PIN_5);
//执行该代码的结果是变量x取得Trig脚接PA4,Echo脚接PB5的超声波模块测得的距离
//自行根据接线更改参数
*/
HC-SR04++.h
#include "main.h"
#include "tim.h"
#include "gpio.h"
float SR04_GetData(GPIO_TypeDef* Trig_GPIO,uint16_t Trig_PIN,GPIO_TypeDef* Echo_GPIO,uint16_t Echo_PIN);
想办法把这两个文件嵌入你的工程,具体步骤不赘述。
5.改驱动代码
注意我提供的.c文件上面的宏定义,你配的是TIM几就改成&htim几
6.正片——读取数值
驱动的用法很简单,定义好变量用来存放模块测得的距离,在合适的地方调用SR04_GetData函数,让变量取得函数的返回值即可。
想操作接在哪两个脚上的模块,那就以哪两个脚作为函数的参数(先Trig后Echo)。
如图就是变量a取得接在PE2、PD2上的模块测得的距离,变量b取得另一个模块的距离。