目录
一、GPIO简介
二、GPIO的基本结构
16个引脚(分AB)PA0-PA15 PB0-PB15
每一位的结构图
三、GPIO的八种工作模式
不同输入输出对于的寄存器状态
·GPIO_Mode_AIN = 0x0——模拟输入
·GPIO_Mode_IN_FLOATING = 0x04——输入浮空
·GPIO_Mode_IPD = 0x28——输入上拉//上拉输入的情况下,悬空的引脚为高电平。
·GPIO_Mode_IPU = 0x48——输入下拉//下拉输入的情况下,悬空的引脚为低电平。
·GPIO_Mode_Out_OD = 0x14——开漏输出//开漏输出下,高电平没有驱动能力,低电平驱动。因为在高电平时相当于高阻态
·GPIO_Mode_Out_PP = 0x10——推挽式输出//推挽模式下,高低电平都有驱动能力
·GPIO_Mode_AF_OD = 0x1C——开漏复用功能
·GPIO_Mode_AF_PP = 0x18——推挽式复用功能
硬件电路图:
一般采用上面两个,可以接上拉输入(上左)和浮空输入(上右)
下面两个接下拉输入(下左)和浮空输入(下右)
右边的为传感器的一般接法。
四、操作GPIO的函数
·常用的RCC三个函数
·RCC AHB外设时钟控制:
void RCC_AHBPeriphClockCmd(uint32_t RCC_AHBPeriph, FunctionalStateNewState);
·RCC APB2外设时钟控制:
void RCC_APB2PeriphClockCmd(uint32_t RCC_APB2Periph, FunctionalState NewState);
·RCC APB1外设时钟控制:
void RCC_APB1PeriphClockCmd(uint32_t RCC_APB1Periph, FunctionalState NewState);
·GPIO常用函数:
·所指用的GPIO外设被复位:
void GPIO_DeInit(GPIO_TypeDef* GPIOx);
·复位AFIO外设
void GPIO_AFIODeInit(void);
·用结构体参数来初始化GPIO外设参数
void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct);
·可以班结构体变量赋值
void GPIO_StructInit(GPIO_InitTypeDef* GPIO_InitStruct);
以下的函数主要用于读写GPIO的值。
·ReadInputDataBit(单个端口)主要用于读取输入数据寄存器某一个端口上的值
uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
·ReadInputData(整个寄存器)主要用于读取输入数据寄存器上以有的值
uint16_t GPIO_ReadInputData(GPIO_TypeDef* GPIOx);
·ReadOutputDataBit主要用于读取输出数据寄存器某一个端口上以为的值
uint8_t GPIO_ReadOutputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
·ReadOutputData主要用于读取整个输出数据寄存器以为的值
uint16_t GPIO_ReadOutputData(GPIO_TypeDef* GPIOx);
·GPIO_SetBits
·第一个参数是GPIOx 第二个是GPIO_Pin,可以把指定端口设置为高电平
void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
·GPIO_ResetBits
·第一个参数是GPIOx 第二个是GPIO_Pin,可以把指定端口设置为低电平
void GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
·GPIO_WriteBit
·第一个参数是GPIOx 第二个是GPIO_Pin,第三个是BitVal,
根据第三个参数的值设置GPIO
void GPIO_WriteBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, BitAction BitVal);
·GPIO_Write
·第一个参数是GPIOx 第二个是PortVal,同时对16个端口进行写入操作(0x0000-0xffff)
void GPIO_Write(GPIO_TypeDef* GPIOx, uint16_t PortVal);
·复位AFIO外设
void GPIO_AFIODeInit(void);
·用于锁定GPIO配置,防止意外更改
void GPIO_PinLockConfig(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
·配置AFIO的事件输出功能
void GPIO_EventOutputConfig(uint8_t GPIO_PortSource, uint8_t GPIO_PinSource);
void GPIO_EventOutputCmd(FunctionalState NewState);
·用来进行引脚重映射(重映射的方式,新的状态)
void GPIO_PinRemapConfig(uint32_t GPIO_Remap, FunctionalState NewState);
·配置APIO的数据选择器,选择我们需要的中断引脚
void GPIO_EXTILineConfig(uint8_t GPIO_PortSource, uint8_t GPIO_PinSource);
·和以太网有关(不需要掌握,了解就行)
void GPIO_ETH_MediaInterfaceConfig(uint32_t GPIO_ETH_MediaInterface);
五、操作STM32的GPIO的三个步骤:
1、使用RCC开启GPIO的时钟
2、使用GPIO_Init函数初始化GPIO
3、使用输出会在输入函数控制GPIO口
1、使用RCC开启GPIO的时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
上述代码我们开启了GPIOA的时钟,因为它在APB2总线上,所以用RCC_APB2PeriphClockCmd.
2、使用GPIO_Init函数初始化GPIO
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//通用推挽输出
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;//端口0
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//速度50Mhz
GPIO_Init(GPIOA, &GPIO_InitStructure);//开启GPIOA
也就是说在上述代码中我们开启了GPIOA的0号端口
3、使用输出会在输入函数控制GPIO口
for(unsigned int i=0;i < 10;i++)
{
GPIO_ResetBits(GPIOA, GPIO_Pin_0);//0
Delay_ms(50);
GPIO_SetBits(GPIOA, GPIO_Pin_0);//1
Delay_ms(50);
}
Delay_ms(2000);
for(unsigned int i=0;i < 10;i++)
{
GPIO_WriteBit(GPIOA, GPIO_Pin_0, Bit_RESET);//0
Delay_ms(50);
GPIO_WriteBit(GPIOA, GPIO_Pin_0, Bit_SET);//1
Delay_ms(50);
}
Delay_ms(2000);
for(unsigned int i=0;i < 10;i++)
{
GPIO_WriteBit(GPIOA, GPIO_Pin_0, (BitAction)0);
Delay_ms(50);
GPIO_WriteBit(GPIOA, GPIO_Pin_0, (BitAction)1);
Delay_ms(50);
}
上述使用了不同的方法实现电平翻转(也就是LED闪烁)。它会在迅速闪烁10次后,停顿两秒,再闪烁。也就是说我们用了三种方法来控制GPIOA上0端口的电平。
六、完整代码以及两个其他GPIO输出应用
1、LED闪烁(也就是上述操作GPIO的例子)
#include "stm32f10x.h" // Device header
#include "Delay.h"
int main(void)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);///¿ªÆôAPB2ʵʱÖÓ
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);//³õʼ»¯GPIOA¿Ú
for(unsigned int i=0;i < 10;i++)
{
GPIO_ResetBits(GPIOA, GPIO_Pin_0);//0
Delay_ms(50);
GPIO_SetBits(GPIOA, GPIO_Pin_0);//1
Delay_ms(50);
}
Delay_ms(2000);
for(unsigned int i=0;i < 10;i++)
{
GPIO_WriteBit(GPIOA, GPIO_Pin_0, Bit_RESET);//0
Delay_ms(50);
GPIO_WriteBit(GPIOA, GPIO_Pin_0, Bit_SET);//1
Delay_ms(50);
}
Delay_ms(2000);
for(unsigned int i=0;i < 10;i++)
{
GPIO_WriteBit(GPIOA, GPIO_Pin_0, (BitAction)0);
Delay_ms(50);
GPIO_WriteBit(GPIOA, GPIO_Pin_0, (BitAction)1);
Delay_ms(50);
}
}
2、流水灯(其中有变化的在设置结构体时开启了所有的端口)
#include "stm32f10x.h" // Device header
#include "Delay.h"
int main(void)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);///¿ªÆôAPB2ʵʱÖÓ
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_All;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);//³õʼ»¯GPIOA¿Ú
GPIO_WriteBit(GPIOA, GPIO_Pin_0, Bit_RESET);//0
Delay_ms(50);
GPIO_WriteBit(GPIOA, GPIO_Pin_0, Bit_SET);//1
Delay_ms(50);
GPIO_WriteBit(GPIOA, GPIO_Pin_1, Bit_RESET);//0
Delay_ms(50);
GPIO_WriteBit(GPIOA, GPIO_Pin_1, Bit_SET);//1
Delay_ms(50);
GPIO_WriteBit(GPIOA, GPIO_Pin_2, Bit_RESET);//0
Delay_ms(50);
GPIO_WriteBit(GPIOA, GPIO_Pin_2, Bit_SET);//1
Delay_ms(50);
GPIO_WriteBit(GPIOA, GPIO_Pin_3, Bit_RESET);//0
Delay_ms(50);
GPIO_WriteBit(GPIOA, GPIO_Pin_3, Bit_SET);//1
Delay_ms(50);
GPIO_WriteBit(GPIOA, GPIO_Pin_4, Bit_RESET);//0
Delay_ms(50);
GPIO_WriteBit(GPIOA, GPIO_Pin_4, Bit_SET);//1
Delay_ms(50);
}
3、使用蜂鸣器
需要在对应的GPIOA的0端口接上一个无源蜂鸣器
#include "stm32f10x.h" // Device header
#include "Delay.h"
int main(void)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);///¿ªÆôAPB2ʵʱÖÓ
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_All;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);//³õʼ»¯GPIOA¿Ú
GPIO_WriteBit(GPIOA, GPIO_Pin_0, Bit_RESET);//0
Delay_ms(50);
GPIO_WriteBit(GPIOA, GPIO_Pin_0, Bit_SET);//1
Delay_ms(50);
}