当前位置:网站首页>STM32外设GPIO的配置和应用
STM32外设GPIO的配置和应用
2022-04-21 22:07:00 【weiDev101】
以下内容主要以F407xx系列为例。
01 PIN脚类型和结构
在讲GPIO之前,我们先看下STM32中的PIN脚类型:
PIN脚类型
| PIN类型 | 描述 | 备注 |
|---|---|---|
| S | Supply pin | 电源引脚 |
| I | Input only pin | 只能作输入 |
| I/O | Input / output pin | 输入输出口 |
PIN类型 - S
| PIN名称 | 描述 | 备注 |
|---|---|---|
| VBAT | 为备份寄存器、RTC和LSE在VDD断开情况下供电 | |
| VDD | 为IO供电以及通过内部稳压器为内核、外设、存储器供电 | |
| VSS | VDD对应的公共接地端 | |
| VDDA | 为模拟部分供电,包括ADC、PLL、RC等 | |
| VSSA | VDDA的对应公共负端 | |
| VREF+ | ADC的外部参考电压 | |
| VREF- | VREF+的对应公共负端 | |
| VCAP_1/VCAP_2 | 内部调压器引脚 |
F407xx中线性调压器为备份域和待机电路以外的所有数字电路供电,调压器输出电压约为 1.2 V。
此调压器需要将两个外部电容连接到专用引脚 VCAP_1 和 VCAP_2。
在调压器使能情况下,这两个引脚输出1.2V电压。
PIN类型 - I
| PIN名称 | 描述 | 备注 |
|---|---|---|
| BOOT0 | BOOT模式配置引脚 | |
| PDR_ON | 内部电源监控器使能引脚 | 掉电复位 |
| BYPASS_REG | 内部调压器使能 |
BYPASS_REG接VSS使能内部调压器,BYPASS_REG接VDD停用内部调压器。
若停用调压器,则必须从VCAP1和VCAP2引脚提供1.2V外部电压。
PIN类型 - I/O
| I/O结构 | 描述 | 备注 |
|---|---|---|
| FT | 5V tolerant I/O | 可以容忍5V电压输入 |
| TTa | 3.3 V tolerant I/O directly connected to ADC | 只能容忍3.3V电压输入,且是直接连接到ADC外设 |
| B | Dedicated BOOT0 pin | BOOT0专用引脚(PB2为BOOT1,但可作I/O使用) |
| RST | Bidirectional 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结构包括:
- 输入钳位保护;
- 上拉/下拉电阻;
- 史密斯触发器;
- PMOS/NMOS结构;
- 输出选择结构;
- 输入/输出寄存器;
- GPIO置位/复位寄存器;
- 模拟外设/复用外设。

在工作模式章节中,会结合这张结构图讲解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寄存器进行配置。
- 完成复位后,所有 IO 都会连接到系统的复用功能 0 (AF0);
- 外设的复用功能映射到 AF1 至 AF13,AF14保留;
- AF15是Cortex-M4F EVENTOUT功能的映射。
使用ADC和DAC外设,只需把IO口配置为模拟通道。

锁定
该功能会冻结GPIOx的控制寄存器(包括GPIOx_MODER、GPIOx_OTYPER、GPIOx_OSPEEDR、GPIOx_PUPDR、GPIOx_AFRL 和 GPIOx_AFRH)。
锁定的是工作模式配置,并非输出值。
重映射(Remap)
重映射就是将引脚功能重新定义到其他引脚上去。在ST早期F1xx系列的芯片中还有“Remap”这一概念,后续的F4xx,L0xx等都是作为“Additional functions”,直接由外设寄存器进行配置来映射。
以下为F1xx系类TIM1的映射表。

GPIO的工作模式
根据IO口的特性,我们可以配置IO口为多种工作模式。
每个 IO 端口位均可自由编程,但 IO 端口寄存器必须按 32 位字、半字或字节进行访问。以确保在读取和修改访问之间发生中断请求也不会有问题。
浮空输入
如图中蓝色路线所示,该模式下IO端口的电平信号直接进入输入数据寄存器(GPIOx_IDR),MCU读取到的IO口电平不确定。
如果在引脚处于悬空的情况下,那么浮空输入端口的电平是不确定的,由外部环境决定。

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

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

模拟模式
当GPIO用于模拟功能时,引脚的上、下拉电阻是不起作用的,这个时候即使配置了上拉或下拉模式,也不会影响到模拟信号的输入输出。
- 输入
如图中蓝色路线所示,该模式用于GPIO作为ADC采集电压的输入通道时,此时信号不经过施密特触发器,直接直接进入ADC外设中,并且输入数据寄存器为空 ,MCU不能在GPIOx_IDR上读到引脚状态。

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

开漏输出
如图中蓝色路线所示,该模式下只有N-MOS管工作。如果控制输出为低电平,则P-MOS管关闭,N-MOS管导通,使IO输出低电平。
如果控制输出高电平,则P-MOS管和N-MOS管都关闭,输出指令就不会起到作用,此时IO端口的电平就不会由所控制输出的高电平决定,而是由IO端口外部的上拉或者下拉决定 如果外部没有上拉或者下拉,那么IO口就会处于悬空状态。
1.开漏输出模式下施密特触发器是开启的,即输入可用。可以通过输入数据寄存器GPIOx_IDR读取IO的实际状态。
2.IO口的电平不一定是输出的电平。

推挽输出
如图中蓝色路线所示,在该模式下,N-MOS管和P-MOS管都工作。如果控制输出为低电平,则N-MOS管关闭,P-MOS管导通,使IO输出低电平。
如果控制输出为高电平,则N-MOS管导通,P-MOS管关闭,使IO输出高电平,此时外部上拉和下拉的作用是控制在没有输出时IO口的电平状态。
1.该模式下施密特触发器是开启的,即输入可用。可以通过输入数据寄存器GPIOx_IDR读取IO的实际状态。
2.IO口的电平不一定是输出的电平。

复用开漏
如图中蓝色路线所示,在该模式下,GPIO复用为其他外设,输出数据寄存器GPIOx_ODR无效。 输出的高低电平来自其它内部外设,其他和开漏输出功能相同。
该模式下施密特触发器是开启的,即输入可用。可以通过输入数据寄存器GPIOx_IDR读取IO的实际状态。

复用推挽
如图中蓝色路线所示,在该模式下,GPIO复用为其他外设,输出数据寄存器GPIOx_ODR无效。 输出的高低电平来自其它内部外设,其他和推挽输出功能相同。
该模式下施密特触发器是开启的,即输入可用。可以通过输入数据寄存器GPIOx_IDR读取IO的实际状态。

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

03 GPIO的配置和应用
通用功能
浮空输入
该模式常应用于按键检测。
#define KEY1_PIN GPIO_Pin_8
#define KEY1_GPIO_PORT GPIOA
#define KEY1_GPIO_CLK RCC_AHB1Periph_GPIOA
void 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_IRQHandler
void 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);
}
模拟功能
- 输入
用于ADC外设输入配置。
#define ADC_GPIO_PORT GPIOB
#define ADC_GPIO_PIN GPIO_Pin_0
#define ADC_GPIO_CLK RCC_AHB1Periph_GPIOB
void 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);
}
- 输出
用于DAC外设输出配置。
#define DAC_CH1_GPIO_CLK RCC_AHB1Periph_GPIOA
#define DAC_CH1_GPIO_PORT GPIOA
#define DAC_CH1_GPIO_PIN GPIO_Pin_4
void 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_I2C1
void 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_GPIOA
void 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_5
void 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_GPIOB
void 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);
}
}
参考文献
-
[Cortex-M4权威指南]
-
[AN4488]
版权声明
本文为[weiDev101]所创,转载请带上原文链接,感谢
https://blog.csdn.net/weixin_40749320/article/details/124286698
边栏推荐
- [basic problems of function implementation C language]
- Smart Chemical Park solutions
- 国产API管理神器Eolink,我爱了
- Jupyter notebook has no run button
- Outil CSV - YAML en ligne
- Oracle merge data operation (merge)
- Online CSV to yaml tool
- Leetcode0785. Judgement bipartite graph (DFS)
- 什么?你们公司还没有将JVM初始和最大堆内存大小设置为相同值?
- Oracle cascade delete table (not subject to foreign key constraints)
猜你喜欢

Oracle合并数据操作(MERGE)

How does wechat applet realize the function of jumping from commodity list to commodity details page

面试必刷算法TOP101之背包九讲篇 TOP14

数据库设计与实现

Authing officially joined the W3C organization and will participate in the formulation of relevant international standards

解放双手,推荐一款阿里开源的低代码工具,YYDS~

kotlin爬虫app,Android开发面试准备

字节日常实习(已OC)

Detailed explanation of redis configuration file

Attack and defense world MFW
随机推荐
Huayun actively responded to the anti epidemic call of Hefei high tech Zone: practicing social responsibility and contributing to the strength of science and technology enterprises
【ES6】变量的解构赋值
Restcloud ETL out of the box - permanently free
WPF data-driven method for modifying binding
Lenovo announced the new progress of ESG: it promised that 100% of all computer products would contain recycled plastics by 2025
kotlin环境搭建,2021百度Android岗面试真题收录解析
[basic problems of function implementation C language]
[ES6] deconstruction and assignment of variables
[ES6] module import and export
攻防世界 mfw
How to connect ODBC database with PHP?
Leetcode0785. 判断二分图(medium,二分图,DFS)
How does PHP add an array element to an array
Analysts believe that Samsung Galaxy Z fold 4 and Z flip 4 may be cheaper than their previous products
ROS - use OpenCV to send and receive cameras
what? Your company has not set the JVM initial and maximum heap memory size to the same value?
一篇彻底搞懂-->shell脚本
GAMES101 Lec6 反走样与深度缓冲
Interview must brush algorithm top101 knapsack nine lectures top14
Hospital-Oriented RFID Service