关于STM32F4xx的GPIO

发布者:Dingsir1902最新更新时间:2020-12-21 来源: eefocus关键字:STM32F4xx  GPIO  端口 手机看文章 扫描二维码
随时随地手机看文章

STM32F4xx的GPIO可以分为GPIOA到GPIOK个端口,每个端口有16个IO口。


对每个GPIO端口,STM32F4xx安排了4个32位配置寄存器(GPIOx_MODER、GPIOx_OTYPER、GPIOx_OSPEEDR、GPIOx_PUPDR)用于对端口内的每个IO口进行配置,安排2个32位数据寄存器(GPIOx_IDR、GPIOx_ODR)用于每个端口的数据输入输出存储,此外,还安排了1个32位置位/复位寄存器(GPIOx_BSRR),1个32位锁定寄存器(GPIOx_LCKR)和2个32位复用功能选择寄存器(GPIOx_AFRH、GPIOx_AFRL)。


对每一个IO口而言,用户可以根据需要将其配置为通用输入模式,通用输出模式,内部外设复用模式,以及模拟模式,这些模式的设置通过对GPIOx_MODER设置完成。GPIOx_MODER的32位中每2位对应其组内的一个IO口(共16个),可以设置为上述的4个模式之一。


若某个IO口设置为输出模式则表明可以通过该IO口输出数字信号0或1(底或高电平)。可以通过设置GPIOx_OTYPER寄存器将该IO口设置为推挽输出或者开漏输出模式之一,32位的GPIOx_OTYPER的0~15位每位控制一个IO口。此外,通过寄存器GPIOx_OSPEEDR可以将口的输出速度设置为低速(2MHz)、中速(25MHz)、快速(50MHz)、高速(100MHz)四种模式之一。同样,32位的GPIOx_OSPEEDR每2位控制一个IO口。此时,数据输出寄存器GPIOx_ODR的0~15每一位对应于一个IO口的数据,可以对其进行读写。


若某个IO口设置位输入模式则表明可以通过该IO口输入数字信号0或1。通过设置GPIOx_PUPDR寄存器将该IO口设置为无上拉下拉、上拉、下拉3种模式之一。同样,32位GPIOx_PUPDR寄存器依然是每2位控制一个IO口。此时,数据输入寄存器GPIOx_IDR每隔1个AHB1时钟周期对输入IO口进行一次采样以获得IO口电平数据,它的0~15每一位对应一个IO口的数据,可以对该寄存器以字的方式读取。


STM32F4有很多内置外设,这些内置外设的外部引脚可以与GPIO复用,即对某个特定的IO口而言,我们可以设置其为通用的IO数字输入输出口或者模拟口,也可以将其设置为功能复用模式,此时该IO口就与被设置的内置外设的相关引脚关联,可以进行该外设相关引脚的输入或者输出操作。在硬件上,每个IO口都有一个复用器连接到内置外设。每个复用器有16个输入,即表明一个IO口可以和16个不同的外设相联。但同一时间复用器只允许一个外设的复用功能连接到IO引脚以保证共用一个IO引脚的外设之间不发生冲突。另外,不是每个IO口都可以复用为任意外设的复用功能,哪些IO口可以复用哪些外设的复用功能可以查找数据手册中的相关资料。当把某个IO口设置为内置外设的复用功能时,我们有以下工作需要明确:

将该IO口的GPIOx_MODER设置为功能复用模式(但要注意,若使用DAC或者ADC,要将相应IO口设置为模拟模式);

根据该复用IO口对应的内置外设的输入输出需求设置输入输出方式(GPIOx_PUPDR、GPIOx_OTYPER)和速度(GPIOx_OSPEEDR);

由于每个IO口的复用器有16个输入连接到不同的外设复用管脚,每次到底复用哪个外设是通过前述的两个32位复用功能选择寄存器GPIOx_AFRL和GPIOx_AFRH来控制的,其中GPIOx_AFRL控制IO口0~7,GPIOx_AFRH控制IO口8~15,每个IO口占4位,对这4位设置相应的值就可以选择IO口复用16个外设的哪个外设。


32位的复位/置位寄存器GPIOx_BSRR用于对每个端口的各IO口分别进行复位或者置位操作。其中0~15位用于对相应的IO口进行置位操作,将相应的位写1则会对对应的IO口置位,写0不产生任何操作;16~31位用于对相应的IO口进行复位,将相应的位写1则会对对应的IO口置位,写0不产生任何操作。当IO口为输出模式时,除了直接向该口写入相应的输出值,也可以采用复位/置为方式对该IO口输出1或0。


32位的锁定寄存器GPIOx_LCKR用于锁定特定IO口的配置,具体的操作可以参考相应手册内容。


GPIO的标准固件库操作

如果对STM32F4的GPIO相关寄存器操作非常熟悉的话,我们当然可以直接操作寄存器完成相关的GPIO端口操作。但为了简化这些操作,标准固件库提供了相应的定义、申明和函数给我们直接使用和调用。STM32F4的GPIO部件的相关申明与定义在头文件stm32f4xx.h中,另外的GPIO相关的定义、申明和函数及其实现都在stm32f4xx_gpio.h和stm32f4xx_gpio.c中。通过这些申明、定义和实现,我们能够较方便的进行GPIO的应用编程。


当我们要进行GPIO应用编程时,通常要进行以下几步操作:


使能要使用的IO口相应组的外设时钟;

对要使用的IO口进行初始化设置,通常包含如下信息:设置哪个IO口,IO口的使用模式(输入、输出、模拟、功能复用),输出类型和速度、输入类型、复用外设连接等;

使用该IO口进行相应的操作(读、写、复位、置位等)。


标准固件库对涉及上述操作的基本数据结构,用到的设备部件,以及相关的函数已经定义和实现完成,我们需要熟悉这些定义,或者在使用的时候能够知道如何找到这些定义。其中主要包括:


对GPIO相关的寄存器的定义GPIO_TypeDef(stm32f4xx.h中):


typedef struct


{

  __IO uint32_t MODER;    /*模式寄存器GPIOx_MODER*/


  __IO uint32_t OTYPER;   /*输出类型寄存器GPIOx_OTYPER*/


  __IO uint32_t OSPEEDR;  /*输出速度寄存器GPIOx_OSPEEDR*/


  __IO uint32_t PUPDR;    /*输入类型寄存器GPIOx_PUPDR*/


  __IO uint32_t IDR;      /*输入数据寄存器GPIOx_IDR*/


  __IO uint32_t ODR;      /*输出数据寄存器GPIOx_ODR*/


  __IO uint16_t BSRRL;    /*置位复位寄存器GPIOx_BSRR的0~15位,即置位寄存器*/


  __IO uint16_t BSRRH;    /*置位复位寄存器GPIOx_BSRR的16~31位,即复位寄存器*/


  __IO uint32_t LCKR;     /*锁存寄存器GPIOxd_LCKR*/


  __IO uint32_t AFR[2];   /*复用功能选择寄存器组GPIOx_AFRL和GPIOx_AFRH */


} GPIO_TypeDef;


同时,针对各GPIO组,stm32f4xx.h中定义了指向各寄存器组的上述类型的指针GPIO_TypeDef* GPIOA~GPIOK,我们在程序中可以直接引用。比如,直接在程序中写GPIOG->IDR即是在访问GPIOG的输入数据寄存器;写GPIOG->BSRRL=0x08即表明将GPIOG的第4个IO口置位。


为了方便对GPIO进行初始化,在stm32f4xx_gpio.h中定义了相应的初始化结构GPIO_InitTypeDef:


typedef struct


{

  uint32_t GPIO_Pin;              /*进行初始化的IO口*/


  GPIOMode_TypeDef GPIO_Mode;     /*GPIO模式,由GPIOMode_TypeDef定义*/


  GPIOSpeed_TypeDef GPIO_Speed;   /*输出速度,由GPIOSpeed_TypeDef定义*/


  GPIOOType_TypeDef GPIO_OType;   /*输出类型,由GPIOOType_TypeDef定义*/


  GPIOPuPd_TypeDef GPIO_PuPd;     /*输入类型,由GPIOIType_TypeDef定义*/


}GPIO_InitTypeDef;


上述结构的每个成员正好对应对IO口初始化时需要设置的相关寄存器的值,而能够取的值也由后面注释中对应的宏或者枚举在stm32f4xx_gpio.h中声明好了,如IO口GPIO_Pin的取值通过宏定义为GPIO_Pin_0到GPIO_Pin_15,如IO模式GPIO_Mode的值通过枚举定义为GPIO_Mode_IN(输入),GPIO_Mode_OUT(输出),GPIO_Mode_AF(功能复用),GPIO_Mode_AN(模拟),我们可以直接使用这些值。此外,stm32f4xx_gpio.h和stm32f4xx_gpio.c中还声明和实现了IO初始化函数void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct),我们可以直接使用已经为我们准备好的数据和函数即可方便地完成初始化,如下例:


GPIO_InitTypeDef  GPIO_InitStructure;                                              /*申明初始化结构*/


void main() {

RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOG, ENABLE);/*使能GPIOG的时钟*/


  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5| GPIO_Pin_6;       /*IO口5和6*/


  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_NOPULL;             /*无上拉下拉*/


  GPIO_Init(GPIOG, &GPIO_InitStructure);                                        /*调用函数初始化*/


  ……


}


当我们要使用的IO口的初始化完成后,即可根据需要对IO口进行访问和使用。为了方便我们的使用,stm32f4xx_gpio.h中也申明了相关函数供我们使用,主要包括:


/*  恢复GPIO为默认配置 ****/


void GPIO_DeInit(GPIO_TypeDef* GPIOx);


 


/* 配置相关函数 *********************************/


void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct);/*GPIO初始化*/


void GPIO_StructInit(GPIO_InitTypeDef* GPIO_InitStruct);/*初始化结构赋值*/


void GPIO_PinLockConfig(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);/*配置锁定*/


 


/* 读写函数 **********************************************/


uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);/*输入位读*/


uint16_t GPIO_ReadInputData(GPIO_TypeDef* GPIOx);/*输入读*/


uint8_t GPIO_ReadOutputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);/*输出位读*/


uint16_t GPIO_ReadOutputData(GPIO_TypeDef* GPIOx);/*输出读*/


void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);/*置位*/


void GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);/*复位*/


void GPIO_WriteBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, BitAction BitVal);/*输出位写*/


void GPIO_Write(GPIO_TypeDef* GPIOx, uint16_t PortVal);/*输出写*/


void GPIO_ToggleBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);/*输出位反转*/


 


/* 功能复用配置函数****************************/


void GPIO_PinAFConfig(GPIO_TypeDef* GPIOx, uint16_t GPIO_PinSource, uint8_t GPIO_AF);


我们利用这些函数,可以对GPIO进行更多的操作。如上例我们可以修改为:


GPIO_InitTypeDef  GPIO_InitStructure;                                              /*申明初始化结构*/


void main() {

RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOG, ENABLE);/*使能GPIOG的时钟*/


  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5| GPIO_Pin_6;       /*IO口5和6*/


  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_NOPULL;             /*无上拉下拉*/


  GPIO_Init(GPIOG, &GPIO_InitStructure);                                        /*调用函数初始化*/


 


  while(1) {

GPIO_SetBits(GPIOG,GPIO_Pin_5|GPIO_Pin_6);/*置位*/


GPIO_ResetBits(GPIOG,GPIO_Pin5|GPIO_Pin_6);/*复位*/


  }


}


则实现了对端口GPIOG的IO口5和IO口6的反复置位和复位。当然,我们也可以直接访问相应的寄存器实现这个功能:


  while(1) {

GPIOG->BSRRL=GPIO_Pin_5|GPIO_Pin_6;/*置位*/


GPIOG->BSRRH=GPIO_Pin5|GPIO_Pin_6;/*复位*/


  }


关键字:STM32F4xx  GPIO  端口 引用地址:关于STM32F4xx的GPIO

上一篇:stm32引脚速度GPIO_Speed的区别
下一篇:STM32学习笔记-GPIO使用超强总结

推荐阅读最新更新时间:2024-11-17 16:10

STM32F103 GPIO基本原理与寄存器
GPIO基本原理与寄存器配置 STM32F103ZET6 一共有7组IO口 每组IO口有16个IO 一共16X7=112个IO GPIOA,GPIOB—GPIOG 4种输入模式: 输入浮空 输入上拉 输入下拉 模拟输入 4种输出模式: 开漏输出 开漏复用功能 推挽式输出 推挽式复用功能 3种最大翻转速度: -2MHZ -10MHz -50MHz 上电复位后,GPIO默认为浮空状态,部分特殊功能引脚为特定状态。 推挽输出:可以输出强高低电平,连接数字器件 开漏输出:只可以输出强低电平,高电平得靠外部电阻拉高。输出端相当于三极管的集电极. 要得到高电平状态需要上拉电阻才行. 适合于做电流型的驱动,其吸收电流的能力相
[单片机]
基于stm32的GPIO寄存器学习解析
GPIO即通用输入/输出 (General Purpose Input Output) 包括: 两个32位的配置寄存器 GPIOx- CRL,GPIOx- CRH 两个32位的数据寄存器 GPIOx- IDR,GPIOx- ODR 一个32位的 set/reset 寄存器 GPIOx- BSRR 一位16位的 reset 寄存器 GPIOx- BRR 一位32位的锁定寄存器 GPIOx- LCKR 端口的模式包括: 浮空输入(Input floating)—— 即没有上拉电阻和下拉电阻,电压呈不确定性,一般用来做ADC输入用,这样可以减少上下拉电阻对结果的影响 上拉输入(Input pull-up) 下拉输入(Input-pu
[单片机]
基于stm32的<font color='red'>GPIO</font>寄存器学习解析
【ARM】s3c2440之gpio按键控制
功能 通过GPIO,实现按键1点亮LED1,按键2点亮LED2…… 说明 1)因为2440的按键只涉及行,所以在扫描按键时比2410简单了很多 2)在进行移位操作之前,必须进行数据寄存器的初始化,否则会出错(硬件特性) 源码 /***************************************************************************** *****函数名:main() *****功 能:通过GPIO,实现按键1点亮LED1,按键2点亮LED2 *****说 明: *********************************************************
[单片机]
用于8051兼容微控制器的高效位敲击SPI端口
快速 SPI 端口可通过 GPIO 引脚进行位冲击,并作为具有 SPI 端口的 8051 兼容微控制器的低成本替代方案。本应用笔记所示的代码利用8051特有的特性,使用最少的额外代码创建快速SPI端口。 虽然可以使用带有SPI端口的8051兼容微控制器,但具有SPI端口通过GPIO引脚位敲击的低成本器件通常足以满足许多应用的需求。此处显示的代码利用特定于 8051 内核的功能,以最小的工作量创建快速 SPI 端口。#define语句中的 CPHA、CPOL 和CS_TOGGLE_BETWEEN_BYTES常量初始化宏,这些宏根据正在实现的 SPI 端口类型定制代码。 预处理器在编译时而不是运行时执行此代码定制,从而节省了宝贵的
[单片机]
用于8051兼容微控制器的高效位敲击SPI<font color='red'>端口</font>
STM32学习记录之GPIO
本篇学习目的: 一、学会对STM32芯片GPIO的基本操作 二、对GPIO的相关函数进行二次封装,以便于后期开发 开发板GPIO原理图如下 由图可知LED接在GPIOC的PC0-PC7 STM的GPIO有如下8中模式 GPIO相关库函数 GPIO模式配置函数:GPIO_Init(GPIO_TypeDef *GPIOx,GPIO_InitTypeDef *GPIO_InitStruct); 第一个参数用来指定GPIO口,取值范围GPIOA—GPIOG 第二个参数用来初始化参数结构体指针,参数结构体定义如下: typedef struct{ uint16_t GPIO_Pin; //选择要设置的Pin口 G
[单片机]
STM32学习记录之<font color='red'>GPIO</font>篇
S3C2440 gpio + main
举例 start.S .globl _start _start: /* 关看门狗 */ /* 往WTCON(0x53000000)写0 */ ldr r0, =0x53000000 mov r1, #0 str r1, @ str, store, /* 设置栈大小,不能大于4k,因为片内SRAM只有4k */ ldr sp, =1024*4 bl main halt: b halt main.c #define GPFCON (*(volatile unsigned int*)0x56000050) #define GPFDAT (*(volatile unsigned
[单片机]
STM32F072RB 实作笔记(四)- GPIO的基础设定技法, 一个LED点亮程式
编写第一个程式 修改1:20210531 第一个步骤一定是写一个简单的程式 由 data BUS 输出 Hi/Low 控制 LED 亮灭,来確定这个开发板是可以用的,确认是可以被控制的。不过,ARM 的设定有一些复杂,需要一边看参考手册,一边做设定。下边列了STM32 的网站,除了下载参考手册以外,也建议注册一下,然后,在上面找找有没有其他好货可以下载的!! STM32F072RB 规格资料 Mainstream ARM Cortex-M0 USB line MCU with 128 Kbytes Flash, 48 MHz CPU, USB, CAN and CEC functions. STM32F072RB Re
[单片机]
STM32F072RB 实作笔记(四)- <font color='red'>GPIO</font>的基础设定技法, 一个LED点亮程式
AVR单片机入门----MEGA端口操作
AVR端口是真正的双向端口,不像51伪双向。这也是AVR的一项优势,只是操作时大家注意DDRn就可以了。真正双向端口在模拟时序方面不如伪双向的方便。 DDRn PORTn PINn 解释:n为端口号:ABCDE DDRn:控制端口是输入还是输出,0为输入,1为输出。个人记忆方法:一比零大所以往外挤,即1为输出,0为输入。 PORTn:从引脚输出信号,当DDRn为1时,可以通过PORTn=x等端口操作语句给引脚输出赋值。 PINn:从引脚读输入信号,无论DDRn为何值,都可以通过x=PINn获得端口n的外部电平。 当引脚配置为输入时,若PORTxn 为 1“,上拉电阻将使能。内部上拉电阻的使用在键盘扫描的时候
[单片机]
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved