# 大佬们，有没有用STM32的HAL库做过PMBus通信的，一个32做主机，另一个做从机。

**URL:** <https://bbs.eeclub.top/t/stm32-hal-pmbus-32/383>\
**Category:** 项目实践\
**Tags:** QA, STM32\
**Created:** [2026 年5 月 22 日 09:21 UTC](https://bbs.eeclub.top/t/stm32-hal-pmbus-32/383 "2026-05-22T09:21:14Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

作者： ![muzi1111](https://bbs.eeclub.top/user_avatar/bbs.eeclub.top/muzi1111/32/1969_2.png) [@muzi1111](https://bbs.eeclub.top/u/muzi1111)\
发布日期： [2026 年5 月 22 日 09:21 UTC](https://bbs.eeclub.top/t/stm32-hal-pmbus-32/383/1 "2026-05-22T09:21:14Z")

</div>

我用CubeMX配置SMBus，添加X\_CUBE\_SMBUS包，我看文件夹Middlewares中有stm32\_PMBUS\_stack以及stm32\_SMBUS\_stack，但是下一步不知道应该做什么，我不会使用

---

<div class="post-metadata">

作者： ![ABC](https://bbs.eeclub.top/user_avatar/bbs.eeclub.top/abc/32/101_2.png) [@ABC](https://bbs.eeclub.top/u/ABC)\
发布日期： [2026 年5 月 22 日 11:54 UTC](https://bbs.eeclub.top/t/stm32-hal-pmbus-32/383/2 "2026-05-22T11:54:35Z")

</div>

别去硬啃Middleware里面的底层源码，容易看晕。ST的套路都一样，你既然下好了X\_CUBE\_SMBUS包，直接去这个包的安装目录（一般在`STM32Cube\Repository`下）找`Projects`文件夹。里面肯定有对应某些开发板（比如NUCLEO或EVAL）的现成Example。 找到PMBus相关的工程，直接打开看它的`main.c`和`stm32_xx_it.c`。重点看两样东西：第一，主循环里调用的那个Stack Process处理函数；第二，从机收到Command之后的Callback回调是怎么写的。把它的应用层代码抄过来改改就能跑了。

---

<div class="post-metadata">

作者： ![知夏](https://bbs.eeclub.top/user_avatar/bbs.eeclub.top/%E7%9F%A5%E5%A4%8F/32/1860_2.png) [@知夏](https://bbs.eeclub.top/u/%E7%9F%A5%E5%A4%8F)\
发布日期： [2026 年5 月 22 日 12:06 UTC](https://bbs.eeclub.top/t/stm32-hal-pmbus-32/383/3 "2026-05-22T12:06:02Z")

</div>

兄弟别急，这包确实文档写得有点散，我第一次用的时候也懵了半天。

**你现在的状态是：硬件层（CubeMX）配好了，但协议层（stack）不知道怎么接业务代码。**

我按我的理解给你理一下主线，你跟着走：

**第一步：确认你生成了正确的工程结构** 在CubeMX的`Software Packs`里添加X-CUBE-SMBUS时，Mode窗口有两个checkbox：`SMBus stack`和`PMBus extension`，两个都要勾上。生成代码后，你的工程里应该有：

- `Middlewares/ST/STM32_SMBus_Stack/` —— 这是核心协议栈
- `Drivers/BSP/` —— 板级支持（如果你选了的话）

**第二步：理解stack的工作方式** 这个stack不是给你调`HAL_I2C_xxx`用的，它封装了一层状态机。你的代码主要和三个函数打交道：

- `STACK_SMBUS_Init()` —— 初始化，绑定I2C句柄
- `STACK_SMBUS_HostCommand()` —— **主机用** ，发起一次通信
- `STACK_SMBUS_ExecuteCommand()` —— **从机用** ，收到命令后的回调

**第三步：从机怎么写** 从机最关键的是`CMD_Table`，这是一个数组，告诉stack：“当我收到命令码0x01时，我去读哪个寄存器；收到0x02时，我去写哪个寄存器”。

```c
const tSMBUS_CMD_Table MyCmdTable[] = {
    {0x01, MyReadHandler, MyWriteHandler, 1}, // 命令码, 读回调, 写回调, 数据长度
    {0x02, MyReadHandler2, NULL, 2},
};

```

然后在`STACK_SMBUS_ExecuteCommand()`里根据`stackhandle.CurrentCommand`去分发。

**第四步：主机怎么写** 主机简单很多，构造好命令结构体，调`STACK_SMBUS_HostCommand(&stackhandle, &cmd)`就行。注意这个函数是非阻塞的，结果在中断回调里看`stackhandle.State`。

**特别提醒：**

- 官方例程在`Projects`目录下，找跟你板子最接近的，比如NUCLEO-G431RB或者F072的Discovery。
- 一定要看AN4502，这是官方应用笔记，虽然厚但第8章"Configuration"和第9章"Project example"是救命稻草。
- 两块32之间连线时SDA和SCL都要上拉，哪怕板子内部有上拉，外部再加个4.7k更稳，PMBus对信号完整性比I2C敏感。

有问题再贴具体报错，大家帮你看。

---

<div class="post-metadata">

作者： ![CCC](https://bbs.eeclub.top/user_avatar/bbs.eeclub.top/ccc/32/595_2.png) [@CCC](https://bbs.eeclub.top/u/CCC)\
发布日期： [2026 年5 月 22 日 12:21 UTC](https://bbs.eeclub.top/t/stm32-hal-pmbus-32/383/4 "2026-05-22T12:21:13Z")

</div>

你看待这些文件夹的角度可能不太对。`stm32_SMBUS_stack` 是底层的通信层，而 `stm32_PMBUS_stack` 位于其上层，用于处理 PMBus 命令。  
接下来你通常需要：启用 HAL SMBus 外设，将中间件源文件包含到项目中，在 `main()` 中初始化协议栈，并实现库所需的回调函数。如果没有回调函数，协议栈接收到的帧就无处发送了。

---

<div class="post-metadata">

作者： ![muzi1111](https://bbs.eeclub.top/user_avatar/bbs.eeclub.top/muzi1111/32/1969_2.png) [@muzi1111](https://bbs.eeclub.top/u/muzi1111)\
发布日期： [2026 年5 月 22 日 13:13 UTC](https://bbs.eeclub.top/t/stm32-hal-pmbus-32/383/5 "2026-05-22T13:13:32Z")

</div>

感谢各位大佬的回答，我先去尝试一下

---

<div class="post-metadata">

作者： ![zeruns](https://bbs.eeclub.top/user_avatar/bbs.eeclub.top/zeruns/32/7_2.png) [@zeruns](https://bbs.eeclub.top/u/zeruns)\
发布日期： [2026 年5 月 29 日 14:24 UTC](https://bbs.eeclub.top/t/stm32-hal-pmbus-32/383/6 "2026-05-29T14:24:18Z")

</div>

尝试结果怎样？

---

<div class="post-metadata">

作者： ![muzi1111](https://bbs.eeclub.top/user_avatar/bbs.eeclub.top/muzi1111/32/1969_2.png) [@muzi1111](https://bbs.eeclub.top/u/muzi1111)\
发布日期： [2026 年5 月 30 日 03:37 UTC](https://bbs.eeclub.top/t/stm32-hal-pmbus-32/383/7 "2026-05-30T03:37:47Z")

</div>

我把这部分丢给队友做了，精力不够 😅
