STM32外设GPIO的配置和应用

news/2024/11/29 5:38:04/

以下内容主要以F407xx系列为例。

01 PIN脚类型和结构

在讲GPIO之前,我们先看下STM32中的PIN脚类型:

PIN脚类型

PIN类型描述备注
SSupply pin电源引脚
IInput only pin只能作输入
I/OInput / output pin输入输出口

PIN类型 - S

PIN名称描述备注
VBAT为备份寄存器、RTC和LSE在VDD断开情况下供电
VDD为IO供电以及通过内部稳压器为内核、外设、存储器供电
VSSVDD对应的公共接地端
VDDA为模拟部分供电,包括ADC、PLL、RC等
VSSAVDDA的对应公共负端
VREF+ADC的外部参考电压
VREF-VREF+的对应公共负端
VCAP_1/VCAP_2内部调压器引脚

F407xx中线性调压器为备份域和待机电路以外的所有数字电路供电,调压器输出电压约为 1.2 V。
此调压器需要将两个外部电容连接到专用引脚 VCAP_1 和 VCAP_2。
在调压器使能情况下,这两个引脚输出1.2V电压。

PIN类型 - I

PIN名称描述备注
BOOT0BOOT模式配置引脚
PDR_ON内部电源监控器使能引脚掉电复位
BYPASS_REG内部调压器使能

BYPASS_REG接VSS使能内部调压器,BYPASS_REG接VDD停用内部调压器。
若停用调压器,则必须从VCAP1和VCAP2引脚提供1.2V外部电压。

PIN类型 - I/O

I/O结构描述备注
FT5V tolerant I/O可以容忍5V电压输入
TTa3.3 V tolerant I/O directly connected to ADC只能容忍3.3V电压输入,且是直接连接到ADC外设
BDedicated BOOT0 pinBOOT0专用引脚(PB2为BOOT1,但可作I/O使用)
RSTBidirectional reset pin with embedded weak pull-up resistor复位

注意如果使用了TTa类型的IO口,需要留意3.3V的电压容忍值。

02 STM32的GPIO

General-Purpose Input Output,通用型输入输出的,也简称I/O口,有时也简写为IO口。用于电信号的传递,以实现与外部器件的通信、控制外部器件或者采集外部器件数据的功能。

GPIO的结构

F407xx的GPIO结构包括:

  1. 输入钳位保护;
  2. 上拉/下拉电阻;
  3. 史密斯触发器;
  4. PMOS/NMOS结构;
  5. 输出选择结构;
  6. 输入/输出寄存器;
  7. GPIO置位/复位寄存器;
  8. 模拟外设/复用外设。

img

在工作模式章节中,会结合这张结构图讲解GPIO的各种工作模式,这里只需了解基本结构。

GPIO的功能

通用

复位后,调试引脚处于复用功能上拉/下拉状态:

  • PA15:JTDI 处于上拉状态
  • PA14:JTCK/SWCLK 处于下拉状态
  • PA13:JTMS/SWDAT 处于下拉状态
  • PB4:NJTRST 处于上拉状态
  • PB3:JTDO 处于浮空状态

1.在复位期间及复位刚刚完成后,复用功能尚未激活时,IO 端口会被配置为输入浮空模式。
2.输入数据寄存器 (GPIOx_IDR) 每隔 1 个 AHB1 时钟周期捕获一次 IO 引脚的数据。

复用(Alternate functions)

MCU的外设引脚与GPIO口共用,默认作为IO口,但可配置作为多种外设用途。这种配置GPIO口为特定外设功能引脚的操作就叫做复用。
F407xx每个 IO 引脚都有一个复用器,且采用 16 路复用功能输入,可通过相应AF寄存器进行配置。

  1. 完成复位后,所有 IO 都会连接到系统的复用功能 0 (AF0);
  2. 外设的复用功能映射到 AF1 至 AF13,AF14保留;
  3. AF15是Cortex™-M4F EVENTOUT功能的映射。

使用ADC和DAC外设,只需把IO口配置为模拟通道。

img

锁定

该功能会冻结GPIOx的控制寄存器(包括GPIOx_MODER、GPIOx_OTYPER、GPIOx_OSPEEDR、GPIOx_PUPDR、GPIOx_AFRL 和 GPIOx_AFRH)。

锁定的是工作模式配置,并非输出值。

重映射(Remap)

重映射就是将引脚功能重新定义到其他引脚上去。在ST早期F1xx系列的芯片中还有“Remap”这一概念,后续的F4xx,L0xx等都是作为“Additional functions”,直接由外设寄存器进行配置来映射。

以下为F1xx系类TIM1的映射表。
img

GPIO的工作模式

根据IO口的特性,我们可以配置IO口为多种工作模式。

每个 IO 端口位均可自由编程,但 IO 端口寄存器必须按 32 位字、半字或字节进行访问。以确保在读取和修改访问之间发生中断请求也不会有问题。

浮空输入

如图中蓝色路线所示,该模式下IO端口的电平信号直接进入输入数据寄存器(GPIOx_IDR),MCU读取到的IO口电平不确定。

如果在引脚处于悬空的情况下,那么浮空输入端口的电平是不确定的,由外部环境决定。

img

上拉输入

如图中蓝色路线所示,该模式下IO内部接入上拉电阻,如果IO口外部没有信号输入或者悬空,则IO口默认为高电平。如果此时IO口有输入低电平,那么引脚就为低电平,MCU读取到的就是低电平。

STM32的内部上拉是"弱上拉",即通过此上拉输出的电流很弱,如需求大电流还是需要接外部上拉。

img

下拉输入

如图中蓝色路线所示,该模式下IO内部接入下拉电阻,如果IO口外部没有信号输入或者悬空,则IO口默认为低电平。如果此时IO口有输入高电平,那么引脚就为高电平,MCU读取到的就是高电平。

img

模拟模式

当GPIO用于模拟功能时,引脚的上、下拉电阻是不起作用的,这个时候即使配置了上拉或下拉模式,也不会影响到模拟信号的输入输出。

  1. 输入
    如图中蓝色路线所示,该模式用于GPIO作为ADC采集电压的输入通道时,此时信号不经过施密特触发器,直接直接进入ADC外设中,并且输入数据寄存器为空 ,MCU不能在GPIOx_IDR上读到引脚状态。

img

  1. 输出
    如图中蓝色路线所示,该模式用于GPIO作为DAC输出电压的输出通道时,信号直接从外设输出到IO口。

img

开漏输出

如图中蓝色路线所示,该模式下只有N-MOS管工作。如果控制输出为低电平,则P-MOS管关闭,N-MOS管导通,使IO输出低电平。

如果控制输出高电平,则P-MOS管和N-MOS管都关闭,输出指令就不会起到作用,此时IO端口的电平就不会由所控制输出的高电平决定,而是由IO端口外部的上拉或者下拉决定 如果外部没有上拉或者下拉,那么IO口就会处于悬空状态。

1.开漏输出模式下施密特触发器是开启的,即输入可用。可以通过输入数据寄存器GPIOx_IDR读取IO的实际状态。
2.IO口的电平不一定是输出的电平。

img

推挽输出

如图中蓝色路线所示,在该模式下,N-MOS管和P-MOS管都工作。如果控制输出为低电平,则N-MOS管关闭,P-MOS管导通,使IO输出低电平。

如果控制输出为高电平,则N-MOS管导通,P-MOS管关闭,使IO输出高电平,此时外部上拉和下拉的作用是控制在没有输出时IO口的电平状态。

1.该模式下施密特触发器是开启的,即输入可用。可以通过输入数据寄存器GPIOx_IDR读取IO的实际状态。
2.IO口的电平不一定是输出的电平。

img

复用开漏

如图中蓝色路线所示,在该模式下,GPIO复用为其他外设,输出数据寄存器GPIOx_ODR无效。 输出的高低电平来自其它内部外设,其他和开漏输出功能相同。

该模式下施密特触发器是开启的,即输入可用。可以通过输入数据寄存器GPIOx_IDR读取IO的实际状态。

img

复用推挽

如图中蓝色路线所示,在该模式下,GPIO复用为其他外设,输出数据寄存器GPIOx_ODR无效。 输出的高低电平来自其它内部外设,其他和推挽输出功能相同。

该模式下施密特触发器是开启的,即输入可用。可以通过输入数据寄存器GPIOx_IDR读取IO的实际状态。

img

复用输入

该模式不能由GPIO外设配置,由其他外设复用功能决定。如图中蓝色路线所示,在该模式下,IO信号经史密斯触发器通过复用通道输入各外设中。

img

03 GPIO的配置和应用

通用功能

浮空输入

该模式常应用于按键检测。

#define KEY1_PIN                  GPIO_Pin_8                 
#define KEY1_GPIO_PORT            GPIOA                      
#define KEY1_GPIO_CLK             RCC_AHB1Periph_GPIOAvoid GPIO_Init(void)
{/*定义一个GPIO_InitTypeDef类型的结构体*/GPIO_InitTypeDef GPIO_InitStructure;/*开启相关的GPIO外设时钟*/RCC_AHB1PeriphClockCmd (KEY1_GPIO_CLK, ENABLE);/*选择要控制的GPIO引脚*/GPIO_InitStructure.GPIO_Pin = KEY1_PIN;/*设置引脚模式为输出模式*/GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;/*设置引脚为不上拉也不下拉模式*/GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;/*初始化GPIO*/GPIO_Init(KEY1_GPIO_PORT, &GPIO_InitStructure);
}

上拉/下拉输入

用于给定外部输入一个初始电平状态。

#define KEY1_INT_GPIO_PORT                GPIOA
#define KEY1_INT_GPIO_CLK                 RCC_AHB1Periph_GPIOA
#define KEY1_INT_GPIO_PIN                 GPIO_Pin_0
#define KEY1_INT_EXTI_PORTSOURCE          EXTI_PortSourceGPIOA
#define KEY1_INT_EXTI_PINSOURCE           EXTI_PinSource0
#define KEY1_INT_EXTI_LINE                EXTI_Line0
#define KEY1_INT_EXTI_IRQ                 EXTI0_IRQn#define KEY1_IRQHandler                   EXTI0_IRQHandlervoid GPIO_Init(void)
{GPIO_InitTypeDef GPIO_InitStructure;EXTI_InitTypeDef EXTI_InitStructure;/*开启按键GPIO口的时钟*/RCC_AHB1PeriphClockCmd(KEY1_INT_GPIO_CLK ,ENABLE);/*使能 SYSCFG 时钟 ,使用GPIO外部中断时必须使能SYSCFG时钟*/RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);/*配置 NVIC */NVIC_Configuration();/*选择按键1的引脚 */GPIO_InitStructure.GPIO_Pin = KEY1_INT_GPIO_PIN;/*设置引脚为输入模式 */GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;/*设置引脚下拉,用于给引脚一个默认电平状态 */GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;/*使用上面的结构体初始化按键 */GPIO_Init(KEY1_INT_GPIO_PORT, &GPIO_InitStructure);/*连接 EXTI 中断源 到key1引脚 */SYSCFG_EXTILineConfig(KEY1_INT_EXTI_PORTSOURCE,KEY1_INT_EXTI_PINSOURCE);/*选择 EXTI 中断源 */EXTI_InitStructure.EXTI_Line = KEY1_INT_EXTI_LINE;/*中断模式 */EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;/*下降沿触发 */EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;/*使能中断/事件线 */EXTI_InitStructure.EXTI_LineCmd = ENABLE;EXTI_Init(&EXTI_InitStructure);
}

模拟功能

  1. 输入

用于ADC外设输入配置。

#define ADC_GPIO_PORT    GPIOB
#define ADC_GPIO_PIN     GPIO_Pin_0
#define ADC_GPIO_CLK     RCC_AHB1Periph_GPIOBvoid GPIO_Init(void)
{GPIO_InitTypeDef GPIO_InitStructure;/*使能 GPIO 时钟*/RCC_AHB1PeriphClockCmd(ADC_GPIO_CLK, ENABLE);/*配置ADC IO*/GPIO_InitStructure.GPIO_Pin = ADC_GPIO_PIN;/*配置为模拟模式*/GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;GPIO_Init(ADC_GPIO_PORT, &GPIO_InitStructure);
}
  1. 输出

用于DAC外设输出配置。

#define DAC_CH1_GPIO_CLK            RCC_AHB1Periph_GPIOA
#define DAC_CH1_GPIO_PORT           GPIOA
#define DAC_CH1_GPIO_PIN            GPIO_Pin_4void GPIO_Init(void)
{GPIO_InitTypeDef GPIO_InitStructure;DAC_InitTypeDef  DAC_InitStructure;/*使能GPIOA时钟 */RCC_AHB1PeriphClockCmd(DAC_CH1_GPIO_CLK, ENABLE);/*使能DAC时钟 */RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC, ENABLE);/*DAC的GPIO配置,模拟输入 */GPIO_InitStructure.GPIO_Pin =  DAC_CH1_GPIO_PIN;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;GPIO_Init(DAC_CH1_GPIO_PORT, &GPIO_InitStructure);
}

(复用)开漏输出

常用于驱动外部数字芯片,如I2C接口的芯片。

#define I2C_SCL_PIN                  GPIO_Pin_8
#define I2C_SCL_GPIO_PORT            GPIOB
#define I2C_SCL_GPIO_CLK             RCC_AHB1Periph_GPIOB
#define I2C_SCL_SOURCE               GPIO_PinSource8
#define I2C_SCL_AF                   GPIO_AF_I2C1#define I2C_SDA_PIN                  GPIO_Pin_9
#define I2C_SDA_GPIO_PORT            GPIOB
#define I2C_SDA_GPIO_CLK             RCC_AHB1Periph_GPIOB
#define I2C_SDA_SOURCE               GPIO_PinSource9
#define I2C_SDA_AF                   GPIO_AF_I2C1void GPIO_Init(void)
{GPIO_InitTypeDef  GPIO_InitStructure;/*I2C Periph clock enable */RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);/*I2C_SCL_GPIO_CLK and I2C_SDA_GPIO_CLK Periph clock enable */RCC_AHB1PeriphClockCmd(I2C_SCL_GPIO_CLK | I2C_SDA_GPIO_CLK, ENABLE);/*GPIO configuration *//*Connect PXx to I2C_SCL*/GPIO_PinAFConfig(I2C_SCL_GPIO_PORT, I2C_SCL_SOURCE, I2C_SCL_AF);/*Connect PXx to I2C_SDA*/GPIO_PinAFConfig(I2C_SDA_GPIO_PORT, I2C_SDA_SOURCE, I2C_SDA_AF);/*Configure I2C pins: SCL */GPIO_InitStructure.GPIO_Pin = I2C_SCL_PIN;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_NOPULL;GPIO_Init(I2C_SCL_GPIO_PORT, &GPIO_InitStructure);/*I2C pins: SDA */GPIO_InitStructure.GPIO_Pin = I2C_SDA_PIN;GPIO_Init(I2C_SDA_GPIO_PORT, &GPIO_InitStructure);
}

(复用)推挽输出

MCU输出电流有限,该模式常用于驱动小功率负载,如LED。

#define LED1_PIN                  GPIO_Pin_6                 
#define LED1_GPIO_PORT            GPIOA                      
#define LED1_GPIO_CLK             RCC_AHB1Periph_GPIOAvoid GPIO_Init(void)
{/*定义一个GPIO_InitTypeDef类型的结构体*/GPIO_InitTypeDef GPIO_InitStructure;/*开启相关的GPIO外设时钟*/RCC_AHB1PeriphClockCmd (LED1_GPIO_CLK, ENABLE);/*选择要控制的GPIO引脚*/GPIO_InitStructure.GPIO_Pin = LED1_PIN;/*设置引脚模式为输出模式*/GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;/*设置引脚的输出类型为推挽输出*/GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;/*设置引脚为上拉模式*/GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;/*设置引脚速率为100MHz */GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;/*初始化GPIO*/GPIO_Init(LED1_GPIO_PORT, &GPIO_InitStructure);
}

重映射功能

该功能多见于早期F1xx系列中,用于映射外设功能到不同IO。

#define TIM3_CH2_GPIO_CLK           RCC_APB2Periph_GPIOB
#define TIM3_CH2_GPIO_PORT          GPIOB
#define TIM3_CH2_GPIO_PIN           GPIO_Pin_5void GPIO_Init(void)
{GPIO_InitTypeDef GPIO_InitStructure;/*使能定时器3时钟*/RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);/*使能GPIO外设和AFIO复用功能模块时钟*/RCC_APB2PeriphClockCmd(TIM3_CH2_GPIO_CLK | RCC_APB2Periph_AFIO, ENABLE); /*Timer3部分重映射  TIM3_CH2->PB5*/GPIO_PinRemapConfig(GPIO_PartialRemap_TIM3, ENABLE); /*设置该引脚为复用输出功能,输出TIM3 CH2的PWM脉冲波形*/GPIO_InitStructure.GPIO_Pin = TIM3_CH2_GPIO_PIN;/*复用推挽输出*/GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(TIM3_CH2_GPIO_PORT, &GPIO_InitStructure);
}

锁定功能

常用于锁定不能被轻易更改工作模式的IO控制,如电机控制IO。

#define MOTOR_A_PIN                  GPIO_Pin_10                 
#define MOTOR_A_GPIO_PORT            GPIOB                      
#define MOTOR_A_GPIO_CLK             RCC_AHB1Periph_GPIOBvoid GPIO_Init(void)
{/*定义一个GPIO_InitTypeDef类型的结构体*/GPIO_InitTypeDef GPIO_InitStructure;/*开启相关的GPIO外设时钟*/RCC_AHB1PeriphClockCmd (MOTOR_A_GPIO_CLK, ENABLE);/*选择要控制的GPIO引脚*/GPIO_InitStructure.GPIO_Pin = MOTOR_A_PIN;/*设置引脚模式为输出模式*/GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;/*设置引脚的输出类型为推挽输出*/GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;/*设置引脚为上拉模式*/GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;/*设置引脚速率为100MHz */GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;/*初始化GPIO*/GPIO_Init(MOTOR_A_GPIO_PORT, &GPIO_InitStructure);/*锁定IO工作模式*/GPIO_PinLockConfig(MOTOR_A_GPIO_PORT,MOTOR_A_PIN)
}

位带操作

位带操作就是可以单独的对一个比特位读和写。在F407 中,有两个地方实现了位带,一个是SRAM 区的最低1MB 空间,另一个是外设区最低1MB 空间。

这两个1MB 的空间除了可以像正常的RAM 一样操作外,他们还有自己的位带别名区,位带别名区把这1MB 的空间的每一个位扩展成一个32 位的字,当访问位带别名区的这些字时,就可以达到访问位带区某个比特位的目的。

1.这部分位带区大家可以看之前的《STM32存储器和寄存器》中讲到的Cortex-M4存储器映射。
2.位带区的一个比特位经过扩展之后,虽然变大到4 个字节,但是还是LSB才有效。
3.Cortex-M4系统总线是32bit的,所以这里把别名区扩展成32bit,使访问更高效。

/*** @ brief  这里只定义了 GPIO ODR和IDR这两个寄存器的位带别名区地址,其他寄存器的没有定义*          SRAM 位带区:    0X2000 0000~0X200F 0000*          SRAM 位带别名区:0X2200 0000~0X23FF FFFF*          外设 位带区:    0X4000 0000~0X400F FFFF*          外设 位带别名区:0X4200 0000~0X43FF FFFF*/
/*把“位带地址+位序号”转换成别名地址的宏*/
#define BITBAND(addr, bitnum) ((addr & 0xF0000000)+0x02000000+((addr & 0x000FFFFF)<<5)+(bitnum<<2))/*把一个地址转换成一个指针*/
#define MEM_ADDR(addr)  *((volatile unsigned long  *)(addr))/*把位带别名区地址转换成指针*/
#define BIT_ADDR(addr, bitnum)   MEM_ADDR(BITBAND(addr, bitnum))/*GPIO ODR 和 IDR 寄存器地址映射*/
#define GPIOA_ODR_Addr    (GPIOA_BASE+20)
#define GPIOB_ODR_Addr    (GPIOB_BASE+20)
#define GPIOC_ODR_Addr    (GPIOC_BASE+20)
#define GPIOD_ODR_Addr    (GPIOD_BASE+20)
#define GPIOE_ODR_Addr    (GPIOE_BASE+20)
#define GPIOF_ODR_Addr    (GPIOF_BASE+20)
#define GPIOG_ODR_Addr    (GPIOG_BASE+20)
#define GPIOH_ODR_Addr    (GPIOH_BASE+20)
#define GPIOI_ODR_Addr    (GPIOI_BASE+20)
#define GPIOJ_ODR_Addr    (GPIOJ_BASE+20)
#define GPIOK_ODR_Addr    (GPIOK_BASE+20)#define GPIOA_IDR_Addr    (GPIOA_BASE+16)
#define GPIOB_IDR_Addr    (GPIOB_BASE+16)
#define GPIOC_IDR_Addr    (GPIOC_BASE+16)
#define GPIOD_IDR_Addr    (GPIOD_BASE+16)
#define GPIOE_IDR_Addr    (GPIOE_BASE+16)
#define GPIOF_IDR_Addr    (GPIOF_BASE+16)
#define GPIOG_IDR_Addr    (GPIOG_BASE+16)
#define GPIOH_IDR_Addr    (GPIOH_BASE+16)
#define GPIOI_IDR_Addr    (GPIOI_BASE+16)
#define GPIOJ_IDR_Addr    (GPIOJ_BASE+16)
#define GPIOK_IDR_Addr    (GPIOK_BASE+16)/*单独操作 GPIO的某一个IO口,n(0,1,2...16),n表示具体是哪一个IO口*/
#define PAout(n)   BIT_ADDR(GPIOA_ODR_Addr,n)
#define PAin(n)    BIT_ADDR(GPIOA_IDR_Addr,n)#define PBout(n)   BIT_ADDR(GPIOB_ODR_Addr,n)
#define PBin(n)    BIT_ADDR(GPIOB_IDR_Addr,n)#define PCout(n)   BIT_ADDR(GPIOC_ODR_Addr,n)
#define PCin(n)    BIT_ADDR(GPIOC_IDR_Addr,n)#define PDout(n)   BIT_ADDR(GPIOD_ODR_Addr,n)
#define PDin(n)    BIT_ADDR(GPIOD_IDR_Addr,n)#define PEout(n)   BIT_ADDR(GPIOE_ODR_Addr,n)
#define PEin(n)    BIT_ADDR(GPIOE_IDR_Addr,n)#define PFout(n)   BIT_ADDR(GPIOF_ODR_Addr,n)
#define PFin(n)    BIT_ADDR(GPIOF_IDR_Addr,n)#define PGout(n)   BIT_ADDR(GPIOG_ODR_Addr,n)
#define PGin(n)    BIT_ADDR(GPIOG_IDR_Addr,n)#define PHout(n)   BIT_ADDR(GPIOH_ODR_Addr,n)
#define PHin(n)    BIT_ADDR(GPIOH_IDR_Addr,n)#define PIout(n)   BIT_ADDR(GPIOI_ODR_Addr,n)
#define PIin(n)    BIT_ADDR(GPIOI_IDR_Addr,n)#define PJout(n)   BIT_ADDR(GPIOJ_ODR_Addr,n)
#define PJin(n)    BIT_ADDR(GPIOJ_IDR_Addr,n)#define PKout(n)   BIT_ADDR(GPIOK_ODR_Addr,n)
#define PKin(n)    BIT_ADDR(GPIOK_IDR_Addr,n)void Application(void)
{/*LED 端口初始化 */LED_GPIO_Config();while (1){/*PA6 = 0,点亮LED*/PAout(6)= 0;Delay_ms(100);/*PA6 = 1,熄灭LED*/PAout(6)= 1;Delay_ms(100);}
}

参考文献

  1. STM32F407参考手册

  2. STM32F407产品规格书

  3. 百度百科

  4. [Cortex-M4权威指南]

  5. [AN4488]

  6. STM32的VCAP

  7. STM32F4 GPIO八种模式及工作原理详解


http://www.ppmy.cn/news/615723.html

相关文章

中断-NVIC与EXTI外设详解(超全面)

✅作者简介&#xff1a;嵌入式入坑者&#xff0c;与大家一起加油&#xff0c;希望文章能够帮助各位&#xff01;&#xff01;&#xff01;&#xff01; &#x1f4c3;个人主页&#xff1a;rivencode的个人主页 &#x1f525;系列专栏&#xff1a;玩转STM32 &#x1f4ac;推荐一…

外设、总线、接口概念辨析

命名&#xff1a; 外设&#xff0c;peripheral。 总线&#xff0c;bus。 接口&#xff0c;interface。 本文对这几个容易混淆的概念进行辨析&#xff0c;以便于更好地理解嵌入式系统。 外设在个人电脑等领域是指主机以外的一些设备&#xff0c;如显示器、键盘、鼠标、打印机…

MCU 如何控制外设

单片机如何控制外设 单片机不是直接控制外设的&#xff0c;而是通过配置片上外设寄存器来控制其输出和检测高低电平&#xff0c;进而控制外围器件。 单片机如何配置寄存器的&#xff1f; 下图是单片机驱动 点亮发光二极管 内核从flash里面加载读取指令。内核根据指令到SRAM里面…

常用芯片外设扫盲

AI算法半路出家的过程其实是有点痛苦的&#xff0c;告别了曾经熟悉的领域&#xff0c;在陌生又熟悉的道路上摸索着前进&#xff0c;其中的焦虑、彷徨以及面对信息过载的不知所措&#xff0c;常常让人怀疑当初的选择。好在&#xff0c;硬核人生不会被小小的困难劝退&#xff0c;…

CPU与外设间数据传输方式

主要有程序传送方式、中断传送方式和直接存储器存取(DMA)传送方式&#xff0c;分别介绍如下。 1. 程序传送方式 程序传送方式是指直接在程序控制下进行数据的输入/输出操作。程序查询方式分为无条件传送方式和查询方式&#xff08;条件传送方式&#xff09;两种。 …

STM32外设

外设 1.认识2.外设------------1.内部外设; 2.外设。3.如何选择外设IO口 1.认识 STM32管脚40个&#xff0c;常见是整个最小系统板&#xff0c;具体介绍认识可自行百度 2.外设------------1.内部外设; 2.外设。 内部是单片机里集成的功能&#xff0c;外设是指单片机扩展的功能 …

单片机外设基本概念_单片机外设有哪些,外设功能是什么?

单片机外设有哪些? 单片机内部的外设一般包括:串口控制模块,SPI模块,I2C模块,A/D模块,PWM模块,CAN模块,EEPROM,比较器模块,等等,它们都集成在单片机内部,有相对应的内部控制寄存器,可通过单片机指令直接控制。 外设指的是单片机外部的外围功能模块,比如键盘控制芯…

计算机外设分为三类,电脑外设有哪些

电脑外设有哪些 导语&#xff1a;电脑外设就是除主机外的大部分硬件设备都可称作外部设备&#xff0c;或叫外围设备&#xff0c;简称外设。下面就来看看小编为大家整理的电脑入门知识&#xff0c;希望对您有所帮助! 外部设备大致可分为三类&#xff1a; 1.人机交互设备&#xf…