1.电路连接及引脚配置
触发信号PA3只需要输出10us的高电平,所以直接设置成 普通的GPIO端口即可;回响信号使用外部中断,上升沿信号产生外部中断,打开定时器,下降沿再产生一次中断,读取定时器的值,就是高电平的时间,测试距离=(高电平时间*声速(340M/S))/2。
调试引脚配置:
配置时钟:
GPIO配置:
打开中断:
定时器设置:配置成最基本的定时器即可
PSC设置为72时候就是没过1us定时器里面的计数值就加1,我们的计数器是16位的,就是最大可以计数到65535,那我这个定时器最大可以计时到65535us,即0.065535s。所以最大测距范围为:,远远大于这款超声波测距模块的测距范围。
除此之外,我们要设置一下I2C给OLED显示屏使用,用于显示测量值:
2.驱动文件编写
(1)添加两个文件sr04.c和sr04.h
(2)sr04. h
cpp
#ifndef _SR04_H
#define _SR04_H
#include "stm32f1xx_hal.h"
void GET_Distance(void);
#endif
(3)sr04.c,超声波测距实现
cpp
#include "sr04.h"
uint16_t count;
float distance;
extern TIM_HandleTypeDef htim3;
/*指令耗时计算延时函数:
在程序里执行若干条空指令,来达到延时效果*/
void RCCdelay_us(uint32_t udelay)
{
__IO uint32_t Delay = udelay * 72 / 8;//(SystemCoreClock / 8U / 1000000U)
//见stm32f1xx_hal_rcc.c -- static void RCC_Delay(uint32_t mdelay)
do
{
__NOP();
}
while (Delay --);
}
/*测距模块触发信号函数*/
void GET_Distance(void)
{
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_3,GPIO_PIN_SET);
RCCdelay_us(12);
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_3,GPIO_PIN_RESET); //触发引脚电平拉高12us输出触发信号
}
/*中断服务函数,计数定时,解算测量距离*/
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
if(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_2)==GPIO_PIN_SET) //上升沿中断
{
__HAL_TIM_SetCounter(&htim3,0); //定时器清零
HAL_TIM_Base_Start(&htim3); //定时器开始计时
}
else //下降沿触发中断
{
HAL_TIM_Base_Stop(&htim3); //定时器停止计时
count=__HAL_TIM_GetCounter(&htim3); //读取定时器计数值
distance=count*0.017; //测试距离:((count/1000000)*340/2)*100,单位CM
}
}
(4)main.c
主函数里直接在直接调用GET_Distance()即可。