Контроль напряжения над блоком питания на STM32: Подход к энергоэффективности и защите
Автономные системы становятся все более востребованными - от портативных приборов до сложных промышленных комплексов - надежное управление напряжением питания превращается в ключевой фактор их долговечности и эффективности. Сердце любой такой системы - аккумулятор, а его безопасность и срок службы, напрямую зависит от контроля напряжения.
В данной статье будет представлен пример контроля напряжения, над блоком питания - внутри которого (никель-металлгидридная аккумуляторная сборка NiMH 14.4В/12 банок по 1.2В(1.4В- при полной зарядке)).
В блоке питания уже есть палата управления над аккумулятором, которая выполняет задачи:
- Работа с кнопкой;
- Работа со светодиодом;
- Работа с пъезоэлектрическим излучателем(звуковая индикация);
- Контроль заряда/разряда аккумулятора(дает звуковой сигнал при напряжении менее 9 вольт и более 14).
В процессе анализа и статистики использования оборудования стало очевидно, что многие пользователи часто забывают своевременно отключать блоки питания. В результате аккумуляторные сборки продолжают разряжаться даже при отсутствии необходимости, напряжение падает до критических значений, и аккумулятор быстро теряет свою емкость, становясь непригодным для дальнейшей эксплуатации.
Помимо этого, подключенная система оказывается в неопределенном состоянии, на плату управления и различные датчики по-прежнему подается питание, что приводит к избыточной нагрузке. В качестве этого сокращается ресурс электронных компонентов и снижается надежность всего устройства.
Для решения данной проблемы я продемонстрирую пример системы контроля напряжения блока питания, в качестве микроконтроллера выбран STM32F103С8T6, который выполняет следующие задачи:
- Непрерывный мониторинг напряжения аккумуляторной сборки, измерение производится через АЦП с использованием DMA;
- Оповещение пользователя о низком заряде, при падении напряжения ниже установленного порога (в данном примере - 9.0В) система активизирует звуковой сигнал, время работы оповещения ограничено - звуковая индикация будет длится 5 минут;
- Переход в энергосберегающий режим, если напряжение остается ниже порога и пользователь не предпринял действий в течении заданного времени, микроконтроллер переводит систему в режим сна, это сопровождается отключением тактирования и всей периферии, что минимизирует и предотвращает глубокий разряд аккумулятора.
Схема подключения NiMH АКБ, делителя напряжения к АЦП МК, кнопки вкл/выкл и пъезо-излучателя
Перечень компонентов
Объяснение схемы
Узел[1]
- Входной силовой ключ, исток подключен к +12V, сток идет к блоку питания(+12_АКК) через предохранители, а затвор подтянут к земле, применение (защищенная подача напряжения питания с аккумуляторного блока);
Узел[2]
- Вторичный силовой ключ, обеспечивает управляемое включение/отключение напряжения питания основной нагрузки системы, управление происходит через МК, сигнал PWR_ON, после включения данного узла, на стоке напряжение питания +12ВК активизируется и передает напряжение другим частям схемы, в моем примере это (узел[4]-Звуковая индикация и узел[5]-lделитель напряжения), но также можно использовать данный узел и на включение преобразователей напряжения;
Узел[3]
- Данный узел обеспечивает логику взаимодействия с кнопкой включения/выключения, кнопка sa2, при нажатии формирует управляющий сигнал, диод АD4 и конденсатор С1 обеспечивают фильтрацию и антидребезг;
Узел[4]
- Данный узел обеспечивает звуковую индикацию, сигнал BEEP подключается к МК;
Узел[5]
Данный узел является делителем напряжения, делит напряжение до уровня, подходящего для измерения АЦП МК (обычно до 3.3V), подстроечный резистор R8, выставлен на 1.7кОм.
Настройка микроконтроллера STM32F103 в CubeIDE
Конфигурация TIM1(PA11)
Таймер TIM1 выполняет роль генератора для звуковой индикации.
Настройка таймера:
- Предделитель (Prescaler) и период (Auto-Reload) выбраны так, чтобы на выходе формировался сигнал с частотой в диапазоне, воспринимаемом слухом (обычно 1–5 кГц);
- Режим работы – PWM (широтно-импульсная модуляция);
- Коэффициент заполнения (Pulse) определяет громкость и характер звучания.
Принцип работы:Таймер генерирует ШИМ-сигнал, который подаётся на транзисторный ключ. Транзистор управляет пьезоизлучателем или динамиком. В результате получается слышимый звук.
Преимущества такого решения:
- Микроконтроллеру не нужно вручную формировать частоту – этим занимается таймер;
- Легко изменять тональность: достаточно переписать значения ARR/PSC;
- Можно реализовать разные звуковые эффекты (короткие сигналы, мелодии) простым управлением таймером из программы.
Конфигурация ADC(PA1)
В проекте используется многоканальный режим работы АЦП с двумя каналами в последовательности (Regular conversion sequence).
Rank 1 – внешний канал (ADC Channel 1).Этот вход подключён к делителю напряжения и используется для измерения напряжения аккумулятора.Благодаря этому микроконтроллер может в реальном времени контролировать состояние питания устройства.
Rank 2 – внутренний канал (Vrefint).Это встроенный источник опорного напряжения микроконтроллера. Он служит для автоматической калибровки и компенсации возможных изменений питающего напряжения. С его помощью можно более точно измерять значение внешних сигналов, в том числе напряжение аккумулятора.
Для повышения эффективности задействован DMA: результаты обоих измерений (Rank 1 и Rank 2) автоматически передаются в память, а процессор получает только готовые данные.
Для правильной настройки ADC я воспользовался данной информацией, там подробно расписано как работать с ADC МК-STM32.
Конфигурация пина для работы с кнопкой
Для работы с кнопкой выбран вывод PB11, сконфигурированный в режиме:
- GPIO_EXTI – внешний прерывающий вход. Это значит, что нажатие кнопки обрабатывается не опросом в цикле, а через аппаратное прерывание;
- Mode - External interrupt, Falling edge trigger – прерывание срабатывает по спаду сигнала (при замыкании кнопки на землю);
- Pull-up – включен внутренний подтягивающий резистор, который удерживает вход в состоянии логической «1», пока кнопка не нажата.
Кнопка подключена так, что в обычном состоянии на входе PB11 присутствует логическая «1» благодаря встроенному подтягивающему резистору (Pull-up). При нажатии контакт замыкается на землю, формируется логический «0» и происходит спад сигнала. Этот спад фиксируется модулем EXTI, который вызывает прерывание.
Конфигурация пина для работы с сигналом PWR_ON
Сигнал PWR_ON играет роль электронного «выключателя питания».
В исходном состоянии (Low) нагрузка обесточена.
При активации (перевод вывода в High) силовой MOSFET открывается, и напряжение +12ВК подаётся на остальные узлы системы.
В примере данная линия питает:
узел [4] – звуковую индикацию,
узел [5] – делитель напряжения для мониторинга питания.
Аналогично этот узел можно использовать и для включения DC/DC-преобразователей или других модулей, требующих управляемого питания.
Реализация программного кода
Ссылка на скачивание исходного кода [ #исскуствомк_исходный_код -Исходный код для Adc_VoltageControl_STM32F103C8T6]
Заголовочный файл keys.h (работа с кнопками)
В данном файле определены:
- Функции работы с кнопками;
- Битовые маски состояний;
- константы для различных сценариев нажатий.
Реализация модуля keys.c (работа с кнопками)
Данный модуль включает в себя задачи:
- Устранение дребезга контактов;
- Различие между коротким и долгим нажатием;
- Отслеживание событий нажатия, удержания и отпускания.
keysDrv_Handler()
Вызывается постоянно в основном цикле или из системного таймера.
Нажатие кнопки (первичное событие)
Сохраняется время нажатия, дальнейшие события блокируются до отпускания
Фильтр дребезга
Если прошло больше DELAY4TIMER, считаем кнопку реально нажатой.
определение удержания
Если прошло больше DELAY_HOLD_TIMER, выставляем бит удержания.
Отпускание кнопки
При отпускании кнопки сбрасываются флаги удержания и нажатия, выставляется бит отпускания.
getKeyState()
Возвращает текущее состояние кнопок в виде битовой маски
- Позволяет определить, была ли кнопка нажата, удержана или отпущена;
- После считывания некоторые флаги (например, отпускание) сбрасываются ,чтобы событие не повторялось.
getKeyPinState_AtNow()
Возвращает моментальное состояние ножек GPIO, без учета дребезга
- Полезно для отладки или когда нужно мгновенно узнать, нажата ли кнопка прямо сейчас
keys.c
Реализация модуля ADC_Calc.c (работа с АЦП)
Данный модуль реализует контроль напряжения питания через АЦП микроконтроллера STM32F103C8T6, измерения выполняются с использованием:
- DMA (циклическая запись данных в буфер);
- Встроенного опорного напряжения Vrefint;
- Собственного делителя напряжения на входе.
ADC_Calc_Handler() - главный обработчик вычислений
- Проверяет, заполнена ли первая или вторая половина DMA-буфера;
- Усредняет значения для канала измерения и Vrefint;
- Конвертирует результат в напряжение вызовом adc_calcVoltage();
- Если напряжение ниже порога critical_stress → возвращает команду отключения питания (FORCE_POWER_OFF);
- Производит фильтрацию значений по диапазону 750 < val_input < 2800 (защита от шумов и выбросов).
HAL_ADC_ConvCpltCallback()
Вызывается по прерыванию DMA Transfer Complete → устанавливает флаг adcIRFullDone
HAL_ADC_ConvHalfCpltCallback()
Вызывается по прерыванию DMA Half Transfer Complete → устанавливает флаг adcIRHalfDone
adc_init()
- Сброс флагов и буфера.
adc_start()
Запускает АЦП в режиме DMA, далее происходит циклическое заполнение adcDMAbuf без участия процессора
adc_stop()
- Останавливает АЦП и DMA;
- Сбрасывает флаги готовности
adc_calcVoltage()
Ключевая функция — переводит «сырые» значения АЦП в напряжение
adc_GetVoltage()
Геттер для получения последнего значения рассчитанного напряжения
Общий алгоритм работы:
- DMA заполняет буфер парами значений (input, Vrefint);
- При заполнении половины буфера → срабатывает прерывание, ставится флаг;
- ADC_Calc_Handler считывает данные, фильтрует и усредняет;
- Вызывается adc_calcVoltage, которая переводит вольты;
- Значение доступно через adc_GetVoltage();
- Если напряжение меньше 9 В (по critical_stress) → отрабатывает аварийное выключение.
ADC_Calc.c
Пояснение к функции adc_calcVoltage()
Расчет VDDA, где:
VREFINT_TYP - калибровочное значение 1.20, взято из datasheet, у других МК на заводе производитель прошивает калибровочное значение в ПЗУ при изготовлении, пример получения значения с МК STM32F030CCTx [0x1FFFF7BA];
4095 - когда измеряется источник встроенным АЦП, результат выражается в единицах квантования, максимум которых равен 4095, поэтому в формуле используется множитель 4095 - это нормализация значения, чтобы связать измеренный АЦП с напряжением VDDA.
ADC_vref - значение встроенного источника опорного напряжения
Перевод значения канала в напряжение
ADC_in - напряжение измеренное с делителя напряжения (узел[5])
Коррекция через делитель напряжения
Вход подключен через делитель R1=221кОм и R2 = 27кОм, переводим в Ом,
добавил смещение (-0.5) для подстройки измерений.
Таблица замеров напряжения от 14.5 вольт до 7 вольт.
Прикладываю видео-тестирования прохода по спаду напряжения, а также видео-тестирования, сброс напряжения и уход в сон микроконтроллера при низком напряжении ссылка [ #исскуствомк_тестирование_ Adc_VoltageControl]
Реализация модуля proj_main.c (Главный метод)
Данный модуль объединяет несколько подсистем:
- Кнопка управления (одиночное и двойное нажатие);
- Контроль напряжения питания через АЦП;
- Звуковая индикация состояния;
- Автоматический переход в сон при низком напряжении.
Вывод
Данная система контроля над блоком питания реализует:
- Обработку кнопок с фильтрацией дребезга, с поддержкой короткого/долгого/двойного нажатия и отпускания;
- Мониторинг напряжения через АЦП с защитой от просадок и автоматическим отключением при критическом низком уровне;
- Звуковая индикация (короткие, двойные сигналы) для информирования пользователя о событиях;
- Энергосбережение переход в режим STOP и пробуждение по прерыванию.
Систему можно использовать как основу для портативных приборов, автономных устройств и встраиваемых систем, где важно одновременно удобное управление и защита электроники.
Если статья показалась Вам интересной, буду рад выпустить для Вас еще множество статей исследований по всевозможным видам устройств, так что, если не хотите их пропустить – буду благодарен за подписку на мой ТГ-канал: https://t.me/ChipCraft.