1. GPIO 端口引脚多 --> 就要选定需要控制的 特定引脚
2.GPIO 功能如此丰富 --> 配置需要的 特定功能
3. 控制 LED 的亮和灭--> 设置 GPIO 输出电压的 高低
GPIO寄存器:

说明:7 个寄存器,相应功能在文档上有详细说明。它们可以分为以下 4 类,其
功能简要概括如下 :
1)配置寄存器 :选定 GPIO 的特定功能,最基本的如选择作为输入还是输出端口。
2)数据寄存器 :保存了 GPIO 的输入电平或将要输出的电平。
3)位控制寄存器 :设置某引脚的数据 为 1 或 0,控制输出的电平。
4)锁定寄存器 :设置某锁定引脚后,就不能修改其配置。
端口配置高寄存器

CRH 是高寄存器,用来配置高 8 位引脚 :pin8 ~ pin15 ;还有一个称为 CRL 寄存器,如果我们要配置 pin0 ~pin7 引脚,则要在寄存器 CRL 中进行配置。
端口位设置/清除寄存器

例如 :对 x 端口的寄存器 GPIOx_BSRR 的第 0 位(BS0) 进行写 1,则 x 端口的第 0
引脚被设置为 1,输出高电平,若要令第 0 引脚再输出低电平 ,则需要向 GPIOx_BSRR 的
第 16 位(BR0)写 1。
4. 地址映射
先看代码:来自stm32f10x.h 源码
1. #define GPIOC_BASE (APB2PERIPH_BASE + 0x1000)
2. #define APB2PERIPH_BASE (PERIPH_BASE + 0x10000)
3. #define PERIPH_BASE ((uint32_t)0x40000000)
外设基地址:PERIPH_BASE这个宏, 宏展开为 0x4000 0000
总线基地址:APB2PERIPH_BASE这个宏 ,宏展开为 0x4001 0000 (PERIPH_BASE 加上偏移地址 0x1 0000)
寄存器组基地址:GPIOC_BASE 这个宏, 宏展开为 0x4001 1000(APB2PERIPH_BASE 加上偏移地址0x1000)
举例:1. #define GPIOC_CRH (GPIOC_BASE + 0x04)(并不这样)
实际情况:
1. #define GPIOA ((GPIO_TypeDef *) GPIOA_BASE)
2. #define GPIOB ((GPIO_TypeDef *) GPIOB_BASE)
3. #define GPIOC ((GPIO_TypeDef *) GPIOC_BASE)
GPIO_TypeDef :
typedef struct
2. {
3. __IO uint32_t CRL;
4. __IO uint32_t CRH;
5. __IO uint32_t IDR;
6. __IO uint32_t ODR;
7. __IO uint32_t BSRR;
8. __IO uint32_t BRR;
9. __IO uint32_t LCKR;
10. } GPIO_TypeDef;
__IO :
1. #define __O volatile
2. #define __IO volatile
结构体内定义了7个 __IOuint32_t类型的变量。这些变量每个都为32位,每个变量占内存空间4个字节。这个结构体的首地址(变量CRL 的地址)若为0x40011000,那么结构体中第二个变量(CRH)的地址即为0x40011000 +0x04,加上的这个0x04 ,正是代表 4个字节地址的偏移量。所以只要我们匹配了结构体的首地址,就可以确定各寄存器的具体地址了。
(GPIO_TypeDef*) : 在这里的作用则是把 GPIOA_BASE地址转换为GPIO_TypeDef 结构体指针类型。
所以修改GPIO方法:
1. GPIO_TypeDef * GPIOx; //定义一个 GPIO_TypeDef 型结构体指针 GPIOx
2. GPIOx = GPIOA; //把指针地址设置为宏 GPIOA 地址
3. GPIOx->CRL = 0xffffffff; //通过指针访问并修改 GPIOA_CRL 寄存器
|