Я настраиваю SMBus в CubeMX, добавил пакет X_CUBE_SMBUS, в папке Middlewares вижу stm32_PMBUS_stack и stm32_SMBUS_stack, но не знаю, что делать дальше, не умею этим пользоваться.
Не стоит упорно вгрызаться в низкоуровневый исходный код в Middleware, можно легко запутаться. У ST всё по одной схеме: раз уж ты скачал пакет X_CUBE_SMBUS, сразу иди в каталог его установки (обычно STM32Cube\Repository) и ищи папку Projects. Там точно будут готовые примеры (Example) для некоторых отладочных плат (например, NUCLEO или EVAL). Найди проект, связанный с PMBus, и просто открой его main.c и stm32_xx_it.c. Обрати внимание на две вещи: во-первых, на функцию обработки Stack Process, которая вызывается в главном цикле; во-вторых, как написан Callback при получении Command ведомым. Скопируй его код прикладного уровня, немного подправь — и всё заработает.
Брат, не парься, дока у этого пакета действительно написана немного разбросанно, я сам, когда впервые с ним столкнулся, долго въезжал.
Сейчас твоя ситуация такая: аппаратный уровень (CubeMX) настроен, но непонятно, как подружить уровень протокола (стек) с прикладным кодом.
Я вкратце распишу тебе основной алгоритм, как я его понял, просто действуй по нему:
Шаг 1: Убедись, что сгенерировал правильную структуру проекта При добавлении X-CUBE-SMBUS в Software Packs в CubeMX, в окне Mode есть два чекбокса: SMBus stack и PMBus extension, нужно отметить оба. После генерации кода в твоем проекте должны быть:
Middlewares/ST/STM32_SMBus_Stack/— это основной стек протоколаDrivers/BSP/— board support package (если ты его выбрал)
Шаг 2: Пойми, как работает стек Этот стек нужен не для того, чтобы ты дергал HAL_I2C_xxx, он оборачивает конечный автомат. Твой код будет в основном взаимодействовать с тремя функциями:
STACK_SMBUS_Init()— инициализация, привязка I2C-хэндлаSTACK_SMBUS_HostCommand()— для хоста (мастера), инициирует обмен даннымиSTACK_SMBUS_ExecuteCommand()— для слейва, коллбэк при получении команды
Шаг 3: Как писать код для слейва Самое главное для слейва — это CMD_Table, массив, который говорит стеку: «Когда я получу код команды 0x01, из какого регистра мне читать; когда получу 0x02, в какой регистр писать».
const tSMBUS_CMD_Table MyCmdTable[] = {
{0x01, MyReadHandler, MyWriteHandler, 1}, // код команды, коллбэк чтения, коллбэк записи, длина данных
{0x02, MyReadHandler2, NULL, 2},
};
А затем внутри STACK_SMBUS_ExecuteCommand() делать диспетчеризацию на основе stackhandle.CurrentCommand.
Шаг 4: Как писать код для хоста С хостом всё намного проще: формируешь структуру команды и вызываешь STACK_SMBUS_HostCommand(&stackhandle, &cmd). Имей в виду, что эта функция неблокирующая, результат нужно смотреть в прерывании коллбэка через stackhandle.State.
Важные моменты:
- Официальные примеры лежат в директории
Projects, ищи тот, что ближе к твоей плате, например, для NUCLEO-G431RB или Discovery F072. - Обязательно прочитай AN4502, это официальный аппноут. Пусть он и объемный, но 8-я глава «Configuration» и 9-я глава «Project example» — просто спасательный круг.
- При соединении двух STM32 линии SDA и SCL нужно подтягивать. Даже если на плате есть внутренние подтяжки, добавь внешние на 4.7 кОм — так надежнее. PMBus более чувствителен к целостности сигнала, чем I2C.
Если будут проблемы, кидай конкретные ошибки, подсобим.
Скорее всего, вы смотрите на эти папки не под тем углом. stm32_SMBUS_stack — это нижний коммуникационный уровень, а stm32_PMBUS_stack находится поверх него для обработки команд PMBus.
Что обычно нужно сделать дальше: включить периферию HAL SMBus, добавить в проект исходные файлы промежуточного ПО, инициализировать стек в main() и реализовать необходимые библиотеке функции обратного вызова. Без функций обратного вызова стеку некуда отправлять принятые кадры.
Спасибо всем гуру за ответы, пойду попробую.
Каков результат попытки?
Я скинул эту часть ребятам из команды, не хватает сил ![]()