一、STC15W系列单片机I/O的工作模式
1、准双向口(弱上拉)
顾名思义,准双向口指的是既可以用作输出功能,又可以用着输入功能,标准的8051单片机IO口就是这种工作模式。
当端口输出高电平1的时候,驱动能力很弱,也就是上拉能力很弱,如果外部电路的下拉能力比较强的话,就可以直接把IO口的电平拉低。
当端口输出低电平0时,驱动能力很强,可以吸收比较大的电流。
2、强推挽输出
强推挽输出的下拉结构与开漏输出以及准双向口的下拉结构相同,但锁存器为1时,上拉能力比较强,因此推挽模式一般用于需要较大驱动电流的情况。
3、高阻输入
高阻输入口,电流既不能流入也不能输出,就相当于把这个IO口给废了
4、开漏输出
开漏模式可以度外部状态,也可以对外输出。如果想要读取外部状态,或对外输出高电平的时候,需要加上拉电阻。
二、STC15W4K系列单片机的IO口配置
STC15系列单片机最多有62个IO口,所有的IO口都可以由软件配置成上面介绍的4种工作模式。
STC15系列单片机复位后为准双向口模式;但是P1.6和P1.7口因为兼容外部晶振引脚,它们的模式就不一定是准双向口,为了确保万无一失还是要手动配置以下,不要使用默认的配置。
STC15系列单片机每个IO口的驱动能力可达20mA,但是40PIN以上的单片机,整个芯片的最大电流不能超过120mA, 32PIN以下的单片机整个芯片的最大电流不能超过90mA。
注意:虽然每个IO口都能承受20mA的灌电流,但是不管是输入还是输出,IO口都应加个限流电阻。
STC15系列单片机的IO口最多有7组,即P0、P1、P2、P3、P4、P5、P6、P7,可以通过PxM1和PxM0寄存器来设置IO口的工作类型,x可以是0/1/2/3/4/5/6/7。
以P0口的设置为例
P0口配置需要用到的寄存器是下面三种:
P1口配置需要用到的寄存器是下面三种:
P2口配置需要用到的寄存器是下面三种:
P3口配置需要用到的寄存器是下面三种:
P4口配置需要用到的寄存器是下面三种:
P5口配置需要用到的寄存器是下面三种:
P6口配置需要用到的寄存器是下面三种:
P7口配置需要用到的寄存器是下面三种:
三、 STC15W4K系列单片机IO口的典型应用
1、IO口直接控制LED的亮灭
使用STC15W系列单片机的P5.5引脚来控制LED闪烁, 需要用到P5口相关的寄存器
首先把P55引脚的模式设置为准双向口,
然后循环把P55引脚设置为高电平(LED亮),低电平(LED灭)
在亮灭之间加一个延时函数,可以根据自己的需要设置延时时间长短;
程序代码
#include <STC15.H> //添加STC15W相关的头文件
#include <intrins.h> //为了使用_nop_()函数
void Delay500ms(void); //延时函数用STC-ISP软件生成
#define LED P55 //给P55引脚起一个跟功能相关的名字,用P55直接控制也可以
main()
{
//将P5整组的IO口都设置为准双向口模式
P5M1 = 0x00;
P5M0 = 0x00;
while(1)
{
LED = 1; //高电平LED熄灭
Delay500ms();
LED = 0; //低电平LED点亮
Delay500ms();
}
}
//
//STC-ISP生成的延时函数,比较准确
void Delay500ms(void) //@11.0592MHz
{
unsigned char data i, j, k;
_nop_();
_nop_();
i = 22;
j = 3;
k = 227;
do
{
do
{
while (--k);
} while (--j);
} while (--i);
}
如果要控制多个IO口,比如要控制8个LED的亮灭
程序代码,IO口直接控制8个LED的亮灭
#include <STC15.H> //添加STC15W相关的头文件
#include <intrins.h> //为了使用_nop_()函数
void Delay500ms(void); //延时函数用STC-ISP软件生成
main()
{
//将P1整组的IO口都设置为准双向口模式
P1M1 = 0x00;
P1M0 = 0x00;
while(1)
{
P1 = 0xFF; //8个LED全部熄灭
Delay500ms();
P1 = 0x00; //8个LED全部点亮
Delay500ms();
}
}
//
//STC-ISP生成的延时函数,比较准确
void Delay500ms(void) //@11.0592MHz
{
unsigned char data i, j, k;
_nop_();
_nop_();
i = 22;
j = 3;
k = 227;
do
{
do
{
while (--k);
} while (--j);
} while (--i);
}
2、LED流水灯控制
在上面8个LED亮灭的基础上实现流水灯
#include <STC15.H> //添加STC15W相关的头文件
#include <intrins.h> //为了使用_nop_()函数
void Delay500ms(void); //延时函数用STC-ISP软件生成
main()
{
unsigned char i; //定义一个无符号字符型局部变量 i 取值范围 0~255
//将P1整组的IO口都设置为准双向口模式
P1M1 = 0x00;
P1M0 = 0x00;
P1=0xFE; //赋初始值点亮其中的一只LED
while (1) //主循环
{
for(i=0;i<8;i++) //加入 for循环,表明for循环大括号中的程序循环执行8次
{
Delay500ms();
P1<<=1;
P1 |= 0x01; //左移之后,最右端自动赋0,需要把它变成1
}
P1=0xFE; //重新开始流水
}
}
//
//STC-ISP生成的延时函数,比较准确
void Delay500ms(void) //@11.0592MHz
{
unsigned char data i, j, k;
_nop_();
_nop_();
i = 22;
j = 3;
k = 227;
do
{
do
{
while (--k);
} while (--j);
} while (--i);
}
3、独立按键检测
电路分析:R11电阻通过5V电源,将P23口上拉,在按键没有按下的情况下,P23是高电平 ,当按键被按下,P23相当于直接接地,为低电平;电容C10是按键的硬件防抖。
程序代码:按下按键LED点亮,松开按键LED熄灭
#include <STC15.H> //添加STC15W相关的头文件
#include <intrins.h> //为了使用_nop_()函数
main()
{
//将P1整组的IO口都设置为准双向口模式
P5M1 = 0x00;
P5M0 = 0x00;
P2M1 = 0x00;
P2M0 = 0x00;
P55 = 1; //LED熄灭
while (1) //主循环
{
if(P23 == 0) //按键按下
{
P55 = 0; //点亮LED
}
else //按键松开
{
P55 = 1; //熄灭LED
}
}
}
软件延时去抖,一般的按键识别抖需要软件去抖,软件延时10到20ms即可
程序代码:按下按键LED点亮,松开按键LED熄灭,添加10ms的软件延时来去抖
#include <STC15.H> //添加STC15W相关的头文件
#include <intrins.h> //为了使用_nop_()函数
void Delay10ms(void);
main()
{
//将P1整组的IO口都设置为准双向口模式
P5M1 = 0x00;
P5M0 = 0x00;
P2M1 = 0x00;
P2M0 = 0x00;
P55 = 1; //LED熄灭
while (1) //主循环
{
if(P23 == 0) //按键按下
{
Delay10ms(); //软件延时去抖动
if(P23 == 0)//按键依旧是按下
{
P55 = 0; //点亮LED
}
}
else //按键松开
{
Delay10ms(); //软件延时去抖动
if(P23 == 1)//按键依旧是松开
{
P55 = 1; //熄灭LED
}
}
}
}
//
//10ms延时
void Delay10ms(void) //@11.0592MHz
{
unsigned char data i, j;
i = 108;
j = 145;
do
{
while (--j);
} while (--i);
}
独立按键控制LED的状态,没按一次按键LED的状态就改变一下,亮的时候就变成灭,灭的时候就百城亮
程序代码
#include <STC15.H> //添加STC15W相关的头文件
#include <intrins.h> //为了使用_nop_()函数
void Delay10ms(void);
main()
{
//将P1整组的IO口都设置为准双向口模式
P5M1 = 0x00;
P5M0 = 0x00;
P2M1 = 0x00;
P2M0 = 0x00;
P55 = 1; //LED熄灭
P23 = 1; //按键的初始状态
while (1) //主循环
{
if(!P23)
{
Delay10ms(); //软件延时防抖
if(!P23)
{
while(!P23); //等待按键松开
P55 = !P55; //改变LED的状态
}
}
}
}
//
//10ms延时
void Delay10ms(void) //@11.0592MHz
{
unsigned char data i, j;
i = 108;
j = 145;
do
{
while (--j);
} while (--i);
}