[技术讨论] MCU内部的”高速公路“:AHB、APB2、APB1三大总线扫盲

📅 2026/7/24 11:09:22
[技术讨论] MCU内部的”高速公路“:AHB、APB2、APB1三大总线扫盲
在很多MCU的库代码里一般都会有类似下面的时钟使能配置宏不同厂商在配置模式上会存在差异即如果你需要使用MCU的某个外设首先就需要使能外设对应的时钟即让外设正常工作起来并且会根据所挂载的总线不同会进行区分然后在数据手册里一般也会有专门一个章节一般称为时钟和复位控制RCC来专门讲解相关内容那到底这几条总线AHBAPB1APB2是什么呢有什么作用呢我们继续往下看其实对从事基于MCU的嵌入式软件攻城狮来说应该都知道MCU里面的AHB、APB2、APB1三大总线吧即使了解不深起码也多少熟悉一点因为有时候很多软件问题和Bug什么的都是与它们息息相关的比如低功耗产品的功耗偏高达不到要求、串口通信收不到数据、需要大量传输音频数据和时钟配置错误导致的数据通信异常等等。因此我们就有必要来深入认识和了解一下这三大总线来一次比较彻底的扫盲行动。其实可以如文章标题那样我们将AHB、APB2、APB1三大总线理解为MCU芯片内部连接各个部件和外设的“高速公路”它们分工明确主要负责在处理器核心、内存和各种外设之间传输数据和控制信号等。而这个“高速公路”的高速也是相对的含义就是说这三大总线支持的速度是不一样的AHB最快APB2次之APB1相对较慢不同的外设挂载在不同的总线上。先简单介绍一下三大总线AHBAdvanced High Performance Bus高级高性能总线其总线频率一般等于系统时钟这是系统的主干线追求高性能和高速度直接连接对速度要求极高的核心部件确保数据能快速流通即主要负责连接处理器、DMA等一些内部接口APB2Advanced Peripheral Bus 2高级外设总线2专门服务于对速度有较高要求的外设让它们能更快地与内核交换数据即主要负责连接外围设备简称外设APB1Advanced Peripheral Bus 1高级外设总线1主要为了功耗优化而设计专门连接对速度不那么敏感的外设也主要负责连接外围设备它的时钟频率通常较低可以有效节省电能。其中APB总线架构不像 AHB那样可以支持多个主模块在APB里面唯一的主模块就是APB 桥这个APB桥就是连接AHB和APB中间的玩意下面会说到。所以从其含义和主要作用就可以看出其设计之讲究分工明确互不干扰相辅相成。再来看看三大总线的架构形式通过下面这张图就能明白三大总线的基本架构形式了上面这张图里的低速是相对高速而言的并不是真正意义上的速度慢只是为了更好的区分APB2和APB1比如STM32的某些系列的AHB最高是72MAPB2是72MAPB1是36MArtery的某些系列的AHB最高是240MAPB2是120MAPB1也是120M等等。通过这张图也可以看出AHB总线是高速核心干道连接了一些最重要的区域而APB2和APB1根据外设类型分别连接着不同速度的外设模块。另外三大总线也不是孤立工作的它们通过总线桥接器相互连接起来形成了一个完整的系统如下面某Cortex-M4核的系列MCU的功能框图所示该功能框图明确了哪些外设挂载在哪条总线上面并且还标注了各总线支持的最高频率比如如果你需要配置SPI1的时钟频率在设置分频系数之前肯定要先确定SPI1是挂载在哪条总线上及该总线配置的最高频率是多少这样你才能最终确定SPI1的时钟频率是你想要配置的:另外也可以看出APB2和APB1都是通过AHB-APB桥接器连接到AHB总线上面的这种架构不仅保证了高速外设的读写速度还可以兼顾低速外设的功耗管理。之所以有相对高速而言的低速外设主要目的是为了降低功耗。因为在电池供电的低功耗产品中功耗是非常重要的设计指标对于很多对速度要求不高的外设我们使用低速外设就能满足设计需求还可以管理功耗比如我们通过控制APB2执行降频运行可以一定程度上延长电池的使用寿命。接着再来说说与总线时钟配置相关的一些问题和排查方法。我们在实际代码开发时其实会经常遇到与时钟配置有关的问题一般排查的步骤可以参考如下所述先检查对于的外设总线时钟是否使能之前我就遇到过一次串口通信的时候收不到主机发来的数据后来排查发现是串口对应的外设时钟没有使能导致的这种问题看似简单在代码工程中有时候却不容易定位再检查时钟频率是否正确特别是对应的总线频率不能超过其最高频率最后可以检查一下外部或者内部时钟源是不是稳定特别是当你用的是外部晶振的时候。对于功耗优化的时候一直很难调试到最优值的时候可以尝试将高速外设修改为低速外设比如用基本或者通用定时器来代替高级定时器等另外通过代码反复精准的使能或禁止外设时钟等操作也可以降低功耗毕竟功耗优化是一个需要耐心和信心慢慢调试的过程。如果需要频繁大量传输音视频数据可以考虑使用通过AHB总线通信的DMA外设来避开CPU干预等等。在项目开发时一定要明确清楚所用的外设归属于哪一条总线这样在遇到问题或者功能和性能优化的时候才能知道怎么修改而不是模棱两可。其实我们再来看三大总线的框图也可以理解为APB2总线和APB1总线是AHB总线的分支和继承两者实现目标不同应用场景不一样而已。另外有些系列的MCU可能还有将AHB总线细分为AHB1 和AHB2并将其中之一通过总线桥接器连接到APB1和APB2之所以这么设计一般是基于性能优化、时钟管理、功耗控制以及硬件设计的物理限制等因素简单一点来说这就像把一条高速公路单个AHB扩建为拥有快慢车道和专用匝道的复合路网AHB1和AHB2以确保不同速度的车辆外设/内核都能高效通行不会互相堵塞。比如下面某个厂商的某个系列的MCU的功能框图所示将AHB细分为了AHB1和AHB2其中AHB2挂载了DAC外设和GPIO外设AHB1连接了APB1和APB2。比如下面这段代码就是使能GPIOA和GPIOB时钟的明显可以看到是挂载在AHB2上面的而DAC同样也是挂载在AHB2总线上面的综上一般情况下通过MCU数据手册里的功能框图或者MCU外设库代码都能知道外设挂载在哪个总线上面。有些外设库代码是以下面这种带形参的函数接口形式来使能或禁止外设时钟的其中的CRM就是时钟和复位管理的意思比如你要使能SPI2外设的时钟这么操作即可复制crm_periph_clock_enable(CRM_SPI2_PERIPH_CLOCK,TRUE);有些库代码是以统一管理外设时钟使能的方式实现的有些是分外设单独管理实现的归根结底本质不变。不仅如此有些系列的MCU可能还有将AHB总线细分为AHB1 AHB2和AHB3但一般常见的APBx都只有APB1和APB2如下图所示不过再怎么变化只是把不同功能模块挂载在不同总线上只要你看的懂功能框图会用库代码就没什么大问题然后在用户手册上也会有对应的可配置的寄存器因此三大总线的基本架构形式基本上都只用AHB作为参考至于其继承的AHBxx1,2,3,……因MCU不同而存在差异需要阅读对应的数据手册才能知道。以上便是对MCU的AHB、APB2和APB1三大总线的一些扫盲解读希望可以给你带来一些有用的东西~~---------------------作者dffzh链接https://bbs.21ic.com/icview-3507106-1-1.html来源21ic.com此文章已获得原创/原创奖标签著作权归21ic所有任何人未经允许禁止转载。