51单片机流水灯实验

基于51单片机的流水灯实验

我们知道通过编写程序对51单片机进行控制,完成流水灯实验的方式有许多种。今天我们试通过51单片机的中断系统来完成流水灯实验。

在此之前,我们应首先清楚中断的概念。那么,什么是中断呢?中断是指:CPU在处理事件1时,发生了另一事件2,并请求CPU去处理(中断的发生)。此时,CPU暂时停止处理当前的事件1(中断响应),去处理事件2(中断服务);等到CPU将事件2处理完成之后,再回到事件1中断产生的地方继续进行处理事件1(中断返回)。这就好比当我们在吃饭的时候,突然门铃响了,我们起身去开门,然后回来继续吃我们吃了一半的馒头。
AT80C51单片机的中断系统有5个中断源,分别是外部中断0(INT0)、外部中断1(INT1)、定时/计数器0(T0)、定时/计数器1(T1)、串行口(Rx,Tx)。现在我们主要介绍外部中断,并通过外部中断实现我们今天的任务。那么,我们应该如何去使用外部中断呢?现在我们来介绍它的原理及其应用。

我们知道,操作单片机的本质就是操作或设置寄存器。我们来看下面这张图。这是中断系统的结构。

当我们在使用单片机的时候,需要设置几个寄存器:

1、中断允许寄存器IE

这个寄存器的作用是用来设置各个中断源的打开和关闭,可以位寻址,在此需要注意的是,当单片机被复位时,IE被全部清零。由上图的结构可以看出,EA的作用为总中断允许位。EA = 1,打开总中断;EA = 0,关闭总中断。ES为串行口中断允许位。ES = 1 ,打开;ES = 0,关闭。ET1(ET0)为定时/计数器的中断允许位,ET1(ET0) = 1,打开;ET1(ET0) = 0,关闭。EX1(EX0)为外部中断允许位,EX1(EX0)= 1,打开;EX1(EX0)= 0。

2、中断优先级寄存器IP

AT80C51单片机有两个中断优先级,可实现二级中断服务嵌套,需要注意的是,与中断允许寄存器相似,单片机复位时,IP被全部清零。PS是串行口中断优先级控制位。PS = 1,串行口中断为高优先级中断;PS = 0,串行口中断为低优先级中断。PT1(PT0)是定时/计数器中断优先级控制位。PT1(PT0)= 1,定义为高优先级中断;PT1(PT0)= 0,为低优先级中断。PX1(PX0)为外部中断优先级控制位。PX1(PX0) = 1,为高优先级中断;PX1(PX0) = 0,为低优先级中断。中断优先级有三条原则:1、首先响应高优先级的中断请求。2、高优先级的中断请求可打断低优先级中断。3、低优先级中断不可打断高优先级和同优先级中断。中断级别的排行:外部中断0>定时/计数器0>外部中断1>定时/计数器1>串行口。

下面我们来看外部中断,外部中断0(1),端口引脚为P3.2(P3.3),引脚符号为INT0(1)。外部中断的请求方式有两种,一种是负边沿触发,即令IT0 = 1即可;另一种是低电平触发,即令IT0 = 0即可。然后我们来设置中断允许寄存器IE,首先我们应该先打开总中断,令EA = 1。然后令EX0= 1。这样我们的IE寄存器就设置好了,之后在编写中断服务函数即可。

介绍了外部中断的原理及其应用后,我们开始完成任务。我们的任务是,按下开关,使得8个LED灯的轮流亮灭。下面来看流程。

1、我们首先需要定义端口。

sbit key = P3^2;
#define PORT = P1;

 

2、为了使我们更好的观察到实验效果,我们需要设置一个延迟函数。

void delay (u16 num)
{
   u16 x,y;
   for(x = num; x>0; x--)
      for(y = 110; y>0; y--)
}

3、然后开始写我们的主函数,作用是对寄存器进行操作,进而控制单片机。

void main (void)
{
    IT0 = 1;   //按键开关为负边沿触发
    EA = 1;    //打开总中断
    EX0 = 1;   //打开中断允许寄存器
    while(1) //做一个等待
    {
          ;
    }
}

4、最后我们来编写中断服务函数。

void ext_int 0(void) interrupt 0
{
    u8 m;
    PORT = 0xff;  //关闭所有LED灯
    if(key == 0)
    {
       while(1)
       {
          PORT = 0xfe;  //使得最右面的LED先发光
          delay (500);  //延迟500ms,使得出现可观察到现象
          for(m = 7;m > 0;m--)
          {
              PORT <<= 1 | 0x01;
              delay(500);
          }

       }
  
    }
}

 

下面我们看这个任务的总程序。

#include<reg52.h>
typedef unsigned char u8 ;
typedef unsigned int u16 ;
sbit key = P3^2 ;
#define PORT P1 ;
void delay(u16 num)
{
    u16 x,y;
    for(x = num;x>0;x--)
       for(y = 110;y>0;y--);
}
void main (void)
{
    IT0 = 1;  //按键开关为负边沿触发
    EA = 1;   //打开总中断
    EX0 = 1;  //打开中断允许寄存器
    while(1)  //做一个等待
    {
       ;    
    }
}
void ext_int 0(void) interrupt 0
{
    u8 m;
    PORT = 0xff;  //关闭所有LED灯
    if(key == 0)
    {
       while(1)
       {
          PORT = 0xfe;  //使得最右面的LED先发光
          delay (500);  //延迟500ms,使得出现可观察到现象
          for(m = 7;m > 0;m--)
          {
              PORT <<= 1 | 0x01;
              delay(500);
          }

       }
  
    }
}

由于本人能力有限,文中可能会有多多少少的错误,请谅解并指出对应错误。

  • 5
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值