3. 常见总线协议(二):AMBA APB总线协议详解、低功耗外设总线设计
好,咱们接着聊总线。上一章我们把AHB这个“高速公路”讲透了,这一章来聊聊它的“小区道路”——APB总线。
APB,全称Advanced Peripheral Bus。说白了,它就是ARM公司专门为低功耗外设设计的一套总线协议。你想想看,芯片里那些UART、I2C、GPIO、定时器,它们对带宽要求不高,但数量多、分布散。如果都用AHB去连,那功耗和面积都扛不住。APB就是干这个活的——简单、省电、够用。
3.1 APB协议的核心特征
我个人习惯把APB总结为三个关键词:低功耗、无流水线、单主控。
- 低功耗:每次传输完成后,总线自动回到IDLE状态。没有时钟翻转的浪费。
- 无流水线:所有传输都是“地址-数据”紧耦合,一拍完成。不像AHB那样可以地址和数据重叠。
- 单主控:整个APB总线只有一个主设备(通常是桥接器),所有外设都是从设备。不需要仲裁。
核心要点:APB的接口信号只有9个,比AHB少了将近一半。你想想看,信号少意味着什么?连线少、面积小、功耗低。这就是它存在的意义。
3.2 状态机与传输时序
APB的状态机只有三个状态:IDLE、SETUP、ACCESS。简单到令人发指。
我刚开始学的时候觉得这也太简单了吧?后来在项目中才发现,越简单的东西越不容易出错。APB的时序,你只要记住一个原则:地址在SETUP阶段给出,数据在ACCESS阶段完成。
来看一个典型的写传输时序:
// APB写传输时序(伪代码描述)
// 时钟上升沿触发
// 1. IDLE状态:PSELx=0, PENABLE=0
// 2. 进入SETUP:PSELx=1, PADDR=有效地址, PWRITE=1, PWDATA=有效数据
// PENABLE保持为0
// 3. 下一个时钟沿进入ACCESS:PENABLE=1
// 从设备在此时采样数据
// 4. 传输完成,回到IDLE或进入下一次SETUP
读传输类似,只是数据方向相反。从设备在ACCESS阶段把数据放到PRDATA上。
我的经验:APB的从设备设计,关键就是处理好PREADY信号。如果外设响应慢(比如EEPROM),你可以在ACCESS阶段拉低PREADY,插入等待周期。我曾经遇到一个坑:某个外设的PREADY逻辑写错了,导致总线一直卡在ACCESS状态,整个系统都挂掉了。排查了整整两天。
3.3 APB桥接器设计
APB桥接器,就是连接AHB和APB的那个“翻译官”。它负责把AHB的高性能传输转换成APB的简单传输。
桥接器的核心逻辑其实就三件事:
- 地址译码:根据地址范围,选中对应的APB从设备。
- 时序转换:把AHB的流水线时序,转成APB的两拍时序。
- 数据缓冲:处理跨时钟域或数据宽度的匹配。
我建议你在设计桥接器时,重点关注地址译码的优先级。如果多个从设备的地址范围有重叠,那可就麻烦了。我见过一个案例,两个外设的地址映射写错了,结果写GPIO的时候,把定时器的寄存器也给改了。调试的时候发现定时器莫名其妙地触发中断,查了三天才找到原因。
3.4 低功耗外设总线设计
APB本身就是为低功耗设计的,但如果你想让功耗再低一点,有几个技巧:
- 时钟门控:当APB总线空闲时,直接把时钟关掉。这招最狠,能省掉60%以上的动态功耗。
- 地址过滤:在桥接器里加一个地址比较器,只有地址命中时才拉高PSELx。否则,外设的输入端口不会翻转。
- 数据保持:在IDLE状态,把PWDATA和PADDR保持在上一次的值。减少信号翻转次数。
注意:时钟门控不是随便加的。你得确保在门控打开时,时钟的第一个沿是干净的,没有毛刺。我建议用标准的ICG(集成时钟门控)单元,别自己用与门拼。我曾经吃过这个亏——自己搭的时钟门控产生了毛刺,导致外设误触发,流片回来才发现,悔之晚矣。
3.5 知识体系结构图
下面这张图,是我自己总结的APB总线知识体系。你可以把它当作一个快速索引:
3.6 实战中的避坑指南
最后,分享几个我在项目中踩过的坑,希望能帮你少走弯路:
- PREADY的默认值:如果从设备不需要等待周期,PREADY必须默认拉高。我曾经见过一个设计,PREADY默认是低电平,结果总线每次传输都多等一个周期,性能直接砍半。
- 地址对齐:APB的地址必须是32位对齐的。如果你要访问一个字节,也得给完整的32位地址。这个和AHB不一样,AHB支持非对齐传输。
- 复位状态:APB总线在复位后必须进入IDLE状态。PSELx和PENABLE都要清零。否则,外设可能会误以为有传输请求。
总结一下:APB总线虽然简单,但它是SoC低功耗设计的基石。你只要把状态机搞明白,把PREADY处理好,剩下的就是体力活了。嗯,这一章就到这里,下一章我们聊聊更复杂的AXI总线——那个才是真正的大杀器。
可可精品资料库