generated from Template/H563ZI-HAL-CMake-Template
新增 Ultrasonic 类和 TaskHelper 类,提供超声波测距功能及任务等待辅助方法
This commit is contained in:
89
Core/App/Common/ultrasonic.hpp
Normal file
89
Core/App/Common/ultrasonic.hpp
Normal file
@@ -0,0 +1,89 @@
|
||||
#pragma once
|
||||
|
||||
#include "../Helper/delay_helper.h"
|
||||
#include "stm32h563xx.h"
|
||||
#include "stm32h5xx_hal_tim.h"
|
||||
#include <cstdint>
|
||||
#include <stdexcept>
|
||||
|
||||
#include "../Helper/gpio_helper.hpp"
|
||||
#include "../Helper/task_helper.hpp"
|
||||
|
||||
class Ultrasonic {
|
||||
public:
|
||||
Ultrasonic(GPIO_TypeDef* gpio, uint16_t pin, TIM_HandleTypeDef* timer, uint32_t channel)
|
||||
: Ultrasonic({gpio, pin}, timer, channel) {}
|
||||
|
||||
Ultrasonic(const GpioHelper::Gpio& trigger, TIM_HandleTypeDef* timer, uint32_t channel)
|
||||
: trigger(trigger), timer(timer), channel(channel) {
|
||||
captureFlag = GetCaptureFlag(channel);
|
||||
}
|
||||
|
||||
double GetDistance(uint32_t time = 1) {
|
||||
double distance = 0;
|
||||
for (uint32_t cnt = 0; cnt < time; ++cnt) {
|
||||
Trigger();
|
||||
auto echoTime = MeasureEchoTime();
|
||||
distance += CalculateDistance(echoTime);
|
||||
}
|
||||
return distance / time;
|
||||
}
|
||||
|
||||
private:
|
||||
constexpr static uint32_t kTimeout = 100;
|
||||
|
||||
GpioHelper::Gpio trigger;
|
||||
TIM_HandleTypeDef* timer;
|
||||
uint32_t channel;
|
||||
uint32_t captureFlag;
|
||||
|
||||
void Trigger() {
|
||||
trigger.Set();
|
||||
DelayUs(10);
|
||||
trigger.Reset();
|
||||
}
|
||||
|
||||
double MeasureEchoTime() {
|
||||
timer->Instance->CNT = 0;
|
||||
uint32_t data[2];
|
||||
HAL_TIM_IC_Start(timer, channel);
|
||||
try {
|
||||
for (auto& value : data) {
|
||||
TaskHelper::WaitFor(
|
||||
[&]() {
|
||||
if (__HAL_TIM_GET_FLAG(timer, captureFlag)) {
|
||||
__HAL_TIM_CLEAR_FLAG(timer, captureFlag);
|
||||
value = HAL_TIM_ReadCapturedValue(timer, channel);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
kTimeout);
|
||||
}
|
||||
HAL_TIM_IC_Stop(timer, channel);
|
||||
return (data[1] - data[0]) / 250.0;
|
||||
} catch (const std::exception& e) {
|
||||
HAL_TIM_IC_Stop(timer, channel);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
[[nodiscard]] static double CalculateDistance(double echoTime) {
|
||||
return (echoTime * 0.0343) / 2.0;
|
||||
}
|
||||
|
||||
static uint32_t GetCaptureFlag(uint32_t channel) {
|
||||
switch (channel) {
|
||||
case TIM_CHANNEL_1:
|
||||
return TIM_SR_CC1IF;
|
||||
case TIM_CHANNEL_2:
|
||||
return TIM_SR_CC2IF;
|
||||
case TIM_CHANNEL_3:
|
||||
return TIM_SR_CC3IF;
|
||||
case TIM_CHANNEL_4:
|
||||
return TIM_SR_CC4IF;
|
||||
default:
|
||||
throw std::invalid_argument("Invalid timer channel");
|
||||
}
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user