GPIO的引脚与外部硬件设备连接,可实现与外部通讯、控制外部硬件或者采集外部硬件数据的功能。
**GPIO基本结构**
![在这里插入图片描述](https://img-blog.csdnimg.cn/68b9bfe9d5654f24bc3655b919f39bb2.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQ1ODQwNzg0,size_16,color_FFFFFF,t_70#pic_center)**保护二极管**:IO引脚上下两边两个二极管用于防止引脚外部输入过高或过低的电压。当输入电压高于ADD时,上方二极管导通,输入电压小于VSS时。下方二极管导通。输入的电压范围是VSS<VIN<VDD。
P-MOS和N-MOS管:由P-MOS和N-MOS管组成的半桥电路使得GPIO具有“推挽输出”和”开漏出书“的功能。
TTL肖特基触发器:IO引脚上的信号经过肖特基触发器后,模拟信号转化为0、1数字信号。当GPIO作为ADC采集电压的输入通道时,即用GPIO的”模拟输入“功能时,这是新号不经过肖特基二级管。
STM32的GPIO工作方式
支持4种输入模式:浮空输入、上拉输入、下拉输入、模拟输入
支持4种输出模式:开漏输出、开漏复用输出、推挽输出、推挽复用输出)(TIP:每个GPIO都可以自由编程,但IO口的寄存器必须按32位字被访问)
/*****************************
浮空输入:IO口的电平状态是不确定的,完全由外部输入确定,IO端的电平信号直接进入到数据寄存器。
上拉输入模式:IO口默认高电平,IO口电平可以被拉低,IO口信号直接进入数据寄存器。
下拉输入模式:IO口默认地电平,IO口电平可以被拉高,IO口信号直接进入数据寄存器。
模拟输入模式:IO端口的模拟信号直接模拟输入到片上外设模块。
******************************/
开漏输出模式:通过设置位设置/清除寄存器或者输出数据寄存器的值,途经N-MOS管,最终输出到I/O端口。设置输出的值为高电平的时候,N-MOS管处于关闭状态,但此时输出的高电平不由设置位设置/清除寄存器或者输出数据寄存器的值来决定,而由I/O端口外部的上拉或者下拉决定。当设置输出的值为低电平的时候,N-MOS管处于开启状态,此时I/O端口的电平就是低电平。类似于下图。
开漏复用输出模式:开漏输出模式很是类似,输出的高低电平来自片上外设的复用功能输出来决定。
开漏输出模式下,通过设置位设置/清除寄存器或者输出数据寄存器的值,途经N-MOS管,最终输出到I/O端口。当设置的输出信号是高电平时,此时N-MOS截止,P-MOS导通,VDD经P-MOS从IO口输出(推)。当设置的输出信号是低电平时,此时P-MOS截止,N-MOS导通,IO口电平经N-MOS管到低,故输出为低电平(挽)。
宏设置PA8PA11、PB6PB9管脚的输出状态****其他管脚的输出状态设定方法与此雷同
// PA8模式配置
//----------------------------------------------------------------------------
// PA8:通用推挽输出
#define PA8_Out_PP { GPIOA->CRH&=0XFFFFFFF0; GPIOA->CRH|=(u32)0x01<<(0*4); }
// PA8:复用推挽输出
#define PA8_AF_PP { GPIOA->CRH&=0X0FFFFFF0; GPIOA->CRH|=(u32)0x09<<(0*4); }
//----------------------------------------------------------------------------
// PA9模式配置
//----------------------------------------------------------------------------
// PA9:通用推挽输出
#define PA9_Out_PP { GPIOA->CRH&=0XFFFFFF0F; GPIOA->CRH|=(u32)0x03<<(1*4); }
// PA9:复用推挽输出
#define PA9_AF_PP { GPIOA->CRH&=0XFFFFFF0F; GPIOA->CRH|=(u32)0x09<<(1*4); }
//----------------------------------------------------------------------------
// PA10模式配置
//----------------------------------------------------------------------------
// PA10:通用推挽输出
#define PA10_Out_PP { GPIOA->CRH&=0XFFFFF0FF; GPIOA->CRH|=(u32)0x01<<(2*4); }
// PA10:复用推挽输出
#define PA10_AF_PP { GPIOA->CRH&=0XFFFFF0FF; GPIOA->CRH|=(u32)0x09<<(2*4); }
//----------------------------------------------------------------------------
// PA11模式配置
//----------------------------------------------------------------------------
// PA11:通用推挽输出
#define PA11_Out_PP { GPIOA->CRH&=0XFFFF0FFF; GPIOA->CRH|=(u32)0x01<<(3*4); }
// PA11:复用推挽输出
#define PA11_AF_PP { GPIOA->CRH&=0XFFFF0FFF; GPIOA->CRH|=(u32)0x09<<(3*4); }
//----------------------------------------------------------------------------
// PB6模式配置
//----------------------------------------------------------------------------
// PB6:通用推挽输出
#define PB6_Out_PP { GPIOB->CRL&=0XF0FFFFFF; GPIOB->CRL|=(u32)0x01<<(6*4); }
// PB6:复用推挽输出
#define PB6_AF_PP { GPIOB->CRL&=0XF0FFFFFF; GPIOB->CRL|=(u32)0x09<<(6*4); }
//----------------------------------------------------------------------------
// PB7模式配置
//----------------------------------------------------------------------------
// PB7:通用推挽输出
#define PB7_Out_PP { GPIOB->CRL&=0X0FFFFFFF; GPIOB->CRL|=(u32)0x01<<(7*4); }
// PB7:复用推挽输出
#define PB7_AF_PP { GPIOB->CRL&=0X0FFFFFFF; GPIOB->CRL|=(u32)0x09<<(7*4); }
//----------------------------------------------------------------------------
// PB8模式配置
//----------------------------------------------------------------------------
// PB8:通用推挽输出
#define PB8_Out_PP { GPIOB->CRH&=0XFFFFFFF0; GPIOB->CRH|=(u32)0x01<<(0*4); }
// PB8:复用推挽输出
#define PB8_AF_PP { GPIOB->CRH&=0XFFFFFFF0; GPIOB->CRH|=(u32)0x09<<(0*4); }
//----------------------------------------------------------------------------
// PB9模式配置
//----------------------------------------------------------------------------
// PB9:通用推挽输出
#define PB9_Out_PP { GPIOB->CRH&=0XFFFFFF0F; GPIOB->CRH|=(u32)0x01<<(1*4); }
// PB9:复用推挽输出
#define PB9_AF_PP { GPIOB->CRH&=0XFFFFFF0F; GPIOB->CRH|=(u32)0x09<<(1*4); }