STM32单片机——GPIO

本文详细介绍了STM32芯片的GPIO模块,包括其功能、基本结构、位结构、模式(输入、输出、模拟和复用功能),以及各种模式下的工作原理和应用场景,如上拉/下拉输入保护、施密特触发器整形、推挽和开漏输出等。
摘要由CSDN通过智能技术生成

一.GPIO简介

       GPIO(general porpose intput output):通用输入输出端口的简称。可以通过软件控制其输出和输入。stm32芯片的GPIO引脚与外部设备连接起来,从而实现与外部通信,控制以及数据采集的功能。

1.可配置为8种输入输出模式

2.引脚电平:0V~3.3V,部分引脚可容忍5V

3.输出模式下可控制端口输出高低电平,用以驱动LED、控制蜂鸣器、模拟通信协议输出时序等

4.输入模式下可读取端口的高低电平或电压,用于读取按键输入、外接模块电平信号输入、ADC电压采集、模拟通信协议接收数据等

二.GPIO基本结构

       如下图,这就是GPIO的整体构造,其中左边是APB2外设总线,在stm32中,所有的GPIO都是挂载在APB2外设总线上的,其中GPIO外设的名称是按照GPIOA,GPIOB,GPIOC等等这样来命名的,每个GPIO外设总共有16个引脚,编号从0到15,那GPIOA的第0号引脚,称作PA0,接着第2号引脚就是PA1,然后PA2以此类推一直到PA15。

       在每个GPIO模块内主要包含寄存器和驱动器,寄存器就是一段特殊的存储器,内核通过APB2总线对寄存器进行读写,来完成输出电平和读取电平的功能,寄存器的每一位对应一个引脚,其中输出寄存器写1,对应的引脚就会输出高电平;写0,就输出低电平输。输入寄存器读取为1,就证明对应的端口目前是高电平;读取为0,就是低电平。

       因为stm32是32位的单片机,所以stm32内部的寄存器都是32位的,但端口只有16位,所以这个寄存器只有低16位对应的有端口,高16位是没有用到的。这个驱动器是用来增加信号的驱动能力的,寄存器只负责存储数据,如果要进行点灯这样的操作的话是需要驱动器来负责增大驱动能力。

 

ecd1c10ca1fe43a195275837ff02ba50.jpg

三.GPIO位结构

      下图就是stm32参考手册中的GPIO位结构的电路图,其中左边三个就是寄存器,中间部分是驱动器,右边是某一个io引脚,整体结构可以分为两个部分,上面是输入部分,下面是输出部分。

     先来看输入部分,io引脚这里接了两个保护二极管,是对输入电压进行限幅的,上面这个二极管接vdd 3.3伏,下面接vss 0伏,如果输入电压比3.3伏还要高,那上方这个二极管就会导通,输入电压产生的电流就会直接流入VDD而不会流入内部电路,可以避免过高的电压对内部这些电路产生的伤害。如果输入电压比零伏还要低,这个电压是相当于vss的电压,所以是可以有负电压的,这时下方这个二极管就会导通,电流会从vss直接流出去,而不会从内部电路汲取电流,也是可以保护内部电路的,如果输入电压在0到3.3伏之间,那两个二极管都不会导通,这时二极管对电路没有影响,这就是保护二极管的用途。

     接下来这根线就到了开关这个地方,这里连接了一个上拉电阻和一个下拉电阻,上拉电阻是vdd,下拉电阻是vss,这个开关是可以通过程序进行配置的,如果上面导通,下面断开,打开又是上拉输入模式,如果下面导通,上面断开就是下拉输入模式,如果两个都断开就是浮空输入模式,那这个上拉和下拉有什么作用呢?这个其实是为了给输入提供一个默认的输入电平,因为对于一个数字的端口,输入不是高电平就是低电平,那如果输入引脚啥都不接,那到底是算高电平还是低电平呢?这就不好说了,实际情况是如果输入啥都不接,这时输入就会处于一种浮空的状态,引脚的输入电平极易受外界干扰而改变,就像是一个物体悬浮在太空一样,它的位置是不确定的,受到一点扰动就会变化,为了避免引脚悬空而导致的输入数据不确定,我们就需要在这里加上上拉或者下拉电阻了,如果接入上拉电阻,当引角悬空时,还有上拉电阻来保证引脚的高电平。所以上拉输入又可以称作是默认为高电平的输入模式,下拉也是同理,就是默认为低电平的输入方式,这就像是在太空的物体来到了地球上,如果不施加外力,由于重力的下拉作用,默认还是回到地面,这个上拉电阻和下拉电阻的阻值都是比较大的,是一种弱上拉和弱下拉,目的是尽量不影响正常的输入操作。

       接着我们继续往下看,这里是一个肖特基触发器,这里写的是施密特触发器的英文,这个斯密特触发器的作用就是对输入电压进行整形,它的执行逻辑是如果输入电压大于某一阈值,输出就会瞬间升为高电平,如果输入电压小于某一阈值,输出就会瞬间变为低电平。

       最后左上面这还有两路线路,这些就是连接到片上外设的一些端口,其中有模拟输入,这个是连接到ADC上的,因为ADC需要接收模拟量,所以这根线是接到施密特触发器前面的,另一个是复用功能输入,这个是连接到其他需要读取端口的外设上的,比如串口的输入引脚等,这根线接收的是数字量,所以在施密特触发器后面。

       接着我们再来看一下输出的部分,输出部分可以由输出数据寄存器或片上外设控制。两种控制方式通过数据选择器接到了输出控制部分,如果选择通过输出数据寄存器进行控制,就是普通的io口输出,写这个数据寄存器的某一位就可以操作对应的某个端口了,左边还有位设置/清除寄存器,这个可以用来单独操作输出数据寄存器的某一位,而不影响其他位,因为这个输出数据寄存器同时控制16个端口,并且这个寄存器只能整体读写,所以如果想单独控制其中某一个端口而不影响其他端口的话,就需要一些特殊的操作方式,常用的方式是通过设置位设置和位清除寄存器,我们需要对某一位进行置1的操作,在位设置寄存器的对应位写1即可,剩下不需要操作的位写0,这样它内部就会有电话,自动将输出数据寄存器对应位置为1,而剩下写0的位则保持不变,这样就保证了只操作其中某一位而不影响其他位,并且这是一步到位的操作,如果想对某一位进行清零的操作,就在位清除寄存器的对应位写1即可,这样内部电路就会把这一位清零了,这也是这个位设置和位清除寄存器的作用。

      继续看,接下来输出控制之后就接到了两个MOS管,上面是P-MOS,下面是N-MOS,这个MOS就是一种电子开关,我们的信号来控制开关的导通和关闭开关,开关负责将io口接到vdd或者vss,在这里可以选择推挽,开漏或关闭三种输出方式,在推挽输出模式下,P-MOS或N-MOS均有效。数据寄存器为1时,上管导通,下管断开,输出直接接到vdd,就是输出高电平,数据寄存器为零时,上管断开下管导通,输出直接接到vss,就是输出低电平。这种模式下,高低电平均有较强的驱动能力,所以推挽输出模式也可以叫强推输出模式。在推广输出模式下,stm32对io口具有绝对的控制权,高低电平都由stm32说的算,在开漏输出模式下,这个P-MOS是无效的,只有N-MOS在工作,数据寄存器为1时,下管断开,这时输出相当于断开,也就是高阻模式,数据寄存器为0时,下管导通,输出直接接到vss,也就是输出低电平。这种模式下只有低电平有驱动能力高电平是没有驱动能力的,那这个模式有什么用呢,这个开漏模式可以做为通信协议的驱动方式,比如12c通信的引脚,就是使用的开漏模式。在多机通信的情况下,这个模式可以避免各个设备的相互干扰,另外开漏模式还可以用于输出5伏的电平信号,比如在io口外接一个上拉电阻到五伏的电源,当输出低电平时,由内部的N-MOS直接接vss,当输出高电平时,由外部的上拉电阻拉高至五伏,这样就可以输出五伏的电平信号,用于兼容一些五伏电平的设备,这就是开漏输出的主要用途。剩下的一种状态就是关闭,这个是当引脚配置为输入模式的时候,这两个MOS管都无效,也就是输出关闭,端口的电平由外部信号来控制,那这些就是GPIO位结构的全部介绍。

e098d994be164ed0bd5fdfe6f5059fe8.jpg

 

 

 

四.GPIO模式

369206a9d99d44c4b42dd1d0933253d6.jpg

 

在输入模式时,施密特触发器打开,输出被禁止。

可通过输入数据寄存器GPIOx_IDR 读取 I/O 状态。

输入模式可以配置为模拟、上拉、下拉以及浮空模式。上拉和下拉输入很好理解,默认的电平由上拉或者下拉决定。

浮空输入的电平是不确定的,完全由外部的输入决定,一般接按键的时候可以使用这个模式。

模拟输入则用于 ADC 采集。

7d156a1bc5a44756b89b44d1b0dcdacb.jpg

 

0c82f99707ca499495110aed7ae60656.jpg 

在输出模式中,推挽模式时双 MOS 管以推挽方式工作,输出数据寄存器GPIOx_ODR 可控制 I/O 输出高低电平。

开漏模式时,只有 N-MOS 管工作,输出数据寄存器可控制 I/O 输出高阻态或低电平。

输出速度可配置,有2MHz\25MHz\50MHz 的选项。此处的输出速度即 I/O 支持的高低电平状态最高切换频率,支持的频率越高,功耗越大,如果功耗要求不严格,把速度设置成最大即可。

在输出模式时,施密特触发器是打开的,即输入可用,通过输入数据寄存器 GPIOx_IDR 可读取 I/O 的实际状态。

 

816a04480caf4e169a3fb72d14316f08.jpg

复用功能模式中,输出使能,输出速度可配置,可工作在开漏及推挽模式,但是输出信号源于其它外设,输出数据寄存器 GPIOx_ODR 无效;输入可用,通过输入数据寄存器可获取 I/O 实际状态,但一般直接用外设的寄存器来获取该数据信号。a5db47e6440142dc8b076ff15ca24f10.jpg 

 

 

 

 

 

 

 

  • 20
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
如果您的STM32单片机屏幕一直闪烁,可能是因为您的程序中使用了循环延时的方式,导致CPU一直忙碌而无法及时刷新屏幕。为了解决这个问题,可以使用STM32的定时器中断来实现LED的闪烁,从而释放CPU资源,让它能够及时地刷新屏幕。 以下是使用TIM中断方式实现LED闪烁的示例代码: ```c #include "stm32f10x.h" void TIM2_IRQHandler(void) // 定时器2中断服务函数 { if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET) // 检查是否发生了更新事件 { static uint8_t led_state = 0; if (led_state == 0) { GPIO_SetBits(GPIOC, GPIO_Pin_13); // PC13输出高电平 led_state = 1; } else { GPIO_ResetBits(GPIOC, GPIO_Pin_13); // PC13输出低电平 led_state = 0; } TIM_ClearITPendingBit(TIM2, TIM_IT_Update); // 清除中断标志位 } } int main(void) { GPIO_InitTypeDef GPIO_InitStructure; TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; NVIC_InitTypeDef NVIC_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE); // 使能GPIOC时钟 RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); // 使能TIM2时钟 // 配置GPIOC.13为推挽输出 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOC, &GPIO_InitStructure); // 配置TIM2 TIM_TimeBaseStructure.TIM_Period = 999; // 自动重载值 TIM_TimeBaseStructure.TIM_Prescaler = 7199; // 预分频器 TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE); // 使能更新中断 TIM_Cmd(TIM2, ENABLE); // 启动定时器 // 配置NVIC NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); while (1) { // 空闲循环 } } ``` 在上面的代码中,我们使用了定时器TIM2,并把它配置为1ms的定时器。在定时器中断服务函数中,我们通过改变LED的状态来实现LED的闪烁。由于使用了中断方式,CPU不会一直忙碌,从而可以释放CPU资源,让它能够及时地刷新屏幕。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值