【STM32】GPIO


一、GPIO是什么?

GPIO全称general-purpose input/output ,即通用输入输出端口。

二、外设框图

在这里插入图片描述

输入通道整体输入逻辑: 外界信号通过IO口进入单片机后,首先由保护二极管检查是否具有破坏性,检查通过后经过上下拉电路,该电路是设置默认电平的,从这里开始,信号要么直接输入,即模拟输入,要么经过触发器转化为数字信号,然后再分叉,要么保存在输入数据寄存器由用户读取,要么复用,被片上外设读取。

1、保护二极管

利用二极管达到阈值电压单向导通的特性,防止从引脚输入过大或过小电压。

当输入电压超过VDD+0.7V(假使是硅管),则上面的二极管导通。
当输入电压小于Vss-0.7V,则下面的二极管导通。

由此将真正输入芯片的电压钳位在Vss-0.7V至VDD+0.7V之间。

2、上下拉电阻

通过软件可以控制内部是否接入上下拉电阻,一共有三种情况:
①仅开启上拉电阻,引脚默认输出高电平
②仅开启下拉电阻,引脚默认输出低电平
③上拉下拉电阻都不开启,此时引脚处于浮空状态

浮空模式下,引脚的电压是不确定的,可能为1,也可能为0,来回摇摆。

根据拉电阻的阻值大小,可以分为强拉弱拉

拉电阻较小时为强拉,可以抵抗外部噪声的能力较强,代价是相应的功耗也较大。

STM32内部的拉电阻属于弱拉,通过查阅数据手册可知拉电阻阻值在40K左右,通过此拉电阻输出的电流很小,如果想要输出一个大电流。那么就需要外接阻值较小的拉电阻了,其实就是增加导线的输出电流。
在这里插入图片描述

3、输入数据寄存器

经过上下拉电阻的信号有三个去向,首先就是经过触发器转化为0/1进入输入数据寄存器。
在这里插入图片描述

4、模拟输入

其次信号如果不经过触发器,则可以将外部模拟信号直接输入内部,如ADC。

5、复用功能输入

第三个去向就是将信号转化为0/1后交由外设处理。


输出通道的整体逻辑: 输出的数据来源有3个,首先我可以控制位设置/清除寄存器,将IO口写1/0,我也可以将多个二进制数据写入数据输出寄存器让IO口依次输出,我还可以将控制权交给片内外设,让它控制IO输出它想要输出的信号。是用户控制还是外设控制由输出控制左边的梯形结构进行切换,输出信号经过双MOS 结构可以调整为推挽模式还是开漏模式,最后经过IO口输出。

6、输出数据寄存器

将想要输出的数据放入该寄存器内
在这里插入图片描述

7、位设置/清除寄存器

将IO口置0或置1。

其中高16位负责reset,低16位负责set。

在这里插入图片描述
除了GPIOx_BSRR,还有一个类似的寄存器叫GPIOx_BRR,它相当于GPIOx_BSRR的高16位
在这里插入图片描述
这个“多余“的寄存器只是为了方便IO口清0,不像BSRR要清零还得先将数据左移16位再写入。

8、复用功能输出

将GPIO输出控制权交给内部外设,输出外设想要输出的信号。

9、双MOS管结构

该结构可以实现推挽输出开漏输出

(1)推挽输出

推挽输出两个MOS管都工作。

当输入为1时,经过反相器得到0,此时PMOS导通,NMOS截止,电流从VDD“推向”输出端,最后输出1;

当输入为0时,经过反相器得到1,此时PMOS截止,NMOS导通,电流从输出端被“拉回”地,拉回也就是挽的意思,最后输出0;
在这里插入图片描述

(2)开漏输出

开漏输出只用到了NMOS。

当输入为1时,经过反相器得到0,此时NMOS截止,引脚相当于在内部被断开,既不输出1也不输出0,对输出高阻态;

当输入为0时,经过反相器得到1,此时NMOS导通,对外输出0;

在这里插入图片描述
想要输出高电平则需要外加上拉电阻:
在这里插入图片描述
这种结构有一个重要的特性就是线与特性,即当有多个设置为开漏输出模式的引脚连在一起时,只要有一个引脚输出0,则整个线路为0,只有所有引脚输出为高阻态,线路上电平才为1。
在这里插入图片描述

开漏输出的应用:
①I2C通讯,该通讯协议通过线与解决多主机同时发送数据时的优先级判断,详见【STM32】I2C
②电平转换,如果要用3.3V单片机控制5V外设,则可以用开漏输出模式,外加一个连接5V的上拉电阻

10、端口配置寄存器(不在框图中)

端口配置寄存器有两个,其中GPIOx_CRL控制低8位,GPIOx_CRH控制高8位。
在这里插入图片描述
在这里插入图片描述
这两个32位寄存器分别控制16个IO口,每个IO口都有一个专属的MODE[1:0]和CNF[0:1]控制。

其中,MODE控制是输入还是输出,输出又有详细的速度配置,支持速率越高,功耗越大。

CNF控制在输入和输出模式下具体的工作模式配置。

GPIO共有8种工作模式:
①模拟输入,如ADC采集
②上拉输入
③下拉输入
④浮空输入,如按键检测

⑤推挽输出,如点亮LED
⑥开漏输出,如I2C,电平转换
⑦复用推挽输出,即由外设控制输出
⑧复用开漏输出,即由外设控制输出

三、编程

首先初始化GPIO

void LED_GPIO_Config(void)
{		
		/*定义一个GPIO_InitTypeDef类型的结构体*/
		GPIO_InitTypeDef GPIO_InitStructure;

		/*开启LED相关的GPIO外设时钟*/
		RCC_APB2PeriphClockCmd( LED1_GPIO_CLK, ENABLE);
		/*选择要控制的GPIO引脚*/
		GPIO_InitStructure.GPIO_Pin = LED1_GPIO_PIN;	

		/*设置引脚模式为通用推挽输出*/
		GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;   

		/*设置引脚速率为50MHz */   
		GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; 

		/*调用库函数,初始化GPIO*/
		GPIO_Init(LED1_GPIO_PORT, &GPIO_InitStructure);	
		/* 关闭所有led灯	*/
		GPIO_SetBits(LED1_GPIO_PORT, LED1_GPIO_PIN);
}

然后就可以库函数了

void GPIO_DeInit(GPIO_TypeDef* GPIOx);//恢复默认设置
void GPIO_AFIODeInit(void);
void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct);//将配置参数写入寄存器
void GPIO_StructInit(GPIO_InitTypeDef* GPIO_InitStruct);//填充GPIO_InitStruct内的元素为复位值
uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);//读指定IO引脚输入数据
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);//读指定端口输出数据
void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);//置1指定的端口引脚
void GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);//清0指定的端口引脚
void GPIO_WriteBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, BitAction BitVal);//设置或清除选择的数据端口引脚
void GPIO_Write(GPIO_TypeDef* GPIOx, uint16_t PortVal);//写指定数据到GPIOx端口寄存器
void GPIO_PinLockConfig(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
void GPIO_EventOutputConfig(uint8_t GPIO_PortSource, uint8_t GPIO_PinSource);//选择GPIO引脚作为事件输出
void GPIO_EventOutputCmd(FunctionalState NewState);//允许或禁止事件输出
void GPIO_PinRemapConfig(uint32_t GPIO_Remap, FunctionalState NewState);
void GPIO_EXTILineConfig(uint8_t GPIO_PortSource, uint8_t GPIO_PinSource);//选择IO口作为事件线
void GPIO_ETH_MediaInterfaceConfig(uint32_t GPIO_ETH_MediaInterface);

四、答疑

1、GPIO引脚驱动能力?

在这里插入图片描述
25mA,可以驱动一般的发光二极管。

2、我怎么知道每个外设相应的引脚应该配置为什么模式?

参考手册中有明确规定
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

参考资料

1、《STM32库开发实战指南》
2、https://zhuanlan.zhihu.com/p/362467204

待补充内容:GPIO中断

  • 4
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值