GPIO操作

1.1GPIO结构
1.2固件库组织代码步骤
1.3IO口操作步骤(常用技巧总结)
1.4IO口位操作**

1.1 GPIO结构

**
(1)基本结构
在这里插入图片描述
(2)工作模式
在这里插入图片描述
(3)寄存器地址
typedef struct //stm32f10x.h 定位到 GPIO_TypeDef 定义处 ,
{
__IO uint32_t CRL;
__IO uint32_t CRH;
__IO uint32_t IDR;
__IO uint32_t ODR;
__IO uint32_t BSRR;
__IO uint32_t BRR;
__IO uint32_t LCKR;
} GPIO_TypeDef;
*#define GPIOA ((GPIO_TypeDef ) GPIOA_BASE);
//GPIOA是指针、GPIOA_BASE代表地址、(GPIO_TypeDef *)代表强制转换类型为
//GPIO_TypeDef结构体,即GPIOA指向地址GPIOA_BASE,GPIOA_BASE所
//代表地址存放的数据类型为GPIO_TypeDef。
其中:#define GPIOA_BASE (APB2PERIPH_BASE + 0x0800);
#define APB2PERIPH_BASE (PERIPH_BASE + 0x10000);
#define PERIPH_BASE ((uint32_t)0x40000000) ;
GPIOA的寄存器的地址=GPIOA 基地址+寄存器相对 GPIOA 基地址的偏移值
(4)7寄存器
①端口配置寄存器
在这里插入图片描述
该寄存器的复位值为 0X4444 4444,复位值其实就是配置端口为浮空输入模式。从上图还可以得出:STM32 的 CRL 控制着每组 IO 端口(A~G)的低 8 位的模式。每个 IO 端口的位占用CRL的4个位,高两位为CNF,低两位为 MODE。
GPIOx_CRH为高8位端口配置寄存器,与CRL基本相同,不再赘述.
②端口输入寄存器
在这里插入图片描述
要想知道某个 IO 口的电平状态,你只要读这个寄存器,再看某个位的状态就可以了。
③端口输出寄存器
ODR 是一个端口输出数据寄存器,也只用了低 16 位。该寄存器为可读写,从该寄存器读出来的数据可以用于判断当前 IO 口的输出状态。而向该寄存器写数据,则可以控制某个 IO 口的输出电平。
在这里插入图片描述
④端口位设置/清除寄存器
在这里插入图片描述
和ODR 寄存器具有类似的作用,都可以用来设置 GPIO 端口的输出位是 1 还是 0。
如你要设置 GPIOA 的第 1 个端口值为 1,那么你只需要往寄存器 BSRR 的低 16 位对应位写 1 即可:GPIOA->BSRR=1<<1;
如果你要设置 GPIOA 的第 1 个端口值为 0, 你只需要往寄存器高 16 位对应为写 1 即可:GPIOA->BSRR=1<<(16+1)
该寄存器往相应位写 0 是无影响的,所以我们要设置某些位,我们不用管其他位的值。
⑤端口位清除寄存器
在这里插入图片描述
⑥端口配置锁定寄存器
在这里插入图片描述
**

1.2 固件库组织代码步骤

**
(1)确定入口参数
**入口参数:函数的的输入参数,也就是形参,给子函数提供运算值的参数。
定义/初始化:对定义变量或者结构体赋初值。
在头文件 stm32f10x_gpio.h头文件中,定义 GPIO 初始化函数为:
void GPIO_Init(GPIO_TypeDef
GPIOx, GPIO_InitTypeDef
GPIO_InitStruct);
首先,函数的入口参数是 GPIO_TypeDef 类型指针和 GPIO_InitTypeDef 类
型指针。
(2)定义入口参数
这个函数有两个参数, 第一个参数是用来指定 GPIO,取值范围为 GPIOA~GPIOG。 双击第二个入口参数 GPIO_InitTypeDef 后右键选择“Go to definition…”。
在这里插入图片描述
分析结构体有 3 个成员变量,即一个 GPIO 口的状态是由速度(Speed)和模式(Mode)来决定的。我们首先要
定义入口参数即定义一个结构体变量
,下面我们定义:
GPIO_InitTypeDef GPIO_InitStructure;
(3)初始化入口参数
要初始化结构体变量 GPIO_InitStructure,首先要初始化成员变量GPIO_Pin,**这个变量到底可以设置哪些值呢?**这些值的范围有什么规定吗?这里我们就要找到 **GPIO_Init()**函数的实现处, 同样,双击 GPIO_Init,右键点击“Go to definition of …”,这样光标定位到 stm32f10x_gpio.c 文件中的 GPIO_Init 函数体开始处
在这里插入图片描述
其中assert_param 函数式对入口参数的有效性进行判断,所以我们可以从这个函数入手,确定我们的入口参数的范围 。第一行是对第一个参数 GPIOx 进行有效性判断,双击“IS_GPIO_ALL_PERIPH”右键点击“go to defition of…” 定位到了下面的定义:
在这里插入图片描述
GPIOx 的取值规定只允许是 GPIOA~GPIOG。
在这里插入图片描述
GPIO_InitStruct->GPIO_Mode 成员的取值范围只能是上面定义的 8 种。这 8种模式是通过一个枚举类型组织在一起的。
同样的方法我们双击“IS_GPIO_PIN” 右键点击“go to defition of…” ,定位到下面的定义:
GPIO_Pin 成员变量的取值范围为 0x0000 到 0xffff,初始化方式:①直接赋16 位数字;②在 IS_GPIO_PIN(PIN)宏定义的上面还有数行宏定义,MDK将这些数字的意思通过宏定义出来,增强可读性。
(4)组织代码
GPIO_InitTypeDef GPIO_InitStructure; //定义入口参数//初始化入口参数:
GPIO_InitStructure.GPIO_Pin= GPIO_Pin_5| GPIO_Pin_6| GPIO_Pin_7; //指定端口
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//速度
GPIO_Init(GPIOB, &GPIO_InitStructure); //初始化GPIO

**

1.3 IO口操作步骤

**
在固件库中,GPIO 端口操作对应的库函数函数以及相关定义在文件stm32f10x_gpio.h 和 stm32f10x_gpio.c 中。
每组IO口对应7个寄存器,控制一组GPIO的16个IO口,而具体寄存器参数参考STM32F1中文参考手册8.2;

IO口操作步骤为:
1) 使能 IO 口时钟。调用函数为 RCC_APB2PeriphClockCmd()。
2) 初始化 IO 参数。调用函数 GPIO_Init();
3) 操作 IO。操作 IO 的方法如下。

(1) 使能时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOE,ENABLE);
//使能 PB,PE 端口时钟
(2) 初始化IO
(3) 操作IO

在这里插入图片描述
**

1.4 IO口位操作

**
(1)位带操作
在这里插入图片描述
eg1:
#include “sys.h”
PAout(1)=1:// 设置GPIOA 的第一个管脚 GPIOA.1 为 1,实际设置寄存器ODR/IDR
eg2:
#include “sys.h”
#define LED0 PBout(5)// LED 端口定义:DS0
LED0=1;
(2)库函数操作
GPIO_SetBits(GPIOB, GPIO_Pin_5); //设置 GPIOB.5 输出 1,等同 LED0=1;
GPIO_ResetBits (GPIOB, GPIO_Pin_5); //设置 GPIOB.5 输出 0,等同 LED0=0;
库函数操作就直接调用两个函数即可控制 IO 输出高低电平。
(3)寄存器操作
BRR/BSRR 的方式来操作 IO 口输出高低电平,方法如下:
GPIOB->BRR=GPIO_Pin_5; //设置 GPIOB.5 输出 1,等同 LED0=1;
GPIOE->BSRR=GPIO_Pin_5; //设置 GPIOB.5 输出 0,等同 LED0=0;

猜你喜欢

转载自blog.csdn.net/qq_38693598/article/details/85641992
今日推荐