我们在学习STM32的过程中,有时候会遇到原理不清楚的问题,所以本篇文章将对GPIO的输入输出模式与配置方法进行简单的介绍,方便各位同学理解与使用。
注:本文部分图片来自于*STM32F10xxx参考手册。
提示:以下是本篇文章正文内容,下面案例可供参考
每个GPIO端口有两个32位配置寄存器(GPIOx_CRL,GPIOx_CRH),两个32位数据寄存器(GPIOx_ IDR和GPIOx_ ODR),一个32位置位/复位寄存器(GPIOx_ BSRR),一个16位复位寄存器(GPIOx_ BRR)和一个32位锁定寄存器(GPIOx_ LCKR)。
根据数据手册中列出的每个I/O端口的特定硬件特征,GPIO端口的每个位可以由软件分别配置成多种模式。
-输入浮空
-输入上拉
-输入下拉
-模拟输入
-开漏输出
-推挽式输出
-推挽式复用功能
-开漏复用功能
当IO口配置为输入时:
浮空模式下CPU可以读取到外部输入的高或低电平。
输入信号经过施密特触发器接入输入数据存储器。当无信号输入时,电压不确定。
可以认为输入端口阻抗无穷大,这样可以方便检测到微弱的信号。此时输入高电平即高电平,输入低电平即低电平。但是外界没有输入时输入电平却容易受到外界电磁干扰的影响。
如:按键采用浮空输入,则在按键按下时输入电平为低,但是当松开按键时输入端口悬空,外界有微弱的干扰都会被端口检测到。此时端口可能高,也可能低。
与上一部分的浮空输入模式相比,仅仅是在数据通道上面,接入了一个上拉电阻。
根据STM32的数据手册,这个上拉电阻阻值介于30K~50K 欧姆。
同样,CPU可以随时在“输入数据寄存器”的另一端,通过内部的数据总线读出I/O 端口的电平变化的状态。
无输入信号时端口电平被拉到高电平。
例如按键信号,当按下时输入低电平,松开时电平被拉到高电平。这样就不会出现按键松开时端口电平不确定的情况。即不知道时按下还是松开。
对于下拉模式的输入,其实是在数据通道的下部,接入了一个下拉电阻。
根据STM32的数据手册,这个下拉电阻阻值也是介于30K~50K 欧姆。
浮空输入在外界没有输入时状态不确定,可能对电路造成干扰。为了使得电路更加稳定,不出现没有输入时端口的输入数据被干扰 (比如手碰一下电压就发生变化)。
这时就需要下拉(上拉)电阻。此电阻与端口输入阻抗相比仍然较小。有输入信号时端口读取输入信号,无输入信号时端口电平被拉到低(高)电平。
当单片机的IO口作输出时,如果不接上拉电阻只能提供灌电流。无法输出电流驱动外接设备。这时也需要考虑上拉电阻。这样才可以使IO输出高电平。
如果把STM32配置为模拟输入模式时,工作原理就十分简单了,信号从左边编号为1 的端口进从右边编号为2的一端直接进入STM32单片机的AD模块。
输入信号不经施密特触发器直接接入,输入信号为模拟量而非数字量,其余输入方式输入数字量。
以上分析的是GPIO的输入模式,下面分析它的输出模式。
当I/O端口被配置为输出时:
当I/O口被配置为复用时:
开漏输出高电平时是由外接电源输出的,因此可以实现高于输出端口电压的输出。可以实现电平的转换。开漏输出可以实现线与功能,方法是多个输出共接一个上拉电阻。但是漏极开路输出上升沿慢,因为上升沿是外接电源对上拉电阻以及外接负载充电。
GPIO的推挽输出模式是在开漏输出模式的基础上,在“输出控制电路”之后,增加了一个P-MOS管
当CPU输出逻辑“1 ”时,编号3 处的P-MOS管导通,而下方的N-MOS管截止,达到输出高电平的目的
当CPU输出逻辑“0 ”时,编号3 处的P-MOS管截止,而下方的N-MOS管导通,达到输出低电平的目的
在这个模式下,CPU 仍然可以从“输入数据寄存器”读到该IO端口电压变化的信号
GPIO的开漏复用输出模式与开漏输出模式的工作原理基本相同
不同的是编号为2的输入源不同,它是和复用功能的输出端相连
此时的“输出数据寄存器”被输出通道给断开了。
同样,CPU也可以从“输入数据寄存器”读取到外部IO端口变化的电平信号。
编号2 “输出控制电路” 输入与复用功能的输出端相连
此时“输出数据寄存器”被从输出通道断开了,片上外设的输出信号直接与“输出控制电路”的输入端想连接。
在将GPIO配置成复用输出功能后,假如相应的外设模块没有被激活,那么此时IO端口的输出将不确定。
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE, ENABLE);
(1)引脚
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
(2)速度
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
(3)模式
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
模式的配置介绍:
一个IO口需要4个bit来控制:
CNF MODE CNF MODE
00 00 ~ 11 11
也就是十六进制的 0x 0 ~ 0x F
其中MODE是设置输入输出模式::
而CNF是在MODE的基础上选择更细分的模式:
(1)当MODE为00,即输入模式下:
(2)当MODE为01,10,11,即输出模式时:
GPIO_Init(GPIOC, &GPIO_InitStructure);
GPIO_Init(GPIOE, &GPIO_InitStructure);
(1) 作为普通GPIO输入:
根据需要配置该引脚为浮空输入、带弱上拉输入或带弱下拉输入,同时不要使能该引脚对应的所有复用功能模块。
(2) 作为普通GPIO输出:
根据需要配置该引脚为推挽输出或开漏输出,同时不要使能该引脚对应的所有复用功能模块。
(3) 作为普通模拟输入:
配置该引脚为模拟输入模式,同时不要使能该引脚对应的所有复用功能模块。(A/D模拟输入)
(4) 作为内置外设的输入:
根据需要配置该引脚为浮空输入、带弱上拉输入或带弱下拉输入,同时使能该引脚对应的某个复用功能模块。
(5)作为内置外设的输出:
根据需要配置该引脚为复用推挽输出或复用开漏输出,同时使能该引脚对应的所有复用功能模块。