STC8系列单片机I/O驱动原理
STC8系列有四种驱动模式
准双向输出
强推挽输出
仅为输入(高阻)
开漏输出
准双向输出配置
说明:准双向输出可以用作输出和输入功能,而不需要重新配置I/O口腔输出状态。如下图所示:当端口锁定数据逻辑较高时,驱动力较弱,允许外部设备降低(尽量避免);当引脚输出较低时,驱动力较强,可吸收大电流。
注:(1)STC 1T单片机供电电压系列(VCC)为3.3V,建议不要在准双向口模式下直接施加5V电压在管脚上。
(2)在准双向口模式下读取外部设备状态之前,在读取正确的外部状态之前,应先将相应的端口位置1。
推拉输出配置
注:该模式提供持续的强上拉,推拉模式通常用于需要更大的驱动电流。
配置仅为输入(高阻)
注:仅为输入(高阻)配置,不提供吸收20mA电流的能力
泄漏输出配置
注:在泄漏模式下,单片机可读取引脚的外部状态;(外部上拉电阻)可正确输出高电平;否则,只要外部输出低电平正确。
(1)由于8051CPU因此,当软件执行由低到高的指令时,通常需要添加1-2个空操作延迟指令,然后读取外部状态。
(2)在STC通过单片机I/O端口模式寄存器可以切换这些引脚的工作模式
I/O端口控制寄存器组
总说明:
(1)对于LQFP 64脚封装的STC只有8系列单片机才有P6组端口和P7组端口
(2)STC8系列单片机STC8A8K64S4A12的P4组端口只有5位有效,即P5.0~P5.5,而端口P0,P1,P2,P3,P6,P7都是8位有效
控制寄存器的端口模式
说明:意思是P以0端口为例,其余类似。
端口寄存器
注:通过端口寄存器,STC单片机可以读取端口状态,或者像端口一样写数据P0为例。
补充说明:P0端口地址为80H,复位值为0xFFH
其他端口如下图所示
端口上拉电阻控制寄存器
说明:(1)在STC在8系列单片机中,每个端口都集成了用户择使用的上拉电阻。
(2)当给端口上拉寄存器相应的位写0时,禁止端口内部的3.7kΩ的上拉电阻;当给每个端口上拉寄存器相应的位写0时,使能端口内部3.7kΩ上拉电阻;默认复位后不使能。
端口施密特触发控制寄存器
说明:(1)在STC8系列单片机中,为每个端口提供了可供选择使用的施密特触发器(使用施密特触发器,可以进一步提高端口的抗干扰能力)
(2)当给每个端口施密特触发控制寄存器相应位写0时,使能施密特触发功能(上电复位后默认使能);当给每个端口施密特触发控制寄存器相应位写1时,禁止端口的施密特触发功能。
在供电电压为5V时和供电电压为3.3V时,使能和禁止施密特触发功能的允许输入电平特性见下图
(说明:STC8系列是宽电压范围供电,2.0~5.5V)
代码驱动GPIO端口的实现
汇编代码版本:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43/*
说明:此例程基于松果派增强版STC51单片机所写
效果:流水灯闪烁
单片机型号:STC8A8K64S4A12
吐槽:松果派抄袭小脚丫FPGA外形,设计小缺陷很多,不管是电路还是给的例程资料,但是出于是高中生所作,也在可以理解范围之内
*/
P5 DATA 0C8H //定义P5的SFR地址
CSEG AT 0x0000 //定义代码段起始地址
LJMP main //无条件跳转到main标号的位置
my_prog SEGMENT CODE //声明代码段
RSEG my_prog //引用代码段
ORG 0x100 //偏移地址0x100
main:
USING 0 //使用0组R0-R7
CLR P5.5 //使能PNP三极管SS8550,见下面电路图
LOOP2:
MOV A,#0FEH //赋值0xFE给累加器A
LOOP1:
MOV P1,A //复位启动后,亮最左边第一个LED
ACALL DELAY1S //延时1s
RL A//循环左移
CJNE A,#0FEH,LOOP1 //如果没有恢复初态(也就是亮左一LED),跳转循环1,依次点亮LED1-LED8
JMP LOOP2 //当A=0xFE时,重新大循环LOOP2,完成流水灯循环
/*
名称:延时子程序
说明:由单片机小精灵自动生成,晶振24M,指令周期STC1T
*/
DELAY1S: ;误差 -0.000000000056us
MOV R7,#8EH
DL1:
MOV R6,#0A8H
DL0:
MOV R5,#0FAH
DJNZ R5,$
DJNZ R6,DL0
DJNZ R7,DL1
MOV R5,#02H
DJNZ R5,$
NOP
RET
END //说明程序到这里结束
C语言代码版本:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42#include "reg51.h"
#include "intrins.h"
#define LED P1 //用LED代替P1口名字,增加程序的通用性,实际上由电路图可知P1的八个管脚分别对应着八个LED
sfr P5=0xC8; //因为传统51只在reg51.h中定义了P0~P3管脚的SFR地址,所以P5得单独声明
sbit PNP_T=P5^5;//由电路图可知PNP三极管控制管脚接的是P5.5管脚,当P5.5=0时,PNP三极管导通
/*
说明:延时1s,由单片机小精灵生成
参数:晶振24M,指令周期STC1T
*/
void delay1s(void) //误差 -0.000000000056us
{
unsigned char a,b,c,n;
for(c=142;c>0;c--)
for(b=168;b>0;b--)
for(a=250;a>0;a--);
for(n=2;n>0;n--);
_nop_(); //if Keil,require use intrins.h
}
void main()
{
unsigned char temp=0xFE;//仅亮最右边一个灯,由电路图可知,P1相应管脚为低电平时点亮
PNP_T=0; //当P5.5=0时,PNP三极管导通
while(1)
{
LED=temp;
delay1s();
/*
这里你得好好理解一下C语言下的左移操作,参见文章https://www.aye.ink/posts/175b9a61/
1111 1110- 1111 1100|0000 0001=1111 1101-...-1111 1111
当为1111 1111时恢复1111 1110 完成流水灯的循环
*/
temp=(temp<<1)|1;
if(temp==0xFF)
{
temp=0xFE;
}
}
}
电路原理图:
实物运行效果如下:
视频略…
附件下载:
Keil51汇编程序及电路图压缩包:
Keil51C语言程序压缩包: