51单片机中断与定时计数

一。51单片机的中断

在51单片机中,中断是指当发生某些特定事件时,会打断当前程序的执行,转而执行预先定义好的中断服务程序。这样可以实现及时响应外部事件或处理紧急任务的功能。中断可以分为外部中断和定时器中断两种类型。

外部中断是由外部信号触发的中断,比如按键触发的中断。定时器中断是由定时器产生的中断,用于定时执行某些操作。

通过使用中断,可以提高系统的响应速度和效率,使单片机能够同时处理多个任务,提高系统的可靠性。

2.单一中断

在51单片机中,单一中断通常指只有一个中断源,即只有一个中断服务程序。当这个中断源触发时,会打断当前程序的执行,转而执行该中断服务程序。这种情况下,单片机只需要管理一个中断服务程序,可以简化系统设计和编程。

单一中断通常用于处理特定的事件或任务,比如处理外部按键的中断、处理定时器的中断等。通过单一中断,可以实现对特定事件的及时响应和处理,提高系统的可靠性和实时性。
代码如下

#include <reg51.h>
#define uchar  unsigned char
void Delay(unsigned int i)	
{	
  unsigned int j;
  for(;i > 0;i--)		
  for(j=0;j<444;j++)//晶振为12MHz,j和i越大延时越久
  {;}               //空操作,用来达到延时效果
}
 
void  main( )		
{	
  EA=1;			//总中断允许
  EX0=1;			//允许外部中断0中断
  IT0=1;			//选择外部中断0为跳沿触发方式
  while(1)		//循环		
    { P1=0;}		// P1口的8只LED全亮
}
 
void int0( )  interrupt 0  using 0  	//外中断0的中断函数
{	
  uchar  m;
  EX0=0;			//禁止外部中断0中断
  for(m=0;m<5;m++)//交替闪烁5次
  {
  P1=0x0f;		//低4位LED灭,高4位LED亮
 	Delay(500);		//延时
  P1=0xf0;		//高4位LED灭,低4位LED亮
  Delay(500); 	//延时
  }
    EX0=1;			//中断返回前,打开外部中断0中断
}

 Proteus仿真:

在51单片机普中开发板

三.51单片机双中断 

51单片机双中断指的是在51单片机中同时存在两个中断源,即可以同时处理两个不同的中断事件。这样可以在同一时间处理两个不同优先级的中断请求,提高系统的响应能力和灵活性。
代码如下

#include <reg51.h>
#define uchar unsigned char
void Delay(unsigned int i)						 	
{	
  uchar j;
  for(;i>0;i--)		
  for(j=0;j<125;j++)		
  {;}				
}
void  main( )					
{ 
uchar display[9]={0xff,0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf, 0x7f}; 		
unsigned int a;
for(;;)
{
 EA=1;			 	
 EX0=1;			 	
 EX1=1;	
 IT0=1;      	          	
 IT1=1;			 	
 IP=0;			 
 for(a=0;a<9;a++)
  {
  	Delay(500);			
  	P1=display[a];	
  }
}
void int0_isr(void)  interrupt 0  using 1//中断0的中断函数
{	
  uchar  n;
  for(n=0;n<10;n++)		
  {
  	 P1=0x0f; 		
  	 Delay(500);		
  	 P1=0xf0;		
  	 Delay(500);		
  } 
}
void int1_isr (void)  interrupt 2  using 2//中断1的中断函数
{	
  uchar  m;
  for(m=0;m<10;m++)				
   {
  	P1=0xff;				
   	Delay(500);				
   	P1=0;					
   	Delay(500); 				
  }
}

 Proteus仿真:

在51单片机普中开发板

 

中断嵌套

   题目:设计一中断嵌套程序:要求K1和K2都未按下时,P1口8只LED呈流水灯显示,当按一下K1时,产生一个低优先级外中断0请求(跳沿触发),进入外中断0中断服务程序,上下4只LED交替闪烁。此时按一下K2时,产生一个高优先级的外中断1请求(跳沿触发),进入外中断1中断服务程序,使8只LED全部闪烁。当显示5次后,再从外中断1返回继续执行外中断0中断服务程序,即P1口控制8只LED,上、下4只LED交替闪烁。设置外中断0为低优先级,外中断1为高优先级

#include <reg51.h>

sbit K1 = P3^2;  // K1按键引脚
sbit K2 = P3^3;  // K2按键引脚

sbit LED = P1^0;  // LED引脚

bit flag = 0;  // 中断嵌套标志
bit flag1 = 0;  // 外中断1计数标志
int count = 0;  // 外中断1计数器

void ExternalInterrupt0() interrupt 0 {
    if (!K1) {
        flag = 1;  // 设置中断嵌套标志
        IE0 = 0;  // 禁止外部中断0
    }
}

void ExternalInterrupt1() interrupt 2 {
    if (!K2) {
        flag1 = 1;  // 设置外中断1计数标志
        IE1 = 0;  // 禁止外部中断1
    }
}

void delay() {
    int i, j;
    for (i = 0; i < 500; i++)
        for (j = 0; j < 500; j++);
}

void main() {
    EA = 1;  // 允许中断
    EX0 = 1;  // 允许外部中断0
    EX1 = 1;  // 允许外部中断1
    
    while(1) {
        if (!K1 && !K2) {
            // 流水灯显示
            int i;
            for (i = 0; i < 8; i++) {
                P1 = ~(1 << i);
                delay();
            }
        }
        
        if (flag) {
            // 外中断0服务程序
            int i;
            for (i = 0; i < 5; i++) {
                P1 = 0x0F;
                delay();
                P1 = 0xF0;
                delay();
            }
            
            flag = 0;  // 清除中断嵌套标志
            IE0 = 1;  // 允许外部中断0
        }
        
        if (flag1) {
            // 外中断1服务程序
            count++;
            P1 = 0xFF;
            delay();
            P1 = 0x00;
            delay();
            
            if (count == 5) {
                flag1 = 0;  // 清除外中断1计数标志
                count = 0;  // 重置计数器
                IE1 = 1;  // 允许外部中断1
            }
        }
    }
}

Keil软件中采用虚拟逻辑仪测试周期准确性

 

100次中断时间间隔差不多在0.5s左右,因此定时器定时较软件定时更为精确。

计数器中断控制LED

在51单片机中,可以通过设置定时器中断来控制LED的闪烁频率。以下是一个简单的示例代码:

假设LED连接在P1口的某一引脚上,使用定时器0来控制中断:

#include <reg52.h>

sbit LED = P1^0; // 假设LED连接在P1.0口

void timer0_init()
{
    TMOD = 0x01; // 设置定时器0为工作方式1
    TH0 = 0xFC; // 定时器初值,通过修改TH0和TL0可以设置定时时间
    TL0 = 0x18;
    ET0 = 1; // 允许定时器0中断
    EA = 1; // 允许总中断
    TR0 = 1; // 启动定时器0
}

void timer0_isr() interrupt 1
{
    LED = ~LED; // 每次定时器中断时LED状态取反
}

void main()
{
    timer0_init();

    while(1)
    {
        // 主循环中可以进行其他操作
    }
}
总结
通过学习51单片机中断系统和定时/计数器的相关内容,我掌握了中断系统的原理和使用方法,了解了如何利用中断来实现对外部事件的实时响应,提高了系统的灵活性和可靠性。同时,我学习了定时/计数器的工作原理和编程方法,掌握了如何利用定时器来实现时间精确控制,提高了系统的时间管理能力。了解了中断和定时/计数器的工作机制,学会了合理设置中断优先级和定时器的工作参数,从而能够有效地节省系统资源,提高系统的性能和效率。通过实际的应用案例,如按键中断、定时器控制LED闪烁等,将理论知识与实际操作相结合,加深了对中断系统和定时/计数器的理解和掌握。
 
  • 11
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值