”GPIO“—STM32最基本的外设

GPIO简介

通用输入输出端口,STM32 芯片的 GPIO 引脚与外部设备连接起来,从而实现与外部通讯、控制以及数据采集的功能。GPIO被分成很多组,每组有 16 个引脚(也有可能少于 16 个),基本的输出功能是输出高低电平,基本的输入功能是检测外部输入电平。

框图解析

image-20221223131933774

保护二极管

我们先看到最右边的芯片引脚连接的两个二极管,这两个二极管主要是保护芯片,防止外部过高或过低的电压输入,当引脚电压高于Vdd时,上方二极管导通,输入芯片的电压就被钳制在Vdd电压,下面的也是同样的道理。

输出模式

输出电路要看到下面的电路,线路经过一个由 P-MOS 和 N-MOS 管组成的单元电路。这个结构使 GPIO 具有了“推挽输出”和“开漏输出”两种模式。

推挽输出

该结构中输入高电平时,经过反相器反向后,上方的 P-MOS 导通,下方的 N-MOS 关闭,对外输出高电平,也即Out直接接到了Vdd,P 管负责灌电流,N 管负责拉电流,推挽输出的低电平为 0 伏,高电平为 3.3 伏,值得注意的是这个输出电压是很低的,不足以驱动电机等外设,所以要驱动电机还必须接上一个驱动电路。

image-20221223133957378

开漏输出

在开漏输出模式时,上方的 P-MOS 管完全不工作。若控制输出为 1 (它无法直接输出高电平) 时,则 P-MOS管和 N-MOS 管都关闭,所以引脚既不输出高电平,也不输出低电平,为高阻态。值得一提的是:**它具有“线与”特性,也就是说,若有很多个开漏模式引脚连接到一起时,只有当所有引脚都输出高阻态,才由上拉电阻提供高电平,此高电平的
电压为外部上拉电阻所接的电源的电压。若其中一个引脚为低电平,那线路就相当于短路接地,使得整条线路都为低电平,0 伏。**我们平常很少需要用到开漏输出模式,除了向I2C这些需要线与的总线电路,以及必须输出5v高电平的场合,可以外接一个上拉电阻和5v电源,并配置成开漏模式

image-20221223135750646

那么问题来了:什么是上拉电阻?

上拉电阻主要接在电源和引脚之间,用于拉高某个节点的电压,从而提高电路驱动能力以及将不确定信号钳制在高电平。

具体讲解看这里:

<上拉电阻的通俗解释,你真正知道吗?_哔哩哔哩_bilibili>

image-20221223135206530

复用功能输出

这里指的是其他片上外设对GPIO引脚进行控制,从其它外设引出来的“复用功能输出信号”与 GPIO本身的数据据寄存器都连接到双 MOS 管结构的输入中,例如我们用串口通讯时需要把某个GPIO引脚复用为发送引脚或接收引脚

模拟输出

DAC模拟信号不经过双MOS结构直接输出到引脚

输入模式

在输入模式时,施密特触发器打开,输出被禁止,可通过输入数据寄存器 GPIOx_IDR 读取 I/O 状态

上拉输入

上拉输入模式下上拉电阻支路导通,当无外部信号时,读到的是Vdd电压,也即高电平,当输入高电平时,读到的是高电平,输入低电平读到低电平,上拉输入的好处是信号较为稳定,无信号输入时稳定在高电平,下拉输入则相反

image-20221223150823765

浮空输入

image-20221223152853798

浮空输入模式下上下拉电阻皆断开,读到的电平完全取决于外部,但是外部无输入时,电平会不确定

模拟输入

不经过触发器,读到的即是模拟信号

image-20221223153102904

寄存器操作GPIO

这里先讲解一下如何寄存器操作GPIO,以便大家可以更好的了解寄存器,我们需要用到参考手册以及原理图,我用的是正点原子精英版。

首先看到参考手册里的GPIO寄存器描述这一节,我们可以清楚的看到手册为我们把GPIO这个外设的寄存器都描述详尽,跟着大家解读一下:

我们首先看到这两个端口配置寄存器,一个是负责低八位,也即是负责PIn0-7,另一个高八位,也即是pin8-15,这样就刚好对应每个GPIO的16个IO(一些GPIO没有16个引脚的除外),这里的每一个单元都是两位的,比如MODE0[1:0]就可以写入 00 01 10 11,看到下面的说明,那我们要配置推挽输出且速度为10MHZ的时候,只需在CNF0[1:0]写入00 ,在 MODE0[1:0]写入01即可,值得一提的是区分输入还是输出看的是MODE这个单元,当这个单元有写入的时候那便是输出,否则为输入,因为输入不需要速度

image-20221223202810688

image-20221224113258144

image-20221224115749024

接下来这些寄存器也是同样的道理,看着说明就好了,这里的每个单元便是对应着16个IO,所以高16位用不上了。r表示只可读,w表示只可写,rw是可读写

我们以拉低PA4为例子:步骤如下

  • 开启对应外设的时钟(时钟将会在下一章做讲解,这里先跳过)

  • image-20221224172112842

    可以看到我们只需要把2那个位 置1

  • 清除PA4的端口位

  • image-20221224172428208

    可以看到这里我们需要把BR4置1

  • 设置PA4的输出模式

    代码如下:

    int main(void)
    {
    	// 开启 GPIOB 端口 时钟
    	RCC_APB2ENR |= (1<<3);
        
    	// 清空控制 PA4 的端口位
    	GPIOA_BSRR |= (1<<5);
        
    	// 配置 PA4 为通用推挽输出,速度为 10M
    	GPIOC_CRL |= (1<<4*2);
        
    	// PA4 输出低电平
    	GPIOA_ODR &= ~(1<<4);
        
    	while (1);
    }  
    

下面是用Cubemx配置的流程:

image-20221225135636731

image-20221225135755534

然后点右上方的start project

image-20221225140056585

搜索对应的引脚

image-20221225140244212

image-20221225140424194

image-20221225140627076

ok,下面就来讲怎么写main里面的函数:

image-20221225140943103

比如这个的,其实GPIO的相关函数并不多,可以简单记一下加上有代码补全功能,你敲到HAL_GPIO_基本就会看到整个函数了,直接回车选中就行,或者我们可以在文件里面找:

image-20221225141151207

在这个文件里往下翻也能找到

函数放入的变量怎么办呢?首先我们右键函数,选择”go to definition of…“,就会跳到如下

image-20221225141404074

在断言里面继续右键,就可以看到我们可填入的变量名称了。

image-20221225141439442

实战

实战部分将演示GPIO相关的实验

1 LED灯

跑马灯配蜂鸣器

首先看原理图

image-20221226115242348

image-20221226115328425

我们只需要输出引脚拉低LED就可以亮,蜂鸣器那里我们需要拉高,main里我是写了一个红灯亮蜂鸣器就响的逻辑,PB5 PE5是LED的,PB8是蜂鸣器的

image-20221226120645794

2 按键输入

按键输入这里涉及到了一个消抖的问题,按键机械触点断开、闭合时,由于触点的弹性作用,按键开关不会马上稳定接通或一下子断开,所以我们需要采用延时函数嵌套判定来解决这一问题。

image-20221226121142070

按键这部分的实验,本质上就是我们要通过GPIO的输人模式,读取引脚外部的电平变化。

/*按下翻转电平*/
void Key_Scan()
{
	if(KEY0==0)
	{
		HAL_Delay(100);//延时消抖
		
		if(KEY0==0)
		{
			/* 等待按键松开*/
			while (KEY0==0);//这句循环要加,也是用于解决抖动产生的误判问题。
			HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_5);
		}
	}
	
	
	
	if(KEY1==0)
	{
		HAL_Delay(100);//延时消抖
		
		if(KEY1==0)
		{
			while (KEY1==0);
			HAL_GPIO_TogglePin(GPIOE, GPIO_PIN_5);
		}
	}

}

按下亮 松开灭:

image-20221226121650840

这里typora的代码块莫名嵌入后变成乱码了,这里直接截个图哈(懒得改了),具体代码我会放Github上的,到时候给个链接

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值