GPIO
1.说明
GPIO,英文全称 General-purpose input/output,即通用型输入输出,是单片机中最常用的外设之一。
2、设置模式
STC15系列单片机最多有62个I/O口(如64-pin单片机): P0.0 ~ P0.7, P1.0~P1.7, P2.0 ~ P2.7,P3.0 ~ P3.7,P4.0 ~ P4.7,P5.0~ P5.5,P6.0 ~ P6.7,P7.0 ~ P7.7。其所有I/O口均可由软件配置成4种工作类型之一,如下表所示。4种类型分别为:
1.准双向口/弱上拉(标准8051输出模式)
2.推挽输出/强上拉
3.高阻输入(电流既不能流入也不能流出)
4.开漏输出功能
每个口由2个控制寄存器中的相应位控制每个引脚工作类型。STC15系列单片机的I/O口上电复位后为准双向口/弱上拉(传统8051的IO口)模式。每个I/0口驱动能力均可达到20mA,但40-pin及40-pin以上单片机的整个芯片最大不要超过120mA,20-pin以上及32-pin以下(包括32-pin)单片机的整个芯片最大不要超过90mA。
如下图,STC15 单片机的 GPIO 可以设定为 4 种工作模式, 分别为准双向口、推挽输出、高阻输入、开漏。可以通过 PxM1 与 PxM0 寄存器进行配置。
其他GPIO口就用对应的PxM1和PxM0寄存器进行配置即可,通过官方的举例可看出配置方法:两排二进制数,依次对齐,最高位是P3.7口,两个寄存器的最高位都是1的话,P3.7口就被配置成了开漏模式,后面依次类推
准双向口
输出使用:
内部给低电平——反相器——高电平——三极管导通——PX.x与GND导通,灌电流从PX.x流入到GND,有20mA——输出低电平
内部给高电平——反相器——低电平——三极管截止——通过上拉电阻,拉电流从VCC流出到PX.x,有270uA——输出高电平
输入使用:
如果内部给低电平——反相器——高电平——三极管导通——PX.x不论是输入高电平还是低电平,因为接GND,都会变成低电平——无法输入
所以内部要给高电平——反相器——低电平——三极管截止——PX.x输入高电平即高电平,输入低电平即低电平
推挽输出
把准双向口的上拉电阻换成了PNP三极管,两个三极管工作时只能有一个导通
只能作输出使用,不能作输入:
内部给低电平——反相器——高电平——下面NPN三极管导通——PX.x与GND导通,灌电流从PX.x流入到GND,有20mA——输出低电平
内部给高电平——反相器——低电平——上面PNP三极管导通——VCC对外输出20mA电流——输出高电平
PNP低电平导通,箭头向里。
NPN高电平导通,箭头向外。
NPN和PNP的E极带箭头。
高阻输入
高阻态电路 指的是电路的一种输出状态也就叫做高阻输入,高阻态是一个数字电路里常见的术语,指的是电路的一种输出状态,既不是高电平也不是低电平,如果高阻态再输入下一级电路的话,对下级电路无任何影响,和没接一样,如果用万用表测的话有可能是高电平也有可能是低电平,随它后面接的东西定。
高阻态的实质:
电路分析时高阻态可做开路理解。你可以把它看作输出(输入)电阻非常大。他的极限可以认为悬空。也就是说理论上高阻态不是悬空,它是对地或对电源电阻极大的状态。而实际应用上与引脚的悬空几乎是一样的。
高阻态的意义:
当门电路的输出上拉管导通而下拉管截止时,输出为高电平;反之就是低电平;如上拉管和下拉管都截止时,输出端就相当于浮空(没有电流流动),其电平随外部电平高低而定,即该门电路放弃对输出端电路的控制 。
高阻 简言之就是 输入输出电阻都相当大,相当于隔离状态。处在高阻态的三态门是与总线隔离开的,这样总线可以同时被其他电路占用。
高阻:从逻辑器件内部电路结构来说,就是其输出电阻很大,该状态即不是高电平,也不是低电平。当三态门处于高阻态时,无论该门的输入如何变化,都不会对其输出有贡献。
只能作为输入使用
开漏
跟准双向口相比,没有上拉电阻,跟推挽输出相比,没有PNP三极管
输出使用:
内部给低电平——反相器——高电平——三极管导通——PX.x与GND导通,灌电流从PX.x流入到GND,有20mA——输出低电平
内部给高电平——反相器——低电平——三极管截止——因为是OC门输出,无法输出高电平
输入使用:
内部给高电平——反相器——低电平——三极管截止——PX.x输入高电平即高电平,输入低电平即低电平
程序
需要注意的是因为开发板设计D1指示灯的一端是接地的,与之前的板子的LED灯一端接VCC的不同,这次要给高电平才能点亮,低电平是熄灭
因为是高电平才点亮,默认GPIO是准双向口,是弱上拉的,输出的高电平电流小,才270uA,驱动能力弱,LED灯亮度小,配置为推挽输出后,强上拉,输出高电平有20mA,电路已经接上限流电阻,所以LED灯亮度比弱上拉的大
#include <STC15.h>
#include "Delay.h"
/**
* @name main
* @brief主函数
* @param无
* @retval无
*/
void main()
{
//1.时钟初始化————可通过STC-ISP软件进行设置
//2.GPIO初始化
// M1 M0
// 0 0 准双向
// 0 1 推挽输出
// 1 0 高阻输入
// 1 1 开漏
/*配置P3.4和P3.5口为推挽输出,P3.4接到系统指示灯,P3.5接PWM灯
若不设置为推挽输出,单片机默认是准双向口弱上拉的,而指示灯要
给高电平才点亮,上拉电流才270uA,灯的亮度较小;
配置为推挽输出后,强上拉,电流可达20mA,亮度较大*/
P3M1 = 0x00; //0000 0000
P3M0 = 0x30; //0011 0000
/*因为硬件设置了外设的电源和单片机的电源是分开供电的,
单片机要往P54引脚给高电平打开PMOS开关,外设才能启动工作
所以如果想要PWM灯也闪烁的话,就要开启外设的供电开关
P54引脚输出高电平,打开PMOS开关,才能给外设(PWM灯供电)*/
P5M1 = 0x00; //0000 0000
P5M0 = 0xFF; //1111 1111
P54 = 1; //打开PMOS开关,给外设供电
//一开始让灯灭,因为指示灯的另一端接地,P34口高电平灯才亮,低电平灯灭
P34 = 0;
while(1)
{
//写法一:
P34 = 0; //运行指示灯灭
P35 = 0; //PWM灯灭
Delay1ms(1000);
P34 = 1; //运行指示灯亮
P35 = 1; //PWM灯亮
Delay1ms(1000);
//写法二:
// P34 = ~P34;
// Delay1ms(1000);
//写法三:
// P3 |= 0x01<<4;
// Delay1ms(1000);
// P3 &= ~(0x01<<4);
// Delay1ms(1000);
//写法四
// P3 |= 0x10; //0001 0000
// Delay1ms(1000);
// P3 &= 0xEF; //1110 1111
// Delay1ms(1000);
}
}