本文基于STM32F407ZGT6,适用于绝大部分M3/M4内核的STM32芯片。
———————————————————————————————
通过STM32 库开发者可调用这些函数接口来配置STM32 的寄存器,使用库函数开发人员得以脱离最底层的寄存器操作(不用天天去查中文参考手册,只需要知道需要配置哪些寄存器,然后直接在库种调用即可),使用库函数开发有开发快速、可移植性高、代码易懂等优点。
使用库函数开发STM32是上上之选。
关于STM32的GPIO口的寄存器相关操作可看博文:STM32-GPIO_寄存器版(1)
通过库函数我们可以完全脱离STM32那些寄存器烦人的位操作,只需知道寄存器的功能然后配置那些寄存器即可完成GPIO口的初始化。
STM32每个通用 I/O 端口包括 10个32位寄存器,在STM32的库函数中已经把它封装成了一个结构体(在stm32f40xx.h大概987行可以查看):
typedef struct
{
__IO uint32_t MODER; /*!< GPIO port mode register, Address offset: 0x00 */
__IO uint32_t OTYPER; /*!< GPIO port output type register, Address offset: 0x04 */
__IO uint32_t OSPEEDR; /*!< GPIO port output speed register, Address offset: 0x08 */
__IO uint32_t PUPDR; /*!< GPIO port pull-up/pull-down register, Address offset: 0x0C */
__IO uint32_t IDR; /*!< GPIO port input data register, Address offset: 0x10 */
__IO uint32_t ODR; /*!< GPIO port output data register, Address offset: 0x14 */
__IO uint16_t BSRRL; /*!< GPIO port bit set/reset low register, Address offset: 0x18 */
__IO uint16_t BSRRH; /*!< GPIO port bit set/reset high register, Address offset: 0x1A */
__IO uint32_t LCKR; /*!< GPIO port configuration lock register, Address offset: 0x1C */
__IO uint32_t AFR[2]; /*!< GPIO alternate function registers, Address offset: 0x20-0x24 */
} GPIO_TypeDef;
关于GPIO口具体的配置和功能函数一共有14个(可以在stm32f4xx_gpio.h中查看)
/* Function used to set the GPIO configuration to the default reset state ****/
void GPIO_DeInit(GPIO_TypeDef* GPIOx);//GPIO口复位函数。
/* Initialization and Configuration functions *********************************/
void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct);//GPIO口初始化函数
void GPIO_StructInit(GPIO_InitTypeDef* GPIO_InitStruct); //GPIO口默认初始化函数,自动配置GPIO口为低速2m输入模式
void GPIO_PinLockConfig(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin); //GPIO口锁定函数
/* GPIO Read and Write functions **********************************************/
uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);//读取某一个GPIO口输入电平,返回值是0或1
uint16_t GPIO_ReadInputData(GPIO_TypeDef* GPIOx); //读取IDR寄存器,返回的是寄存器状态即某一组比如GPIOA的状态
uint8_t GPIO_ReadOutputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);//读取某一个GPIO口输出电平,返回值是0或1
uint16_t GPIO_ReadOutputData(GPIO_TypeDef* GPIOx); //读取IDR寄存器,返回的是寄存器状态即某一组比如GPIOA的状态
void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);//设置BSRRL,设置某一个GPIO口为高电平
void GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);//设置BSRRH,设置某一个GPIO口为低电平
void GPIO_WriteBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, BitAction BitVal); //用于配置BSRRH/BSRRL寄存器,设置某个个IO口电平为低或者高。相当于GPIO_ResetBits和GPIO_SetBits两个函数的总和
void GPIO_Write(GPIO_TypeDef* GPIOx, uint16_t PortVal);//用于配置ODR寄存器,输出IO口电平
void GPIO_ToggleBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);//用于实现GPIO口输出电平的反转
/* GPIO Alternate functions configuration function ****************************/
void GPIO_PinAFConfig(GPIO_TypeDef* GPIOx, uint16_t GPIO_PinSource, uint8_t GPIO_AF);//配置GPIO口为复用模式
下面就两个例子来具体来讲一下STM32的GPIO口配置:
GPIO口配置只需用到GPIO_Init函数即可:
1、配置为输入模式:
- 需要配置的寄存器有2个:GPIOx_MODER、GPIOx_PUPDR
GPIO_InitTypeDef GPIO_InitStructure;//定义一个GPIO初始化结构体GPIO_InitStructure
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA|RCC_AHB1Periph_GPIOE, ENABLE);//使能GPIOA,GPIOE时钟
//初始化GPIOE2、3、4为输入模式
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4; //对应引脚
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;//普通输入模式
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉
GPIO_Init(GPIOE, &GPIO_InitStructure);//初始化GPIOE2,3,4
2、配置为输出模式:
- 需要配置的寄存器有4个(复用功能时有五个,要调用GPIO_PinAFConfig函数)
GPIOx_MODER、GPIOx_OTYPER、GPIOx_OSPEEDR、GPIOx_PUPDR(GPIOx_AFRH/GPIOx_AFRL)
这里没有用到复用功能所以只是配置4个即可
GPIO_InitTypeDef GPIO_InitStructure;//定义一个GPIO初始化结构体GPIO_InitStructure
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF, ENABLE);//使能GPIOF时钟
//初始化GPIOF8为输出模式
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;//普通输出模式
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//输出速度100MHz
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;//下拉
GPIO_Init(GPIOF, &GPIO_InitStructure);//初始化GPIO
这样我们不需要知道寄存器的哪些位的配置即可实现GPIO口的初始化,十分的方便。
其他函数具体的用法,可以参考STM32固件库。