Car/Core/Src/hcsr04.c

90 lines
2.6 KiB
C
Raw Normal View History

2024-07-11 18:14:13 +08:00
#include "hcsr04.h"
#include "tim.h"
#include <stdio.h>
2024-07-11 18:14:13 +08:00
static uint64_t time; // 声明变量,用来计时
static uint64_t time_end; // 声明变量,存储回波信号时间
2024-07-13 15:59:18 +08:00
static int16_t delay_time = -1; // 用于延时
uint8_t sonor_state; // 测距状态变量0未测量1正在测量2已测量
uint32_t sonor_distance; // 测量出的距离单位mm
2024-07-11 18:14:13 +08:00
void delay_us(uint16_t us);
void HCSR04_HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim);
2024-07-11 18:14:13 +08:00
// 初始化超声波测距
void HC_SR04_Init(void)
2024-07-11 18:14:13 +08:00
{
// 禁用JTAG
__HAL_RCC_AFIO_CLK_ENABLE();
__HAL_AFIO_REMAP_SWJ_NOJTAG();
2024-07-11 18:14:13 +08:00
// 注册定时器中断溢出回调
HAL_TIM_RegisterCallback(&htim2, HAL_TIM_PERIOD_ELAPSED_CB_ID, HCSR04_HAL_TIM_PeriodElapsedCallback);
}
2024-07-11 18:14:13 +08:00
// 启动测距单位mm
uint32_t sonar_mm(void)
{
sonor_state = 1;
HAL_GPIO_WritePin(Trig_GPIO_Port, Trig_Pin, GPIO_PIN_SET); // 输出高电平
delay_us(15); // 延时15微秒
HAL_GPIO_WritePin(Trig_GPIO_Port, Trig_Pin, GPIO_PIN_RESET); // 输出低电平
if (time_end / 100 < 38)
{ // 判断是否小于38毫秒大于38毫秒的就是超时直接调到下面返回0
sonor_distance = (time_end * 346) / 2; // 计算距离25°C空气中的音速为346m/s
sonor_distance = sonor_distance / 100; // 因为上面的time_end的单位是10微秒所以要得出单位为毫米的距离结果还得除以100
}
return sonor_distance;
2024-07-11 18:14:13 +08:00
}
/// @brief 微秒级延时
/// @param us 取值范围0-32767
2024-07-11 18:14:13 +08:00
void delay_us(uint16_t us)
{
if (us == 0)
return;
2024-07-13 15:59:18 +08:00
delay_time = us;
2024-07-11 18:14:13 +08:00
time = 0;
2024-07-13 15:59:18 +08:00
HAL_TIM_Base_Start_IT(&htim2);
2024-07-11 18:14:13 +08:00
while (time < us)
;
2024-07-13 15:59:18 +08:00
delay_time = -1;
2024-07-11 18:14:13 +08:00
}
void HCSR04_HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
2024-07-11 18:14:13 +08:00
{
if (htim == &htim2)
2024-07-13 15:59:18 +08:00
{
// 每10us自增一
2024-07-11 18:14:13 +08:00
++time;
if (delay_us > 0 && time * 10 >= delay_time)
2024-07-13 15:59:18 +08:00
HAL_TIM_Base_Stop_IT(&htim2);
}
2024-07-11 18:14:13 +08:00
}
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
if (GPIO_Pin == Echo_Pin)
2024-07-11 18:14:13 +08:00
{
if (HAL_GPIO_ReadPin(Echo_GPIO_Port, Echo_Pin))
2024-07-11 18:14:13 +08:00
{
time = 0;
HAL_TIM_Base_Start_IT(&htim2);
2024-07-11 18:14:13 +08:00
}
else
{
time_end = time;
HAL_TIM_Base_Stop_IT(&htim2);
sonor_state = 2;
Sonar_CP_Callback();
2024-07-11 18:14:13 +08:00
}
}
}
// 测距完毕回调执行完自定义任务后将sonor_state置0
__attribute__((weak)) void Sonar_CP_Callback()
{
printf("distance = %d (mm)\n", sonor_distance);
sonor_state = 0;
}