Compare commits

...

2 Commits

Author SHA1 Message Date
chauyinn
3f2e7bf019 新增 CommonCenter 类和 Config 结构体,提供超声波测距功能的配置和实例化支持
All checks were successful
Build and Upload Artifact / build and upload-artifact (push) Successful in 20m2s
2025-05-10 18:23:47 +08:00
chauyinn
b9a9165c71 新增 Ultrasonic 类和 TaskHelper 类,提供超声波测距功能及任务等待辅助方法 2025-05-10 18:23:21 +08:00
5 changed files with 140 additions and 0 deletions

View File

@@ -0,0 +1,16 @@
#pragma once
#include "../Common/ultrasonic.hpp"
#include "../config.hpp"
class CommonCenter {
public:
static Ultrasonic& GetUltrasonic() {
static Ultrasonic* instance = nullptr;
if (instance == nullptr) {
instance = new Ultrasonic(
Config::kCaptureConfig.trigger, Config::kCaptureConfig.timer, Config::kCaptureConfig.channel);
}
return *instance;
}
};

View 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");
}
}
};

View File

@@ -0,0 +1,19 @@
#pragma once
#include "stm32h5xx_hal.h"
#include <cstdint>
#include <stdexcept>
class TaskHelper {
public:
template <typename Func>
static void WaitFor(Func func, int timeoutMilliseconds) {
auto start = HAL_GetTick();
while (!func()) {
uint32_t now = HAL_GetTick();
if ((now - start) > static_cast<uint32_t>(timeoutMilliseconds)) {
throw std::runtime_error("Operation timed out");
}
}
}
};

View File

@@ -3,11 +3,13 @@
#include "Common/serial_port.hpp"
#include "Helper/gpio_helper.hpp"
#include "Center/common_center.hpp"
void Setup() {
GpioHelper::EnableAllGpioPeripheral();
DelaySetup();
auto ultrasonic = CommonCenter::GetUltrasonic();
}
extern "C" void AppStart() {

14
Core/App/config.hpp Normal file
View File

@@ -0,0 +1,14 @@
#pragma once
#include "stm32h563xx.h"
#include "tim.h"
#include "./Helper/gpio_helper.hpp"
struct Config {
static inline struct {
GpioHelper::Gpio trigger;
TIM_HandleTypeDef* timer;
uint32_t channel;
} kCaptureConfig = {{GPIOA, GPIO_PIN_0}, &htim7, TIM_CHANNEL_1};
};