微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > STM32的GPIO使用的函数剖析

STM32的GPIO使用的函数剖析

时间:11-10 来源:互联网 点击:
该文是自己学习了一段STM32后所写,是对STM32使用固件库编程最简单的一段程序,是对固件库函数的一部分进行解析。如有错误之处请指正,不胜感激。

一、GPIO_Init函数解析1

1、参数GPIO_TypeDef1

2、参数GPIO_InitStruct2

3、函数代码详解4

4、备注6

一、GPIO_Init函数解析

首先来看一下GPIO_Init函数的原型voidGPIO_Init(GPIO_TypeDef*GPIOx,GPIO_InitTypeDef*GPIO_InitStruct)。这个函数的实现是在Stm32f10x_gpio.c文件中,若要使用该函数在相应的应用程序的前面包含Stm32f10x_gpio.h头文件。

1、参数GPIO_TypeDef

该函数的第一个参数为GPIO_TypeDef,它是一个结构体类型,该类型在Stm32f10x.h中被定义。定义的原型为:

typedefstruct

{

__IOuint32_tCRL;

__IOuint32_tCRH;

__IOuint32_tIDR;

__IOuint32_tODR;

__IOuint32_tBSRR;

__IOuint32_tBRR;

__IOuint32_tLCKR;

}GPIO_TypeDef;

在这个结构体类型当中有7个32(8字节)位的变量,这些变量在存储空间的地址是相邻的。打开STM32数据手册不难看出,每个端口对应有16的引脚,由7个寄存器控制GPIO行为,并且这7个寄存器的顺序也是连续的。各个端口都有相同的结构。STM32的固件库就将这种结构抽象出一个类型GPIO_TypeDef。在操作寄存器之前你一定要有一个寄存器映射的操作,否则无法访问指定的寄存器,在这里我们只需要映射一次而不需要映射7此。这样做是不是很方便,也提高了代码的可读性,使代码规范化。

既然GPIO_Init的第一个参数GPIO_TypeDef的指针变量,这个指针变量存放的就是某一个端口的首地址。某一个程序的调用语句是这样的GPIO_Init(GPIOD,&GPIO_InitStructure);//初始化GPIOD

GPID是固件库中定义的一个宏,在编译的时候会宏展开,先列出与GPIOD端口地址映射有关的宏定义如下:

#defineGPIOD((GPIO_TypeDef*)GPIOD_BASE)

#defineGPIOD_BASE(APB2PERIPH_BASE+0x1400)

#defineAPB2PERIPH_BASE(PERIPH_BASE+0x10000)

#definePERIPH_BASE((uint32_t)0x40000000)

看到了0x40000000这个数字是不是非常熟悉,它是外设的首地址。在STM32芯片的内部STM32有两个,一个叫APB1,一个叫APB2。每一个APB桥都会管理很多外设。STM32F10x把这两个APB的外设寄存器访问地址放在了不同的存储空间。0x10000就是APB2外设的存储空间首地址相对于整个外设的偏移。而0x1400是GPIOD端口外设首地址相对于APB2外设的存储空间首地址的偏移。这样就找到了GPIOD外设的基地址了!而((GPIO_TypeDef*)GPIOD_BASE)可以同时实现所有控制GPIOD端口的7个寄存器的映射。若访问某一个寄存器只需要通过指向GPIO_TypeDef变量的指针。

2、参数GPIO_InitStruct

第二个参数的为GPIO_InitTypeDef*GPIO_InitStruct。就是一个指向GPIO_InitTypeDef的地址。第一个参数只找到配置的目标寄存器,第二个参数就是对相应端口如何配置的数据参数。这些参数存储在指向GPIO_InitTypeDef变量的首地址处。先列处该参数由来的一断代码

GPIO_InitTypeDefGPIO_InitStructure;

GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0;

GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;

GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;

GPIO_InitTypeDef是一个结构体的变量,该变量在Stm32f10x_gpio.h头文件中被定义,定义的原型如下:

typedefstruct

{

uint16_tGPIO_Pin;

GPIOSpeed_TypeDefGPIO_Speed;

GPIOMode_TypeDefGPIO_Mode;

}GPIO_InitTypeDef;

GPIO_InitTypeDef的第一个变量为GPIO_Pin是一个16为的无符号数,该数只有16位,每一位代表一个引脚,若要配置某一个端口的某一个引脚只需要把相应的位设置为1就可以了。在STM32的固件库中有如下引脚号定义:

#defineGPIO_Pin_0((uint16_t)0x0001)/*!

#defineGPIO_Pin_1((uint16_t)0x0002)/*!

#defineGPIO_Pin_2((uint16_t)0x0004)/*!

#defineGPIO_Pin_3((uint16_t)0x0008)/*!

#defineGPIO_Pin_4((uint16_t)0x0010)/*!

#defineGPIO_Pin_5((uint16_t)0x0020)/*!

#defineGPIO_Pin_6((uint16_t)0x0040)/*!

#defineGPIO_Pin_7((uint16_t)0x0080)/*!

#defineGPIO_Pin_8((uint16_t)0x0100)/*!

#defineGPIO_Pin_9((uint16_t)0x0200)/*!

#defineGPIO_Pin_10((uint16_t)0x0400)/*!

#defineGPIO_Pin_11((uint16_t)0x0800)/*!

#defineGPIO_Pin_12((uint16_t)0x1000)/*!

#defineGPIO_Pin_13((uint16_t)0x2000)/*!

#defineGPIO_Pin_14((uint16_t)0x4000)/*!

#defineGPIO_Pin_15((uint16_t)0x8000)/*!

#defineGPIO_Pin_All((uint16_t)0xFFFF)/*!

使用这些定义好的宏就方便多了,要配置某几个引脚只需要把相应的

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top