STC15系列单片机学习2:GPIO的结构与应用

一、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);
}

  • 4
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值