[51单片机]中断原理与定时器的工作原理

目录

中断系统的原理

1.51单片机中断原理

2.中断响应原理

3.中断优先级原理

4.中断标志位复位原理

中断系统的具体应用

1.一级中断的具体应用编程

2.二级中断具体应用编程

3.中断嵌套的具体应用编程

定时器/计数器的工作原理

定时器/计数器的具体应用

1.定时计数器控制LED灯

A.应用实例

 B.Keil仿真中的虚拟逻辑仪对LED管脚进行波形观察

2.计数器中断实例

中断程序优化方案

总结


中断系统的原理

1.51单片机中断原理

中断系统结构见下图。中断系统有5个中断请求源(简称中断源),2个中断优先级,可实现2级中断服务程序嵌套。每一中断源可用软件独立控制为允许中断或关闭中断状态;每一个中断源的优先级均可用软件设置。

由上图,中断系统共有5个中断请求源,它们是:

(1)INT0*—外部中断请求0,外部中断请求信号(低电平或负跳变有效)由INT0*引脚输入,中断请求标志为IE0。

(2)INT1*—外部中断请求1,外部中断请求信号(低电平或负跳变有效)由INT1*引脚输入,中断请求标志为IE1。

(3)定时器/计数器T0计数溢出的中断请求,标志为TF0。

(4)定时器/计数器T1计数溢出的中断请求,标志为TF1。

(5)串行口中断请求,标志为发送中断TI或接收中断RI。 

2.中断响应原理

一个中断源中断请求被响应,须满足以下必要条件:

(1)总中断允许开关接通,即IE寄存器中的中断总允许位EA=1。

(2)该中断源发出中断请求,即该中断源对应的中断请求标志为“1”。

(3)该中断源的中断允许位=1,即该中断被允许。

(4)无同级或更高级中断正在被服务。   中断响应就是CPU对中断源提出的中断请求的接受,当查询到有效的中断请求时,满足上述条件时,紧接着就进行中断响应。

中断响应过程:    首先由硬件自动生成一条长调用指令“LCALL addr16”。即程序存储区中相应的中断入口地址。例如,对于外部中断1的响应,硬件自动生成的长调用指令为:  

  LCALL 0013H  

生成LCALL指令后,紧接着就由CPU执行该指令。首先将程序计数器PC内容压入堆栈以保护断点,再将中断入口地址装入PC,使程序转向响应中断请求的中断入口地址。各中断源服务程序入口地址是固定的,见表6-2。

 其中两个中断入口间只相隔8字节,一般情况下难以安放一个完整的中断服务程序。 

3.中断优先级原理

中断请求源有两个中断优先级,每一个中断请求源可由软件设置为高优先级中断或低优先级中断,也可实现两级中断嵌套。  

   所谓两级中断嵌套,就是AT89S51正在执行低优先级中断的服务程序时,可被高优先级中断请求所中断,待高优先级中断处理完毕后,再返回低优先级中断服务程序。  

 两级中断嵌套见下图。

 各中断源的中断优先级关系,可归纳为下面两条基本规则:

(1)低优先级可被高优先级中断,高优先级不能被低优先级中断。

(2)任何一种中断(不管是高级还是低级)一旦得到响应,不会再被它的同级中断源所中断。如果某一中断源被设置为高优先级中断,在执行该中断源的中断服务程序时,则不能被任何其他的中断源的中断请求所中断。

4.中断标志位复位原理

在微控制器系统中,中断标志位是用来指示特定类型的中断事件是否发生。

当中断源(如外部中断、定时器溢出、接收完成等)触发时,相应的中断标志位会被设置。

中断处理程序(Interrupt Service Routine, ISR)需要检查这些标志位以确定中断的来源,并执行相应的处理逻辑。处理完成后,很关键的一步是复位(清除)这些中断标志位,以便系统可以响应后续的同类型中断。这里的复位原理涉及几个方面:

自动复位:某些微控制器的中断标志位在中断响应后会自动被硬件清零。这意味着,当中断被CPU识别并开始执行对应的ISR时,中断标志位自动清除,无需手动编程清除。 

手动复位:大多数情况下,中断标志位需要在ISR中手动清除。这通常通过写特定的值到相关的寄存器来实现。复位中断标志位的方法依赖于具体的微控制器及其寄存器结构。例如,对于许多微控制器来说,可能需要向中断标志位寄存器写入`1`来清除中断标志位(写`1`清零)。

为什么需要复位中断标志位? 

如果不清除中断标志位,中断服务程序完成后,中断控制逻辑可能会再次判断中断仍然有效,并再次进入相同的中断处理程序,从而形成循环,不再返回到主程序执行,导致程序卡在中断处理中。因此,正确管理中断标志位是中断编程中非常关键的一部分。

中断系统的具体应用

1.一级中断的具体应用编程

在单片机P1口上接有8只LED。在外部中断0输入引脚(P3.2)接一只按钮开关K1。要求将外部中断0设置为电平触发。程序启动时,P1口上的8只LED全亮。每按一次按钮开关K1,使引脚接地,产生一个低电平触发的外中断请求,在中断服务程序中,让低4位的LED与高4位的LED交替闪烁5次。然后从中断返回,控制8只LED再次全亮。

c语言代码

#include <reg51.h>
#define uchar unsigned char
	void Delay(unsigned int i)
	{
	unsigned int j;
		for(;i>0;i--)
		{
		for(j=0;j<333;j++)
			{;}
		}
	}
	void main()
	{
	EA=1;
		EX0=1;
		IT0=1;
		while(1)
		{
		P2=0;
		}
	}

	void int0() interrupt 0 using 0
	{
	uchar m;
		EX0=0;
		for(m=0;m<5;m++)
		{
		P2=0x0f;
			Delay(400);
			P2=0xf0;
			Delay(400);
			EX0=1;
		}
	}

Proteus上完成的实验

普中单片机板上完成的实验

2.二级中断具体应用编程

在单片机P1口上接有8只LED。在外部中断0输入引脚(P3.2)接有一只按钮开关K1。在外部中断1输入引脚(P3.3)接有一只按钮开关K2。要求K1和K2都未按下时,P1口的8只LED呈流水灯显示,仅K1(P3.2)按下再松开时,上下各4只LED交替闪烁10次,然后再回到流水灯显示。如果按下再松开K2(P3.3)时,P1口的8只LED全部闪烁10次,然后再回到流水灯显示。设置两个外中断的优先级相同。

c语言代码

#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);
			P2=display[a];
		}
	}
	}
	void int0_isr(void) interrupt 0 using 1
	{
	uchar n;
		for(n=0;n<10;n++)
		{
		P2=0x0f;
			Delay(500);
			P2=0xf0;
			Delay(500);
		}
	}
	void int1_isr(void) interrupt 2 using 2
	{
	uchar m;
		for(m=0;m<10;m++)
		{
		P2=0xff;
			Delay(500);
			P2=0;
			Delay(500);
		}
	}

Proteus上完成的实验

K1和K2都未按下时

仅K1(P3.2)按下再松开时

按下再松开K2(P3.3)时 

普中单片机板上完成的实验

K1和K2都未按下时

仅K1(P3.2)按下再松开时

按下再松开K2(P3.3)时 

3.中断嵌套的具体应用编程

设计一中断嵌套程序:要求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为高优先级。

c语言代码

#include <reg51.h>
#define uchar unsigned char
	void  Delay(unsigned int i)
	{
	unsigned int 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};
	uchar a;
	for(;;)
	{
	EA=1;
		EX0=1;
		EX1=1;
		IT0=1;
		IT1=1;
		PX0=0;
		PX1=1;
   for(a=0;a<9;a++)
		{
		Delay(500);
			P2=display[a];
		}
	}
	}
	void int0_isr(void) interrupt 0 using 0
	{
	for(;;)
		{
		P2=0x0f;
			Delay(500);
			P2=0xf0;
			Delay(500);
		}
	}
	void int1_isr(void) interrupt 2 using 1
	{
	uchar m;
		for(m=0;m<5;m++)
		{
		P2=0;
			Delay(500);
			P2=0xff;
			Delay(500);
		}
	}

Proteus上完成的实验

要求K1和K2都未按下时

当按一下K1时

当按一下K1时,产生一个低优先级外中断0请求(跳沿触发),进入外中断0中断服务程序,上下4只LED交替闪烁。此时按一下K2时:

普中单片机板上完成的实验

要求K1和K2都未按下时

当按一下K1时

当按一下K1时,产生一个低优先级外中断0请求(跳沿触发),进入外中断0中断服务程序,上下4只LED交替闪烁。此时按一下K2时:

定时器/计数器的工作原理

定时器/计数器是微控制器中非常重要的组件,广泛用于时间管理、事件计数、协议通信、PWM产生等。它们的工作原理可以根据其功能分为两大类:定时器模式和计数器模式。 

定时器模式

在定时器模式下,定时器/计数器根据内部或外部时钟源(通常是微控制器的系统时钟)递增其计数值。当计数值达到预设值时,可以触发中断或其他事件,如改变输出引脚状态。

1. 初始化:首先设定定时器的基本参数,包括预分频值(决定计数速度)和初始计数值。

2. 启动:启动定时器,使其开始根据时钟源递增计数值。

3. 计数到达预设值:当计数值达到预设值时,根据配置,定时器可能会发生以下几种情况之一: - 产生中断,由CPU处理。 - 自动重装初值并继续计数,用于周期性任务。 - 改变某个输出引脚的电平状态,用于生成波形等。

4. 中断处理:如果定时器触发了中断,CPU会暂停当前任务,执行中断服务程序(ISR)。在ISR中,通常会清除定时器的中断标志位,以便定时器可以继续工作。

计数器模式

在计数器模式下,定时器/计数器不再依赖内部时钟源,而是通过外部事件(如外部引脚的电平变化)来递增计数值。这使得计数器可以用于计数外部事件的发生次数。

1. 初始化:设置计数器的工作模式和初始计数值。

2. 启动:启动计数器。

3. 外部事件计数:每当检测到预定义的外部事件(例如外部引脚上的上升沿或下降沿),计数器的计数值就会递增。

4. 计数到达预设值:与定时器模式相同,当计数值达到预设值时,可以配置计数器产生中断、重置计数值或进行其他操作。 

共同特点 :

1.预分频:定时器/计数器通常具有预分频功能,允许调整计数速度,以适应不同的应用需求。

2.中断功能:定时器/计数器达到预设值时,常常可以配置为触发中断,允许CPU进行相应处理。

3.自动重载:许多定时器/计数器支持自动重载功能,当计数值达到预设值后,自动重置为初始值,从而实现周期性任务。

定时器/计数器是微控制器中功能强大且多用途的组件,通过精巧的配置和编程,可以实现各种复杂的功能。

定时器/计数器的具体应用

1.定时计数器控制LED灯

A.应用实例

在AT89S51的P1口上接有8只LED,原理电路如下。采用T0方式1的定时中断方式,使P1口外接的8只LED每1s闪亮一次。

(1)设置TMOD寄存器      

T0工作在方式1,应使TMOD寄存器的M1、M0=01;应设置C/T*=0,为定时器模式;对T0的运行控制仅由TR0来控制,应使相应的GATE位为0。定时器T1不使用,各相关位均设为0。所以,TMOD寄存器应初始化为0x01。

(2)计算定时器T0的计数初值      

设定时时间10ms(即10 000µs),设T0计数初值为X,假设晶振的频率为11.059 2MHz,则定时时间为: 

定时时间=(216−X)×12/晶振频率     则  10 000=(65536 −X) ×12/11.059 2     得  X = 56320, 转换成十六进制:0xdc00,其中0xdc装入TH0,0x00装入TL0。

(3)设置IE寄存器        

本例由于采用定时器T0中断,因此需将IE寄存器中的EA、ET0位置1。

(4)启动和停止定时器T0    

将定时器控制寄存器TCON中的TR0=1,则启动定时器T0;TR0=0,则停止定时器T0定时。

c语言代码

#include <reg51.h>
char i=100;
void main()
{
TMOD=0x01;
	TH0=0xdc;
	TL0=0x00;
	P2=0x00;
	EA=1;
	ET0=1;
	TR0=1;
	while(1);
	{;}
}
void timer0() interrupt 1
{
TH0=0xdc;
	TL0=0x00;
	i--;
	if(i<=0)
	{
	P2=~P2;
		i=100;
	}
}

在Proteus上 

在普中单片机板上

 B.Keil仿真中的虚拟逻辑仪对LED管脚进行波形观察

Keil仿真中的虚拟逻辑仪对LED管脚进行波形观察,测量真实的周期数,并与采用软件循环进行周期定时的精度进行对比,看哪一种方式更加精准。

定时器循环

软件循环

如图软件定时一个周期内约为0.924755秒,而采用定时器定时一周期内约为0.93338秒。

​ 因此定时器定时较软件定时更为精确。

2.计数器中断实例

T1采用计数模式,方式1中断,计数输入引脚T1(P3.5)上外接按钮开关,作为计数信号输入。按4次按钮开关后,P1口的8只LED闪烁不停。如图:

(1)设置TMOD寄存器

T1工作在方式1,应使TMOD的M1、M0=01;设置C/T*=1,为计数器模式;对T0运行控制仅由TR0来控制,应使GATE0=0。定时器T0不使用,各相关位均设为0。所以,TMOD寄存器应初始化为0x50。

(2)计算定时器T1的计数初值 由于每按1次按钮开关,计数1次,按4次后,P1口的8只LED闪烁不停。因此计数器初值为65 536−4=65 532,将其转换成十六进制后为0xfffc,所以,TH0=0xff,TL0=0xfc。 

(3)设置IE寄存器     本例由于采用T1中断,因此需将IE寄存器的EA、ET1位置1。

(4)启动和停止定时器T1将寄存器TCON中TR1=1,则启动T1计数;TR1=0,则停止T1计数。 

c程序 

#include <reg51.h>
void Delay(unsigned int i)
{
unsigned int j;
	for(;i>0;i--)
	for(j=0;j<125;j++)
	{;}
}
void main()
{
TMOD=0x50;
	TH1=0xff;
	TL1=0xfc;
	EA=1;
	ET1=1;
	TR1=1;
	while(1);
}
void T1_int(void) interrupt 3
{
for(;;)
	{
	P2=0xff;
		Delay(500);
		P2=0;
		Delay(500);
	}
}

 在Proteus上

 在普中单片机板上

中断程序优化方案

为了实现按4次按钮后使P1口的8只LED不停闪烁,可以采用计数器中断结合按键检测的方法。下面是一个简化的示例代码,展示了如何在C语言中实现这个功能。

#include <reg51.h> // 适用于8051,根据实际微控制器调整

volatile unsigned int buttonPressCount = 0; // 按钮按下计数器,用volatile修饰,因为它会在中断服务例程中被修改

// 假设使用外部中断0来检测按键按下
void ExternalInterrupt0_ISR(void) interrupt 0 {
    buttonPressCount++; // 按键按下计数
    if(buttonPressCount >= 4) {
        // 达到4次按键后的处理逻辑
        // 这里仅改变状态或设置标志位,具体闪烁逻辑在main函数中实现
    }
}

void main() {
    IE = 0x81; // 开启外部中断0和全局中断
    IT0 = 1; // 设置为边缘触发模式

    while(1) {
        if(buttonPressCount >= 4) {
            P1 = ~P1; // 切换P1口状态,实现LED闪烁
            // 延时函数,根据需要调整延时时长来控制闪烁速度
            // 注意,实际使用中应避免使用过长的延时,或者改用计时器中断实现非阻塞延时
        }
    }
}

重要注意事项 

  • 中断向量号和寄存器:上述代码示例采用了8051系列微控制器的外部中断0(interrupt 0)和相关寄存器(如IEIT0)作为示例。具体的中断向量号、寄存器和设置方法取决于你使用的具体微控制器型号,因此在实际应用中需要参考相应的微控制器手册。

  • 去抖动:实际应用中,按键输入需要去抖动处理以避免误操作。去抖动通常通过软件实现,即在检测到按键动作后,延时一小段时间再确认按键状态。

  • 延时处理:示例中的延时处理非常简化。在实际应用中,考虑使用计时器中断而非阻塞式延时来实现LED的闪烁,这样可以避免阻塞程序其他部分的执行。

这个示例提供了一种实现思路。具体实现细节,如IO口的配置、中断优先级的设置等,需要根据实际使用的微控制器和开发环境进行调整。

总结

通过此次学习51单片机中断系统和定时/计数器的相关内容,掌握了中断系统的原理和使用方法,了解了如何利用中断来实现对外部事件的实时响应,还学习了定时/计数器的工作原理和编程方法,掌握了如何利用定时器来实现时间精确控制,提高了系统的时间管理能力。

了解了中断和定时/计数器的工作机制,学会了合理设置中断优先级和定时器的工作参数,从而能够有效地节省系统资源,提高系统的性能和效率。

通过实际的应用案例,如按键中断、定时器控制LED闪烁等,将理论知识与实际操作相结合,加深了对中断系统和定时/计数器的理解和掌握。

  • 24
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值