From 1d90e806a0363cf884b2e1ae40526dc805a515fb Mon Sep 17 00:00:00 2001 From: Nikita Bulatov Date: Sat, 21 Mar 2026 19:58:12 +0300 Subject: [PATCH 1/4] =?UTF-8?q?=D0=A0=D0=B0=D0=B1=D0=BE=D1=87=D0=B0=D1=8F?= =?UTF-8?q?=20=D0=B2=D0=B5=D1=80=D1=81=D0=B8=D1=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Core/Inc/pressure_wrapper.h | 65 +++++++------------------------------ Core/Src/main.cpp | 15 ++++++--- 2 files changed, 22 insertions(+), 58 deletions(-) diff --git a/Core/Inc/pressure_wrapper.h b/Core/Inc/pressure_wrapper.h index a6039c9..ca1de62 100644 --- a/Core/Inc/pressure_wrapper.h +++ b/Core/Inc/pressure_wrapper.h @@ -14,102 +14,78 @@ extern "C" { #include #include -/** - * Константы преобразований (замена макросов) - */ namespace PressureConversions { - // Преобразование среднего значения АЦП (без учёта атмосферного давления) в напряжение (мВ) constexpr uint32_t adcToVoltage(uint32_t adc_press, uint32_t adc_z) noexcept { return (adc_press - adc_z) * 16575u / 2048u; } - // Преобразование напряжения (мВ) в давление (Па) constexpr uint32_t voltageToPascals(uint32_t voltage_mv) noexcept { return voltage_mv * 6895u / 4u * 37u / 9u; } - // Преобразование давления (Па) в глубину (мм) constexpr uint32_t pascalsToDepthMm(uint32_t pascals) noexcept { - return pascals / (10u * 981u); // 10 * 981 = 9810 + return pascals / (10u * 981u); } - // Преобразование среднего значения АЦП температуры в напряжение (мВ) constexpr uint32_t tempAdcToVoltage(uint32_t adc_temp) noexcept { return adc_temp * 33120u / 4096u; } - // Преобразование напряжения температуры (мВ) в температуру (десятые доли градуса Цельсия) constexpr int32_t voltageToTempCelsius(uint32_t voltage_mv) noexcept { - // формула: (напряжение - 5000) * 10 return (static_cast(voltage_mv) - 5000) * 10; } -} // namespace PressureConversions +} class PressureWrapper { public: - // Конструктор PressureWrapper(ADC_HandleTypeDef& hadc, TIM_HandleTypeDef& htim) noexcept : hadc_(hadc), htim_(htim) {} - // Инициализация: калибровка АЦП, запуск таймера и DMA bool init() noexcept { - // Калибровка АЦП (однополярный режим для большинства STM32) if (HAL_ADCEx_Calibration_Start(&hadc_) != HAL_OK) { return false; } - HAL_Delay(100); if (HAL_TIM_Base_Start(&htim_) != HAL_OK) { return false; } + HAL_Delay(100); // дополнительная задержка для стабильности - // Запуск DMA: буфер adcRaw_ объявлен как uint16_t, приводим к uint32_t* - if (HAL_ADC_Start_DMA(&hadc_, reinterpret_cast(adcRaw_.data()), kAdcBufferSize * 2) != HAL_OK) { + // Запуск DMA с правильным типом буфера + if (HAL_ADC_Start_DMA(&hadc_, adcRaw_.data(), kAdcBufferSize * 2) != HAL_OK) { return false; } - return true; } - // Опрос: вызывать в основном цикле void poll() noexcept { - // Проверяем, завершён ли полный буфер (флаг атомарный) if (fullConvDone_.load(std::memory_order_acquire)) { - // Определяем, какая половина буфера заполнена (если обе, то обрабатываем полную) bool half = halfConvDone_.load(std::memory_order_acquire); - - // Обрабатываем данные буфера (используется локальное копирование) adcProcess(half); - // Для первого набора данных сохраняем нулевое давление (атмосферное) if (isFirst_) { - adc_z_ = pressSum_; // среднее значение АЦП для нулевого давления + adc_z_ = pressSum_; isFirst_ = false; } - // Вычисляем физические величины adcVoltage_ = PressureConversions::adcToVoltage(pressSum_, adc_z_); adcPascals_ = PressureConversions::voltageToPascals(adcVoltage_); depthMm_ = PressureConversions::pascalsToDepthMm(adcPascals_); - - // Если температура используется, вычисляем и её tempMilliCelsius_ = PressureConversions::voltageToTempCelsius( PressureConversions::tempAdcToVoltage(tempSum_) ); - // Сбрасываем флаг полного завершения (после того как данные обработаны) fullConvDone_.store(false, std::memory_order_release); } } - // Геттеры uint32_t getDepthMm() const noexcept { return depthMm_; } uint32_t getPressurePascals() const noexcept { return adcPascals_; } uint32_t getAdcVoltage() const noexcept { return adcVoltage_; } int32_t getTemperatureMilliCelsius() const noexcept { return tempMilliCelsius_; } - // Методы, вызываемые из обработчиков прерываний + // Эти методы должны вызываться из прерываний DMA void setHalfConvFlag() noexcept { halfConvDone_.store(true, std::memory_order_release); fullConvDone_.store(true, std::memory_order_release); @@ -119,24 +95,17 @@ class PressureWrapper { fullConvDone_.store(true, std::memory_order_release); } - // Доступ к дескриптору АЦП для идентификации в обработчиках (опционально) ADC_HandleTypeDef& getHadc() noexcept { return hadc_; } - ~PressureWrapper() = default; - private: - // Обработка данных из DMA-буфера void adcProcess(bool isHalf) noexcept { - // Определяем диапазон индексов в буфере adcRaw_ const size_t start = isHalf ? 0 : kAdcBufferSize; const size_t end = isHalf ? kAdcBufferSize : kAdcBufferSize * 2; uint32_t pressSumLocal = 0; uint32_t tempSumLocal = 0; - // Суммируем значения из указанной половины буфера for (size_t i = start; i < end; ++i) { - // Чётные индексы — канал давления, нечётные — температуры if ((i & 1) == 0) { pressSumLocal += adcRaw_[i]; } else { @@ -144,12 +113,10 @@ class PressureWrapper { } } - // Вычисляем среднее значение для каждой половины буфера - const size_t halfCount = kAdcBufferSize / 2; + const size_t halfCount = kAdcBufferSize / 2; // количество пар в половине pressSum_ = pressSumLocal / halfCount; tempSum_ = tempSumLocal / halfCount; - // Сбрасываем флаги (только тот, который был обработан) if (isHalf) { halfConvDone_.store(false, std::memory_order_release); } else { @@ -157,30 +124,22 @@ class PressureWrapper { } } - // Дескрипторы периферии ADC_HandleTypeDef& hadc_; TIM_HandleTypeDef& htim_; - // Параметры DMA - static constexpr size_t kAdcBufferSize = 200; // количество отсчётов на канал - // Буфер АЦП: 16-битные значения от DMA (обычно для 12-битных АЦП) - std::array adcRaw_{}; + static constexpr size_t kAdcBufferSize = 200; + // Буфер теперь 32-битный, как требует HAL + std::array adcRaw_{}; - // Атомарные флаги для синхронизации с прерываниями std::atomic halfConvDone_{false}; std::atomic fullConvDone_{false}; - // Состояние bool isFirst_ = true; - // Суммы/средние АЦП uint32_t pressSum_ = 0; uint32_t tempSum_ = 0; + uint32_t adc_z_ = 0; - // Эталонное значение АЦП для атмосферного давления - uint32_t adc_z_ = 0; - - // Вычисленные физические величины uint32_t adcVoltage_ = 0; uint32_t adcPascals_ = 0; uint32_t depthMm_ = 0; diff --git a/Core/Src/main.cpp b/Core/Src/main.cpp index 8308eaa..dd8d601 100644 --- a/Core/Src/main.cpp +++ b/Core/Src/main.cpp @@ -110,7 +110,7 @@ int main(void) { manager.Process(); sensor.poll(); depth = sensor.getDepthMm(); - master.Write(static_cast(&depth), 0, sizeof(depth)); + // master.Write(static_cast(&depth), 0, sizeof(depth)); } /* USER CODE END 3 */ } @@ -263,12 +263,17 @@ static void MX_DMA_Init(void) { } /* USER CODE BEGIN 4 */ -void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef *hadc) { - sensor.setFullConvFlag(); + +void HAL_ADC_ConvHalfCpltCallback(ADC_HandleTypeDef* hadc) { + if (hadc == &sensor.getHadc()) { + sensor.setHalfConvFlag(); + } } -void HAL_ADC_ConvHalfCpltCallback(ADC_HandleTypeDef *hadc) { - sensor.setHalfConvFlag(); +void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc) { + if (hadc == &sensor.getHadc()) { + sensor.setFullConvFlag(); + } } void USART1_IRQHandler(void) { RS.IRQCallback(); } From 624bc189d0edcef3a8ede142055a0f33a16b3918 Mon Sep 17 00:00:00 2001 From: Nikita Bulatov Date: Sat, 21 Mar 2026 20:06:04 +0300 Subject: [PATCH 2/4] =?UTF-8?q?=D0=A0=D0=B0=D0=B1=D0=BE=D1=82=D0=B0=D0=B5?= =?UTF-8?q?=D1=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Core/Src/main.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Core/Src/main.cpp b/Core/Src/main.cpp index dd8d601..4347ead 100644 --- a/Core/Src/main.cpp +++ b/Core/Src/main.cpp @@ -3,7 +3,7 @@ extern "C" { #endif #include "main.h" - +#include "stm32f1xx_it.h" #ifdef __cplusplus } #endif @@ -110,7 +110,7 @@ int main(void) { manager.Process(); sensor.poll(); depth = sensor.getDepthMm(); - // master.Write(static_cast(&depth), 0, sizeof(depth)); + master.Write(static_cast(&depth), 0, sizeof(depth)); } /* USER CODE END 3 */ } From eaa678c7ca82ef90e41dbf15efb4c1b76d6dd617 Mon Sep 17 00:00:00 2001 From: Svvyppy Date: Sat, 21 Mar 2026 21:56:13 +0300 Subject: [PATCH 3/4] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=B8=D0=BB?= =?UTF-8?q?=20=D0=B7=D0=B0=D0=BF=D1=83=D1=81=D0=BA=20=D0=BF=D0=B0=D0=B9?= =?UTF-8?q?=D0=BF=D0=B0=20=D0=BD=D0=B0=20=D0=9F=D0=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/cmake-multi-platform.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/cmake-multi-platform.yml b/.github/workflows/cmake-multi-platform.yml index db9c4a9..e60e626 100644 --- a/.github/workflows/cmake-multi-platform.yml +++ b/.github/workflows/cmake-multi-platform.yml @@ -5,6 +5,9 @@ on: branches: [ '*' ] tags: [ 'v*' ] workflow_dispatch: + pull_request: + branches: [ '*' ] + workflow_dispatch: jobs: Build-F1: From b54cada65b4a705ba780b8f576e01a4b90a7b329 Mon Sep 17 00:00:00 2001 From: Svvyppy Date: Sat, 21 Mar 2026 21:57:28 +0300 Subject: [PATCH 4/4] fix --- .github/workflows/cmake-multi-platform.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/cmake-multi-platform.yml b/.github/workflows/cmake-multi-platform.yml index e60e626..dd27b94 100644 --- a/.github/workflows/cmake-multi-platform.yml +++ b/.github/workflows/cmake-multi-platform.yml @@ -4,7 +4,6 @@ on: push: branches: [ '*' ] tags: [ 'v*' ] - workflow_dispatch: pull_request: branches: [ '*' ] workflow_dispatch: