国外课栈 - 国外电子信息技术

深入探索STM32硬件抽象层 - GPIO

 二维码 5
文章附图

背景知识视频教程

STM32外设映射和HAL处理程序

每个STM32外设都通过几条总线互连到MCU内核,如下图所示。

  • 系统总线将Cortex-M内核的系统总线连接到BusMatrix,后者管理内核和DMA之间的仲裁。 核心和DMA都充当主服务器。
  • DMA总线将DMA的高级高性能总线(AHB)主接口连接到BusMatrix,后者管理CPU和DMA对SRAM,闪存和外设的访问
  • BusMatrix管理核心系统总线和DMA主总线之间的访问仲裁。 仲裁使用循环算法。 BusMatrix由两个主机(CPU,DMA)和四个从机(闪存接口,SRAM,带有AHB到高级外围总线(APB)桥的AHB1和AHB2)组成。 AHB外设通过BusMatrix连接在系统总线上,以允许DMA访问
  • AHB到APB的桥接器在AHB和APB总线之间提供了完整的同步连接,在该总线上连接了大多数外围设备

正如我们将在看到的那样,每条总线都连接到不同的时钟源,时钟源决定了连接到该总线的外设的最大速度。

外围设备已映射到4GB地址空间的特定区域,从0x4000 0000开始,一直持续到0x5FFF FFFF。 该区域被进一步划分为几个子区域,每个子区域映射到一个特定的外围设备,如下图所示。

该空间的组织方式以及外围设备的映射方式特定于给定的STM32微控制器。 例如,在STM32F030微控制器中,AHB2总线映射到范围从0x4800 0000到0x4800 17FF的区域。 这意味着该区域为6144字节宽。 该区域进一步分为几个子区域,每个子区域对应一个特定的外围设备。GPIOA外设(管理与PORT-A连接的所有引脚)从0x4800 0000映射到0x4800 03FF,这意味着它占用了1KB的别名外设存储器。 该内存映射空间的组织方式又取决于特定的外围设备。 下表1显示了GPIO外设的存储器布局。

控制外围设备以修改和读取这些映射区域的每个寄存器。 例如,继续以GPIOA外设为例,要使PA5引脚作为输出引脚,我们必须配置MODER寄存器,以便将位[11:10]配置为01(对应于通用输出模式),如上图所示。接下来,将引脚拉高,我们必须设置相应的输出数据寄存器(ODR)中的位[5],根据下表映射到GPIOA + 0x14存储器位置,即0x4800 0000 + 0x14。

以下最小示例显示了如何使用指针访问STM32F030 MCU中的GPIOA外设映射的存储器。

int main(void) {
   
volatile uint32_t * GPIOA_MODER = 0x0, * GPIOA_ODR = 0x0;
   GPIOA_MODER = (
uint32_t * ) 0x48000000; // Address of the GPIOA->MODER register
   GPIOA_ODR = (
uint32_t * )(0x48000000 + 0x14); // Address of the GPIOA->ODR register
   
// This ensure that the peripheral is enabled and connected to the AHB1 bus
   __HAL_RCC_GPIOA_CLK_ENABLE();
   * GPIOA_MODER = * GPIOA_MODER | 0x400;
// Sets MODER[11:10] = 0x1
   * GPIOA_ODR = * GPIOA_ODR | 0x20;
// Sets ODR[5] = 0x1, that is pulls PA5 high
   
while (1);
}

再次需要澄清的是,每个STM32系列(F0,F1等)和给定系列的每个成员(STM32F030,STM32F1等)都提供其外设子集,这些子集被映射到特定地址。 此外,STM32系列之间外设的实现方式也有所不同。

HAL角色之一是从特定的外围设备映射中抽象出来。 这是通过为每个外围设备定义几个处理程序来完成的。 处理程序只不过是C结构,C结构的引用用于指向实际的外设地址。 让我们看看其中之一。

如下配置PA5引脚:

/*Configure GPIO pin : PA5 */
GPIO_InitStruct.Pin = GPIO_PIN_5
;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP
;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct)
;

此处,GPIOA变量是以这种方式定义的GPIO_TypeDef类型的指针:

typedef struct {
volatile uint32_t MODER;
volatile uint32_t OTYPER;
volatile uint32_t OSPEEDR;
volatile uint32_t PUPDR;
volatile uint32_t IDR;
volatile uint32_t ODR;
volatile uint32_t BSRR;
volatile uint32_t LCKR;
volatile uint32_t AFR[2];
volatile uint32_t BRR;
} GPIO_TypeDef;

定义GPIOA指针,使其指向地址0x4800 0000:

GPIO_TypeDef *GPIOA = 0x48000000;
GPIOA->MODER |
= 0x400;
GPIOA->ODR |
= 0x20;

GPIO配置

模式

GPIO备用功能

速度

驱动GPIO

取消初始化GPIO

阅读完整文档

文章分类: 嵌入式STM32
分享到: