Цифровой источник питания Buck-Boost с синхронным выпрямлением на базе STM32 — открытый исходный код

Не понял ваш вопрос

Исходный код находится здесь

Всё ещё не понимаю, что ты хочешь спросить.

Коллега, подскажите, пожалуйста. Я немного изменил модуль вспомогательного питания: заменил ваш DCDC-понижающий модуль на модуль NDP2355KC. В качестве силового дросселя использовал PSPMAA0605H-100M-ANP. Возникла такая проблема: при подаче на вход напряжения 16 В и попытке установить выходное напряжение около 10 В система перезагружается (при питании через разъем Type-C) или происходит перегрузка по току, и источник выдает максимальный ток (при подключении к стабилизированному источнику питания). Когда я питаю схему от источника постоянного тока, он переключается в режим CC, и выходное напряжение падает примерно до 6 В. К тому же, полевой транзистор на плате сильно нагревается. Не могли бы вы проанализировать проблему? Спасибо.

Проверьте, нет ли короткого замыкания на выходе

Посмотрите свою разводку PCB

Это PCB

Результат также не короткое замыкание

Кажется, линия выборки не подключена, и токовая выборка не использует кельвиновскую трассировку

Это сопротивление случайно повернули, с PCB всё в порядке. Я действительно не обратил внимания на то, что токовая выборка должна проходить по схеме Кельвина. Спасибо автору за напоминание.

Как настроить этот HRTIM, чтобы запускать выборку АЦП в середине периода ШИМ? Я пробовал настроить, но время срабатывания немного не то — оно наступает намного позже, чем я установил. Как мне найти, где возникает проблема?

Сделай скриншот, покажи, как у тебя настроено.

Я использовал только C, а D — для будущего расширения

При тестировании я обнаружил, что момент переключения пина PC15 всегда на 2.5 мкс позже установленного времени, ниже приведена моя тестовая функция

// Функция обратного вызова

void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef *hadc)

{

// ADC1_2_IRQHandler();

if (hadc->Instance == ADC2)

{

    GPIOC->ODR ^= GPIO_PIN_15;

    Control_Loop_Update(); // твой высокочастотный цикл управления

    // GPIOC->ODR ^= GPIO_PIN_15;

}

else if (hadc->Instance == ADC1)

{

    // GPIOC->ODR ^= GPIO_PIN_13;

    // flag_adc1 = 1;

    PID_V();

    GPIOC->ODR ^= GPIO_PIN_13;

}

// HAL_GPIO_WritePin(GPIOB, GPIO_PIN_15, GPIO_PIN_RESET); // Установка низкого уровня

}

Не знаю, почему на этом скриншоте сбился порядок :sweat_smile:

Брат, да сам твой метод тестирования кривой. Инвертируя IO внутри HAL_ADC_ConvCpltCallback, ты измеряешь вообще не «время срабатывания», а «время выборки АЦП + время преобразования + задержка реакции на прерывание + огромные накладные расходы на проверки в библиотеке HAL».
Зайди в исходники HAL_ADC_IRQHandler и глянь сам: перед тем как дергнуть этот колбэк, HAL от ST проверяет кучу состояний регистров, и то, что на это улетает 1–2 мкс, — это абсолютно нормально. Плюс, судя по скрину, у тебя время выборки настроено на 6.5 циклов, а на преобразование нужно еще 12.5 — это всё чисто потраченное время.
Если хочешь измерить реальный момент срабатывания, настрой пин выхода сравнения таймера и сними осциллографом ШИМ-сигнал вместе с этим выходом. А если прям обязательно мерить в прерывании — выкинь HAL, найди в startup-файле вектор прерывания АЦП и первой же строкой инвертируй GPIO: увидишь, что задержка моментально станет намного меньше.

1 лайк

Глянул твой скриншот CubeMX, проверь несколько сомнительных моментов:

  1. В качестве источника запуска АЦП у тебя настроен Timer C Compare 3. Я вижу, что в настройках Timer C ты задал Compare 3 как 46080 / 4. Если период твоего ШИМ — 46080, то центр разве не должен быть /2? (если только ты не используешь центрально-выровненный режим, тогда нужно отдельно считать).
  2. Для запуска АЦП по фронту ты выбрал Trigger detection on the falling edge (по заднему фронту). Ты уверен, что событие запуска от HRTIM в ожидаемом тобой месте — это задний фронт? Обычно по умолчанию чаще настраивают передний фронт.
  3. Как уже сказали выше, 2.5 мкс — это однозначно программные накладные расходы. При тактовой частоте G474 170 МГц за 2.5 мкс выполняется около 400 с лишним инструкций, и всё это уходит на вход в прерывание, сохранение контекста в стек и проверки IF в библиотеке HAL. Рекомендую задействовать DMA: пусть АЦП по завершении выборки напрямую запускает DMA для передачи данных, не используй прерывания CPU для ожидания.
1 лайк

Да, потом я еще раз протестировал и заметил, что если поместить код в функцию ADC1_2_IRQHandler, задержка практически исчезает.

Гуру, я сейчас в процессе тестирования, сначала всё работало нормально (на выходе были большие «пульсации», совпадающие с частотой коммутации, но усиленные, их частота была очень высокой, как на фото ниже). Затем я добавил несколько выходных конденсаторов, и после повторной подачи питания АЦП у 32-го, похоже, полностью вышло из строя: сейчас данные, считываемые с пинов АЦП, всегда одинаковые, независимо от того, какой сигнал подается на вход. Чем это может быть вызвано? Мое входное напряжение 40В, на выходе выставлено 30В, нагрузка 20R. Хочу спросить, нужно ли после тестируемого модуля добавить компонент для защиты пинов 32-го? Если нужно, есть ли какие-нибудь рекомендации? Спасибо, гуру!

Вот моя измерительная цепь и основная цепь

Не понял, что ты говоришь, это моя плата с открытым исходным кодом?

Топология та же, просто эту я нарисовал сам

Мои вопросы:

  1. Почему на моём графике измерения переменной составляющей на выходе возникает такой высокий выброс? В одном периоде коммутации он появляется 4 раза, как мне устранить его влияние?

  2. При тестировании платы полностью вышла из строя часть АЦП STM32. Не знаю, почему АЦП могло повредиться: перед пином АЦП у меня стоит RC-фильтр нижних частот, но пин АЦП всё равно сгорел. Что могло стать причиной этого? Раньше я просто подозревал, что пин АЦП повреждён, а теперь практически уверен, что он действительно сгорел. (Я предполагаю, что пин АЦП STM32 повредился из-за слишком высоких выбросов переменной составляющей, показанных на графике выше, но не знаю, верно ли моё предположение). Я уже спалил два МК, и оба — из-за повреждения пинов АЦП, но не могу найти причину.

  3. Если я хочу обеспечить дополнительную защиту пина АЦП STM32, чтобы входное напряжение АЦП находилось в диапазоне 0–3.3 В, есть ли для этого хорошие методы/компоненты?