目录
在上一篇文章中,我们已经说明了从代码编译到单片机程序下载最后到执行程序的流程。在这个过程中主要涉及到的STM32的外设是Flash和SRAM,也就是单片机的磁盘和内存。但是除了这两个之外,STM32芯片还有很多其他外设指的我们讨论。本篇文章会根据官方手册中的系统结构,谈谈如何理解外设和内核的连接关系。
一、AHB总线协议
AHB总线(Advanced High-performance Bus)不是单纯的地址总线,而是一个综合性的高性能总线系统协议 ,它集成了地址总线 、数据总线 和控制信号线,用于在微控制器或片上系统(SoC)中实现主设备(如CPU、DMA)与从设备(如存储器、外设)之间的高效通信。

之前我们谈过在读写flash和SRAM的时候,有几个关键的线路:ICode、DCode、以及总线矩阵。到了这里我们要明白一点,他们不是独立存在的,而是AHB总线的一部分。
所以我们之前说经过总线矩阵、经过DCode线,其实就是经过AHB总线,只不过先前的说法更具体,这里是一个更框架的理解。
这里有一个System总线,他是Cortex-M内核与外设寄存器之间的高速数据传输通道。这个外设寄存器指的就是各个外设模块内部集成的寄存器,**这些寄存器负责数据存储、状态记录和配置控制。**当内核想要读取、修改外设的某些配置的时候,就可以通过System总线、经过总线矩阵连接到各个外设,从这里读取修改即可。

二、地址总线和数据总线
AHB总线传输过程分为两个阶段:地址阶段 和数据阶段 。地址阶段用于传输地址信号,确定要访问的目标设备或寄存器。地址总线也是AHB总线协议的一个部分。
注意:地址总线只有一个,所有的外设包括内核共用一个地址总线,内核到外设的交互需要先经过地址总线,再经过总线矩阵才能到外设。
- 传输过程 :
- 主设备(Master) (如CPU)将目标地址放置在地址总线上。
- 地址总线 将地址信号传输到总线矩阵(Bus Matrix)。
- 总线矩阵 根据地址信号选择目标从设备(Slave)(如外设寄存器、内存)。
- 关键点 :
- 地址总线仅在地址阶段传输地址信号。
- 地址阶段完成后,地址总线不再传输数据。
数据总线顾名思义就是用来传输数据的,之前谈到的ICode和DCode线就是数据总线的具体应用。

示例:CPU读取外设寄存器的数据
- 地址阶段 :
- CPU将外设寄存器的地址放置在地址总线上。
- 地址总线将地址信号传输到总线矩阵。
- 总线矩阵选择目标外设寄存器。
- 数据阶段 :
- 数据总线从外设寄存器读取数据。
- 数据通过数据总线传输到CPU。
三、SDIO和FSMC外设扩展接口
在系统结构图中可以看到这两个外设。
**SDIO是一种用于访问安全数字(SD)存储卡和其他兼容设备的接口。**它支持多种类型的SD卡,包括SD、SDHC(高容量SD卡)和SDXC(扩展容量SD卡)。SDIO接口允许主机设备(如嵌入式系统)与SD卡进行通信,以读取、写入和管理存储在卡上的数据。
**FSMC是一种灵活的静态存储器控制器,用于访问各种类型的静态存储器,如SRAM、NOR闪存和PSRAM。相当于内存条。**FSMC通过提供一组通用的接口和控制信号,使得嵌入式系统能够轻松连接和管理多种静态存储器设备。
在图中可以看到FSMC是直接连接到总线矩阵的,而SDIO是先经过AHB系统总线的,这种布局能让内存条的读写效率进一步提高。

四、RCC模块与SYSCLK时钟信号
我们前面已经说了许多外设了,但是他们是如何保证数据的有效性的,因为在机器领域,所有的机器设备都是只能读取二进制信号,即高低电平。所以这就必然导致高低电平要以流式串行发送,打个比方:模块A要和模块B进行通信,就需要传递一些数据,但是由于只能传递二进制电平信号,而两个模块之间又通过有限根线连接,所以二进制数据不可能同一时间发送完成,必定会有先后顺序、间隔时间等问题。
而在STM32中,他的做法就是引入SYSCLK系统时钟,即某种晶振周期。然后双方模块设定一个时钟协议,比如我的时钟线收到上升沿的时候,说明过了一个时钟周期,那么我就采样数据线的电平情况;比如时钟线收到下降沿的时候,说明又过了一个时钟周期,我可以选择继续采样或者做出应答(通过把数据线置1/0)。
在系统结构图中可以看到一个外设模块---RCC,他的作用就是修改晶振到内核的路径,不同的路径会有不同的电子元件对时钟信号进行分频、或者倍频。

过程解释:
- 晶振与初始时钟 :
- 当系统通电后,晶振开始工作,产生一个基础的时钟信号。
- 经过振荡电路的稳定处理后,产生一个固定的8MHz频率的时钟信号。
- 这个8MHz的时钟信号最初被用作系统的时钟源。
- RCC模块的作用 :
- RCC模块负责管理和配置系统的时钟源。
- 它首先利用已经存在的8MHz时钟信号让自己运行起来。
- 然后,RCC模块可以通过配置对晶振路径进行倍频或分频操作,从而改变系统的时钟频率。
- 时钟频率的调整 :
- 通过修改晶振的电路路径(例如,通过配置PLL倍频器),可以改变时钟信号的频率。
- 这种调整可以影响整个系统的时钟频率,以满足不同的性能需求或节能要求。
- 外设通信 :
- 系统使用固定的时钟频率与外设进行通信。
- 在这个例子中,最初使用的是8MHz的时钟频率,但随后可以根据需要进行调整。
- 没有经过AHB总线的外设如Flash、SRAM(因为他们需要频繁访问,直接使用内核相同的时钟频率能大大提高运行效率)直接使用的就是SYSCLK与内核进行通信。
其中,RCC可以配置的路径一般有以下三种:

(1)HSI路径
路径 :
HSI(8MHz内部RC振荡器) → (无分频) → SYSCLK
特点:
直接使用内部8MHz时钟,无需外部晶振。
无需PLL倍频,路径简单,启动速度快。
适用于低功耗或对时钟精度要求不高的场景。
(2)HSE路径
路径 :
HSE(外部晶振,如8MHz) → (无分频) → SYSCLK
特点:
直接使用外部晶振时,SYSCLK频率等于HSE频率。
通过PLL倍频时,SYSCLK频率可大幅提高(如8MHz → 72MHz)。
适用于对时钟精度和性能要求较高的场景。
(3)PLL路径
路径 :
HSI/HSE → PLL(倍频) → SYSCLK
特点:
PLL可以将HSI或HSE的频率乘以一个整数倍(如2倍、4倍、8倍等)。
例如:
HSI(8MHz) → PLL(×9) → SYSCLK(72MHz)
HSE(25MHz) → PLL(×6.72) → SYSCLK(168MHz)
适用于需要高频率时钟的场景,如高速通信或复杂计算。
五、其他经过AHB总线外设的时钟
(1)为什么要针对不同外设使用不同的时钟频率?
结构图中除了SYSCLK之外,还有APB总线以及桥接APB的总线APB2、APB1。他们是其他更为丰富的外设使用的时钟频率。
那么有人就会问了,你为什么不能做到对每一个外设给予公平的时钟,而是区别对待?
所以一方面是外设的硬件设备并不足以支撑他那么高速的时钟频率、另一方面是协议限制了外设的时钟频率必须在特定范围内。同时,如果所有的外设都使用SYSCLK作为时钟频率的话,芯片的发热会变得严重,反过来导致性能下降。由此,必须要堆SYSCLK进行分频处理,得到各种外设较为合适的方案。
HCLK
HCLK是AHB总线的时钟频率 ,其作用是为AHB总线上的设备(如CPU内核、存储器、DMA等)提供时钟信号。当HCLK和SYSCLK不同时,是通过AHB预分频器实现时钟频率的分配和调整。
SYSCLK → 预分频器(Prescaler) → HCLK
HCLK的存在是时钟树设计的必要条件,直接生成PCLK2和PCLK1将导致系统灵活性丧失、功耗浪费和设计复杂度增加。通过HCLK作为分频的源头,可以实现高效、灵活的时钟管理。就是为了分层设计人为增加的一层罢了。当需要高性能的时候可以直接操作HCLK来对整个外设系统进行效率提升、而不用一个个调整(如果直接使用SYSCLK对每个外设模块进行分配得到时钟频率,则无法统一管理)。
APB1
- 定义 :
- APB1是高级外设总线1 (Advanced Peripheral Bus 1)的简称,属于ARM Cortex-M系列微控制器 中的低速外设总线。
- 它连接低功耗、低速率的外设模块,如定时器、UART、I2C、SPI等。
- 特点 :
- 低功耗:设计用于低速率外设,功耗较低。
- 低速率 :最大时钟频率通常为42 MHz(具体取决于芯片型号)。
- 简单协议:使用简单的握手协议,适合低复杂度外设。
APB2
- 定义 :
- APB2是高级外设总线2 (Advanced Peripheral Bus 2)的简称,属于ARM Cortex-M系列微控制器 中的高速外设总线。
- 它连接高带宽、高实时性要求的外设模块,如ADC、高级定时器、GPIO等。
- 特点 :
- 高带宽:支持更高的数据传输速率。
- 高实时性:适用于对时序要求严格的外设。
- 复杂协议:相比APB1,APB2的协议更复杂,支持更多功能。
那么到这里相信你就可以理解为什么我们在使用库函数初始化外设的时候往往需要先配置其时钟频率了吧!
(2)桥接器
桥接器的一个核心作用正是控制AHB协议和APB协议的信号转换,从而解决核心与外设因时钟频率差异导致的数据读取问题。

1. 频率转换
问题 :
CPU和高速外设需要高频时钟(如168MHz),而低速外设(如I2C)无法承受高频。
解决方案 :
桥接器将AHB高频时钟分频为APB低速时钟。
- 示例 :
AHB=168MHz → APB2=84MHz → APB1=42MHz2. 信号转换
- AHB协议 :
- 支持突发传输(Burst Transfer)
- 数据总线宽度为32位
- APB协议 :
- 单次传输(Single Transfer)
- 数据总线宽度通常为16位或8位
- 桥接器功能 :
将AHB的突发传输拆分为APB的单次传输,并适配数据总线宽度。3. 延迟隔离
AHB访问延迟 :
通常为1个时钟周期(如168MHz下约6ns)
APB访问延迟 :
可能增加1-2个时钟周期(如42MHz下约23-47ns)
桥接器作用 :
隐藏APB的低速特性,使CPU无需感知外设速度差异。
六、DMA
DMA 是一种硬件机制,允许外设**(这里的外设包含片上外设和片外外设)**或内存之间直接传输数据,而无需CPU参与。它通过独立的DMA控制器(DMA Controller)管理数据传输,显著提升系统效率,减少CPU负载。
在没有DMA的情况下,CPU需要全程参与数据传输,主要步骤如下:
(1)配置外设寄存器
设置外设模式:例如,配置USART为发送模式,SPI为主模式等。
设置传输参数:如波特率、数据位宽、停止位等。
启用外设:通过设置控制寄存器中的使能位,启动外设。
(2)从内存读取数据
CPU通过内存地址总线访问指定的内存区域,读取需要传输的数据。
数据通常存储在RAM中,CPU使用通用寄存器(如ARM Cortex-M中的R0-R12)暂存数据。
(3)将数据写入外设寄存器
CPU通过外设地址总线 访问外设的寄存器,将数据写入外设的数据寄存器(如USART的
TDR
寄存器)。外设接收到数据后,开始处理(如通过串口发送数据)。
(4)轮询或等待传输完成
轮询方式:
CPU不断读取外设的状态寄存器(如USART的
SR
寄存器),检查传输是否完成。如果未完成,CPU继续轮询,直到传输完成。
中断方式:
外设传输完成后,触发中断。
CPU响应中断,执行中断服务程序(ISR),继续处理后续数据。
(5)重复上述步骤
- 如果需要传输多个数据,CPU需要重复上述步骤,直到所有数据传输完成。
因为之前想要访问一个外设必须要通过核心CPU的处理,即CPU先从外设拿到数据,再通过某些引脚传输出去,但是由于CPU要做的事情太多了,一旦你要拿数据非常频繁,CPU就会频繁中断其他其他任务,而耗费大量的时间来处理这个不需要什么运算的事情,大大降低了效率。所以设计出了DMA结构,他允许直接通过总线(如AHB、APB)访问外设寄存器或内存。当数据已经读到了合适的位置后,再通知CPU内核来处理。

DMA的核心原理
- 独立于CPU的传输 :
- DMA控制器负责数据搬运,CPU可同时执行其他任务,避免因数据传输导致的性能瓶颈。
- 案例:在高速ADC采样中,DMA可自动将采样数据从外设缓冲区传输到内存,无需CPU干预。
- 数据传输类型 :
- 内存到内存:直接在两个内存区域之间传输数据。
- 内存到外设:将数据从内存传输到外设(如UART、SPI)。
- 外设到内存:将外设数据(如ADC采样值)传输到内存。
- 触发方式 :
- 硬件触发:由外设事件(如ADC转换完成)触发。
- 软件触发:通过CPU指令手动启动。
DMA的工作流程
- 初始化阶段 :
- CPU配置DMA控制器(如源地址、目标地址、传输长度、传输方向等)。
- CPU启动DMA传输后,可继续执行其他任务。
- 传输阶段 :
- DMA控制器独立管理数据搬运,无需CPU干预。
- 数据从外设直接写入内存(或反之),绕过CPU。
- 完成阶段 :
- DMA传输完成后,触发中断通知CPU。
- CPU处理后续任务(如数据处理、结果反馈)。
