#什么是GPIO口#
GPIO就是IO口,管输入输出的,引脚电平一般是0~3.3V,即可以输出0~3.3V的电压。
然而有些引脚可以容忍5V的电压,这里再引脚的定义表当中有表示
**引脚定义表**
在上表IO电平当中写有FT的就是可以容忍5V的引脚,这个容忍是指可以输入5V的电压。
GPIO口的输出模式:可以模拟通信协议,驱动外设等
GPIO的输出模式:可以用来读取外设、ADC信号采集、,通信协议的接收等。
**GPIO的内部结构**
GPIO是接在了APB2外设总线上的,核心可以通过这个总线来控制GPIO口。在GPIO的外部有16个引脚,内部有一个寄存器和驱动器。寄存器是32位的,只有低16位于外部的16个引脚一一对应,驱动器是为了提高GPIO口的驱动能力的。
**GPIO内部电路图**
**输入部分**
**输入模式下不可以输出**。 在GPIO的引脚上接了两个保护二极管,这是用来保护内部电路的,防止输入电压过大或过小。上面的那一条路是输入路,输入路有上拉电阻和下拉电阻的开关,可以控制输入的模式。输入的模式总共有四种**上拉输入**、**下拉输入**、**浮空输入**、**模拟输入**。其中前三种模式只需要控制上拉下拉电阻的开关即可。上拉和下拉电阻的组织都很大,因此上拉和下拉都是弱的。后面的**模拟输入**控制的是触发器,**模拟输入**是专门位ADC准备的。
上图中的触发器是施密特触发器,可以用来输出稳定的数字信号,如果想要模拟信号就必须在施密特触发器之前来读取信号。
**输出部分**
**输出模式**下可以有多个输入。输入的来源有两个分别是**内核**和**片上外设**。在输出的电路当中有上下两个MOS管,可以控制输出的模式。输出的模式分别有**推挽输出**、**开漏输出**、**复用推挽**、**复用开漏**这四种模式。其中,**推挽输出**具有很强的上拉和下拉能力。**开漏输出**就是上面的MOS管关闭,下面的导通,0为0,1为高阻态,开漏输出可以外接上拉电阻。当内核控制输出的时候就是普通IO口,当外设控制的时候就是有其他的意义了。
位设置/清除寄存器可以单独的为某一位置0或1.
#代码控制GPIO#
**输入**
操作GPIO的三个步骤:
第一步:RCC开启GPIO时钟
第二步:使用GPIO初始化函数初始化GPIO
第三步:使用输出或输入的函数控制GPIO
**关于RCC的库函数**
//RCC库函数(常用)第一个参数可以使用或的方式来选中该总线上的多个外设
void RCC_AHBPeriphClockCmd(uint32_t RCC_AHBPeriph, FunctionalState NewState); //使能或者失能外设时钟,参数1选择外设,参数二使能或者失能时钟控制的第一个参数可以使用按位或来选中多个外设。
void RCC_APB2PeriphClockCmd(uint32_t RCC_APB2Periph, FunctionalState NewState); //以此类推
void RCC_APB1PeriphClockCmd(uint32_t RCC_APB1Periph, FunctionalState NewState); //以此类推
以上库函数我们都可以转到定义在参数中看到这几个总线控制的是那些外设。
**关于GPIO的库函数**
GPIO库函数
GPIO输入模式的选择:我们一般看接在这个GPIO口的外部引脚的外部模块输出的默认电平,如果外部模块默认输出高电平,那我们就选择上拉输入模式,如果外部模块默认输出低电平,那我们就选择下拉输入模式,和外部模块默认输入电平保持一致,防止默认电平打架,但一般外部模块默认高电平居多,所以上拉输入模式用的也比较多。如果不确定外部默认输出模式又或者外部信号输出功率非常小,这是就尽量选择浮空输入,这样就不会因为上拉或者下拉电阻对去影响外部的信号,缺点就是当引脚悬空的时候,默认就是没有点电平了,容易受到外部噪声的影响。
void GPIO_DeInit(GPIO_TypeDef* GPIOx); //调用此函数所指定的GPIO就会被复位(将IO口设置为默认模式)
void GPIO_AFIODeInit(void); //复位AFIO
void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct); //用结构体的参数来初始化GPIO,先定义结构体,然后给结构体进行赋值,最后传入结构体参数(几乎所有外设都有这个函数来进行初始化)
void GPIO_StructInit(GPIO_InitTypeDef* GPIO_InitStruct); //把结构体变量赋一个默认值
//GPIO读取函数
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); //读取整个输出寄存器
//GPIO写入函数
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); //可以同时对16个端口进行写入操作。
//GPIO8中工作模式
GPIO_Mode_AIN = 0x0, //模拟输入(GPIO Mode Analog Input)
GPIO_Mode_IN_FLOATING = 0x04, //浮空输入(当外部的输入功率很小的时候可以选择浮空输入,内部的上拉电阻可能会影响到这个输入信号的时候最好选用浮空输入)(GPIO Mode Input Floating)
GPIO_Mode_IPD = 0x28, //下拉输入(GPIO Mode Input Pull-Down)
GPIO_Mode_IPU = 0x48, //上拉输入(GPIO Mode Input Pull-Up)
GPIO_Mode_Out_OD = 0x14, //开漏输出(GPIO Mode Output Open-Drain)
GPIO_Mode_Out_PP = 0x10, //推挽输出(GPIO Mode Output Push-Pull)
GPIO_Mode_AF_OD = 0x1C, //复用开漏(GPIO Mode Alternate Function Open-Drain)
GPIO_Mode_AF_PP = 0x18 //复用推挽(GPIO Mode Alternate Function Push-Pull)
//GPIO_Pin_ 可以实现按位或的操作,实现控制多个IO口,因为每一个引脚对应了一个二进制,按位或可以得出一个所有这些IO口都选中的一个二进制的值
//PA15 PB8 PBC默认是JTAG的调试端口不是普通IO口,如果要配置为普通IO口我们还需要在进行一些其他的配置。
//GPIO配置好了之后默认就是低电平。
//stm32的引脚上电之后,如果不初始化,默认是浮空输入模式,该模式下引脚不会输出电平
//内核外设的手册要去 Cortex-M3编程手册去找,里面有内核和内核外设的详细介绍