STM32的GPIO原理及操作

本文详细介绍了GPIO的八种输入输出模式,包括上拉输入、下拉输入、浮空输入、模拟输入、复用功能以及推挽和开漏输出。还讲解了如何通过RCC时钟和GPIO_Init函数操作GPIO,以及LED闪烁和按键输入的示例。
摘要由CSDN通过智能技术生成

一、GPIO

1、GPIO的八种输入输出模式

GPIO位结构图如下图所示:

fcf7eb0f3ed8410eb6b0560106fa26fd.png

上图分两部分,上半部分为输入控制,下半部分为输出控制,先从最右边的“保护二极管”看起:

保护二极管的作用是防止电压过高或过低而产生对内部电路的损坏。当输入电压大于Vdd时(stm32的Vdd是3.3v),上方的二极管就会导通,电流由I/O引脚流入通过保护二极管直接流入Vdd而不会进入内部电路从而保护了内部电路;相同的,当输入电压小于Vss时,下方的二极管就会导通,电流由Vss通过保护二极管直接流出,而不会从内部电路汲取电流;如果输入电压在Vss和Vdd之间,那么两个二极管都不导通,从而保证电路正常工作。

(1)输入模式

接下来先看上半部分,也就是GPIO的输入模式,首先是下图这里:

29393c085ba849b8ac934dbda4ffa2bf.png

 这里当上方导通下方断开则为上拉输入模式,上方断开下方导通则为下拉输入模式,两者都断开则为浮空输入模式。但因为浮空输入模式非常不稳定,易受外界信号干扰,所以就引出了上拉输入和下拉输入模式的作用,即事先给定一个高/低电平,使引脚在悬空状态下仍能固定输出高低电平。但这里上拉下拉电路中电阻较大,是一种弱上拉或弱下拉,这样能够尽量不影响正常输入。

下一步来看这个施密特触发器(江协科技中讲到这里的肖特基触发器应该是个翻译错误)如下图:c54afb37afb9425689cdb5a81753a59a.png

 这个触发器的执行逻辑为:当输入电压大于某一阈值,那就输出高电平;当输入电压小于某一阈值,那就输出低电平。这样可以减少信号输入失真抖动时的影响。

经过施密特触发器整形后的信号就可以直接写入寄存器然后读取某一位的高低电平了。除此之外还有两类输入:1.模拟输入,需要读取模拟量所以在施密特触发器之前,用来接ADC,因为ADC就是读取模拟量。2.复用功能输入:需要读取数字量所以在施密特触发器之后,比如串口的输入引脚等。

(2)输出模式

接下来是输出部分,如下图:7cffbda45e7440c6a788fb97bba558b3.png

输出可由输出数据寄存器和片上外设控制,经过输出控制器后来到P-MOS和N-MOS两电子开关处,此处可选择推挽、开漏或关闭输入模式。1、推挽输出:当数据寄存器为1时,P-MOS导通,N-MOS断开,输出直接接到Vdd,输出高电平;当数据寄存器为0时,P-MOS断开,N-MOS导通,输出直接接到Vss,输出低电平。此时高低电平均有较强的驱动能力,stm32对I/O口有绝对的控制权,高低电平由stm32决定。2、开漏输出:在开漏输入模式下P-MOS无效,当数据寄存器为1时,N-MOS断开,也就是输出断开,相当于高阻模式,当数据寄存器为0时,输出低电平。这个模式下只有低电平有驱动能力,在I2C通信协议中采用这个方式能避免多个通信之间相互干扰。此外,开漏输出还可以用来输出5V的电平信号。3.关闭输出:P-MOS和N-MOS两电子开关都无效。

(3)总结

程序名称模式名称性质特征
GPIO_Mode_IN_FLOATING浮空输入数字输入可读取引脚电平,若引脚悬空则电平不确定
GPIO_Mode_IPU上拉输入数字输入可读取引脚电平,悬空时默认高电平
GPIO_Mode_IPD下拉输入数字输入可读取引脚电平,悬空时默认低电平
GPIO_Mode_AIN模拟输入模拟输入GPIO无效,引脚直接接入内部ADC
GPIO_Mode_Out_PP推挽输出数字输出可输出引脚电平,高电平接Vdd,低电平接Vss
GPIO_Mode_Out_OD开漏输出数字输出可输出引脚电平,高电平为高阻态,低电平接Vss
GPIO_Mode_AF_PP复用推挽输出数字输出由片上外设控制,高电平接Vdd,低电平接Vss
GPIO_Mode_AF_OD复用开漏输出数字输出由片上外设控制,高电平为高阻态,低电平接Vss

 

2、操作GPIO

操作GPIO口的步骤为三个部分:

(1)使用RCC开启GPIO时钟

(2)使用GPIO_Init函数初始化GPIO

(3)使用输入输出函数控制GPIO

2.1 GPIO输出:

以LED灯闪烁代码为例:

#include "stm32f10x.h"                  // Device header
#include "Delay.h"

int main(void)
{
	 \\第一步,开启RCC时钟 
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); 
	
    \\第二步,使用GPIO_Init函数初始化GPIO
	GPIO_InitTypeDef GPIO_InitStructure;   
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	
	GPIO_Init(GPIOA,&GPIO_InitStructure);
	
    \\第三步,使用输入输出函数控制GPIO
	while(1)
	{
	    GPIO_WriteBit(GPIOA,GPIO_Pin_0,Bit_RESET);
		Delay_ms(500);
	    GPIO_WriteBit(GPIOA,GPIO_Pin_0,Bit_SET);
		Delay_ms(500);
		
		//GPIO_WriteBit(GPIOA,GPIO_Pin_0,(BitAction)0);
		//GPIO_WriteBit(GPIOA,GPIO_Pin_0,(BitAction)1);
	}	
}

由此可以看出GPIO输出的运行规则。 

2.2  GPIO输入:

首先来看按键输入。按键的原理其实就是按下接通,松手断开,这个过程会出现一定的机械抖动。

按键的硬件电路如下:

8ea7c1a0d29a42dcb6ef96c866a03a93.png

由这个原理图可以看出当按键按下接通时,PA0引脚直接接到GND,此时读取端口的电平为低电平;当按键松开时,PA0引脚处于悬空状态,此时端口的电压如果是浮空输入就会出现电平不确定的错误情况,所以这种接法一定要配置上拉输入模式。相较而言,以下硬件电路接法就很好的规避了这个问题:

e03299742a6c4d00afa74ea132fc0bd6.jpeg

以上是一些硬件基础,接下来还要复习一些软件基础,比如c语言的一些知识:

2.2.1  c语言的数据类型

关键字位数表示范围stdint关键字ST关键字
char8-128~127int8_ts8
unsighed char80~255uint8_tu8
short16-32768~32767int16_ts16
unsighed short160~65535uint16_tu16
int32-2147483648~2147483647int32_ts32
unsighed int320~4294967295uint32_tu32
long32-2147483648~2147483647 s32
unsighed long320~4294967295 u32
long long64-2^64/2~2^64/2-1int64_ts64
unsighed  long long640~2^64-1uint64_tu64
float32-3.4e38~3.4e38  
double64-1.7e308~1.7e308  

 2.2.2 c语言的宏定义

关键字:#define

用途:用一个字符串代替一串数字,便于理解,防止出错。

注意:定义后不加分号,定义的新名字在左边

2.2.3 c语言的typedef

关键字:typedef

用途:将一个比较长的变量类型名换个名字,便于使用

注意:定义后加分号,定义的新名字在右边,只能专门给变量类型换名字

2.2.4 c语言的结构体

关键字:struct

用途:数据打包,不同类型变量的集合

定义结构体变量:struct{char x;int y; float z;} StructName;

引用结构体成员:StructName.x =  'A';

                             StructName.y =  66; 

2.2.5 c语言的枚举

关键字:enum

用途:定义一个取值受限制的整型变量,用于限制变量的取值范围;宏定义的集合

定义枚举变量:

        enum{FALSE = 0,TRUE = 1} EnumName;

        因为枚举变量类型较长,所以通常用typedef更改变量类型名

引用枚举成员:

        EnumName  = FALSE;

        EnumName  = TRUE;

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值