目录
STM32GPIO端口位基本结构图:
结构图I/O引脚:
GPIO输入输出总结
1.GPIO引脚的四种输入方式及其特点:
1)上拉输入(GPIO_Mode_IPU)
2)下拉输入(GPIO_Mode_IPD)
3)模拟输入(GPIO_Mode_AIN)
4)浮空输入(GPIO_Mode_IN_FLOATING)
2.GPIO引脚的四种输出方式及其特点:
1)推挽输出:
2)开漏输出:
3)复用开漏输出、复用推挽输出:
STM32的GPIO设置举例
端口配置低寄存器(GPIOx_CRL) (x=A..E)
端口配置高寄存器(GPIOx_CRH) (x=A..E)
端口输入数据寄存器(GPIOx_IDR) (x=A..E)
端口输出数据寄存器(GPIOx_ODR)(x=A....E)
端口位设置/清除寄存器(GPIOx_BSRR)(x=A.....E)
端口位清除寄存器(GPIOx_BRR) (x=A..E)
配置GPIO令LED灯闪烁代码+注解
图片描绘了STM32GPIO口内部的基本结构:左边寄存器 中间驱动器 右边I/O口引脚
由于STM32芯片内部电路所能承受的电压有限,因此I/O引脚向里是两个保护二极管,他们的作用是:当有静电等瞬间电压波动进入I/O引脚时,若此波动电压大于3.3V(VDD),则上方的保护二极管导通,将电压引入电源,让电源网络吸收;若此波动电压小于0V(VSS),则下方的保护二极管导通。
STMO2的GPIO的输入输出方式有以下8种:
(1) GPIO_Mode_AIN 模拟输入:
(2) GPIO_Mode_IN_FLOATING浮空输入:
(3) GPIO_Mode_IPD 下拉输入:
(4) GPIO_Mode_IPU 上拉输入:
(5) GPIO_Mode_Out_OD开漏输出:
(6) GPIO_Mode_Out_PP推挽输出:
(7) GPIO_Mode_AF_OD复用开漏输出:
(8) GPIO_Mode_AF_PP复用推挽输出。
上拉输入,就是信号进入芯片后被内部的一个上拉电阻上拉,再经过施密特触发器转换成0、1信号,因此,复位后该引脚电平为高电平。
下拉输入,就是信号进入芯片后被内部的一个下拉电阻下拉,再经过施密特触发器转换成0、1信号,因此,复位后该引脚电平为低电平。
信号进入芯片后不经过上拉电阻或者下拉电阻,也不经过施密特触发器,经由另一线路把电压信号传送到片上相应的外设模块。 例如,通常是ADC模块,然后由ADC采集电压信号。因此,可以将这种方式理解为模拟输入的信号是未经处理的信号。
信号进入芯片内部后,既没有经过上拉电阻也没有经过下拉电阻,只经由施密特触发器输入。如果被配置成这个模式,用电压表测量其引脚电压为1伏左右,是个不确定值。
由于其输入阻抗比较大,所以一般把这种模式用于标准的通信协议,如IIC、USART等。
可以输出高、低电平,连接数字器件。推挽结构一般是指P-MOS和N-MOS两个三极管分别受两个互补信号的控制,总是在一个三极管导通的时候另一个截止,各负责正、负半周的波形放大任务。电路工作时,两个对称的功率开关管每次只有一个导通,所以导通损耗小、效率高。输出既可以向负载灌电流,也可以从负载抽取电流(拉电流)。推挽输出既提高了电路负载能力,又提高了开关速度。推挽输出有一定的电压与电流驱动能力,可以直接驱动一些合适的原件工作。
一般情况下:当我们控制I/O口输出高电平时,P-MOS激活,N-MOS关闭,VDD连接到I/O口引脚;当我们控制I/O口输出低电平时,N-MOS激活,P-MOS关闭,VSS连接到I/O口引脚
开漏模式下只有N-MOS工作 P-MOS一直处于断开状态
输出端相当于三极管的集电极,因此要得到高电平状态需要外接上拉电阻才行。该方式适合于做电流型的驱动,其吸收电流的能力相对较强(可达到20mA)。开漏输出没有电流电压驱动能力,必须依靠外部的电压源来驱动,而且选用开漏输出必须选择能够5V容忍的I/O口
例如,用该方式去驱动继电器。该方式的特点是:利用外部电路的驱动能力,减少IC内部的驱动,IC 内部仅需很小的栅极驱动电流:开漏可用来连接不同电平的器件,以实现电平匹配:提供灵活的输出方式,可以将多个开漏输出引脚并接到一条线上。通过一个上拉电阻,在不增加任何器件的情况下,形成“与逻辑”关系。这也IIC、SMBus 等总线判断总线占用状态的原理。
(如图所示:芯片定义图中有"FT"的都可以容忍5V电压)
可以理解为GPIO口被用作第二功能时的配置情况(即并非作为通用I/O口使用),STM32的很多引脚是多功能复用的,所以对此必须要重视:
(1)复用开漏输出:片内外设功能,如TX1、MOSI、MISO、SCK、SS等。
(2)复用推挽输出:片内外设功能,如IIC的SCL、SDA等。
在每个GPIO模块内,主要包含了寄存器和驱动器
寄存器:可以理解为特殊的存储器,内核可以通过APB2总线对寄存器进行读写,由此完成输出电平和读取电平的功能,and与此同时,寄存器的每一位对应一个引脚,由于STM32是32位单片机,因此STM32内部的寄存器都是32位的,但由于端口只有16位,所以这个寄存器只有低16位所对应的有端口,高16位没有用到
驱动器:增加驱动能力
库函数使用的是读写位设置和位清除寄存器的方法
GPIO配置寄存器,每个端口的模式由4位进行配置(16个端口就需要64位)
低16位对应16个引脚,高16位没有用
低16位对应16个引脚,高16位没有用
如果想要对多个端口同时进行位设置和位清除——使用端口位设置/清除寄存器,可保证位设置和位清除的同步性
#include "stm32f10x.h" // Device header
#include "Delay.h"
int main(void)
{
/*开启时钟*/
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //开启GPIOA的时钟
//使用各个外设前必须开启时钟,否则对外设的操作无效
/*GPIO初始化*/
GPIO_InitTypeDef GPIO_InitStructure; //定义结构体变量
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //GPIO模式,赋值为推挽输出模式
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; //GPIO引脚,赋值为第0号引脚
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //GPIO速度,赋值为50MHz
GPIO_Init(GPIOA, &GPIO_InitStructure); //将赋值后的构体变量传递给GPIO_Init函数
//函数内部会自动根据结构体的参数配置相应寄存器
//实现GPIOA的初始化
/*主循环,循环体内的代码会一直循环执行*/
while (1)
{
/*设置PA0引脚的高低电平,实现LED闪烁,下面展示3种方法*/
/*方法1:GPIO_ResetBits——设置低电平,GPIO_SetBits——设置高电平*/
GPIO_ResetBits(GPIOA, GPIO_Pin_0); //将PA0引脚设置为低电平
Delay_ms(500); //延时500ms
GPIO_SetBits(GPIOA, GPIO_Pin_0); //将PA0引脚设置为高电平
Delay_ms(500); //延时500ms
// /*方法2:GPIO_WriteBit设置低/高电平,由Bit_RESET/Bit_SET指定*/
// GPIO_WriteBit(GPIOA, GPIO_Pin_0, Bit_RESET); //将PA0引脚设置为低电平
// Delay_ms(500); //延时500ms
// GPIO_WriteBit(GPIOA, GPIO_Pin_0, Bit_SET); //将PA0引脚设置为高电平
// Delay_ms(500); //延时500ms
//
// /*方法3:GPIO_WriteBit设置低/高电平,由数据0/1指定,数据需要强转为BitAction类型*/
// GPIO_WriteBit(GPIOA, GPIO_Pin_0, (BitAction)0); //将PA0引脚设置为低电平
// Delay_ms(500); //延时500ms
// GPIO_WriteBit(GPIOA, GPIO_Pin_0, (BitAction)1); //将PA0引脚设置为高电平
// Delay_ms(500); //延时500ms
}
}
(代码来自江科大STM32教学视频)