中断的介绍与实现

一、中断的介绍

51系列允许5个中断源:

外部中断源(2个):

INT0——由P3.2端口线引入,低电平下降沿引起。

INT1——由P3.3端口线引入,低电平下降沿引起。

这两个外部中断源标志和它们的触发方式控制位由特殊功能寄存器TCON的低4位控制。

内部中断源(3个):

T0——定时器/计数器0中断,由T0回零溢出引起。

T1——定时器/计数器1中断,由T1回零溢出引起。

TI/RI——串口I/O中断,串口端口完成一帧字符发送/接收后引起。

这3个内部中断源的控制位分别锁存在特殊功能寄存器TCON和SCON中。

二、外部中断

1、低电平触发

#include <reg51.h>

#define uchar unsigned char
#define uint unsigned int
uchar code seg[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
uchar i=0;
sbit P32=P3^2;
void init_int0()
{
	IT0=0;	//低电平触发,只要是低电平就可以触发中断
	EX0=1;
	EA=1;
}

void main()
{
	init_int0();
	while(1)
	{
		if(i>=10) i=0;
		P2=seg[i];
		
	}
}

void int0() interrupt 0 //0:INT0 1:T0 2:INT1 3:T1 4:RI/TI
{
	i++;
	while(P32==0);
}

外部中断低电平触发

2、下降沿触发

(1)多行注释的快捷键设置

这样选择要注释的内容,直接按ctrl+/,就可以多行注释了

(2)代码和仿真效果

#include <reg51.h>

#define uchar unsigned char
#define uint unsigned int
uchar code seg[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
uchar i=0;
sbit P32=P3^2;
void init_int0()
{
	//IT0=0;	//低电平触发,只要是低电平就可以触发中断
	IT0=1;    //下降沿触发    
	EX0=1;
	EA=1;
}

void main()
{
	init_int0();
	while(1)
	{
		if(i>=10) i=0;
		P2=seg[i];
		
	}
}

//void int0() interrupt 0 //0:INT0 1:T0 2:INT1 3:T1 4:RI/TI
//{
//	i++;
//	while(P32==0);
//}

void int0() interrupt 0 //0:INT0 1:T0 2:INT1 3:T1 4:RI/TI
{
	i++;
	
}

外部中断下降沿触发

3、两个外部中断

#include <reg51.h>

#define uchar unsigned char
#define uint unsigned int
uchar code seg[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
char i=0;
sbit P32=P3^2;
sbit P33=P3^3;

void init_int0()
{
	IT0=1;
	EX0=1;
	IT1=1;
	EX1=1;
	EA=1;
}

void main()
{
	init_int0();
	while(1)
	{
		if(i>=10) i=0;
		if(i<0) i=9;
		P2=seg[i];
		
	}
}

//void int0() interrupt 0 //0:INT0 1:T0 2:INT1 3:T1 4:RI/TI
//{
//	i++;
//	while(P32==0);
//}

void int0() interrupt 0 //0:INT0 1:T0 2:INT1 3:T1 4:RI/TI
{
	i++;
	
}

void int1() interrupt 2 //0:INT0 1:T0 2:INT1 3:T1 4:RI/TI
{
	i--;
	
}

两个外部中断实现数码管加减功能

三、定时器中断

1、定时器/计数器的介绍

8位分别为两组,高4位控制T1,第4位控制T0。

(1)GATE——门控位

        GATE=0时,仅由运行控制位TRX(X=0,1)=1来启动定时器/计数器运行。

        GATE=1时,由TRX(X=0,1)=1和外部中断引脚(INT0或INT1)上的高低电平共同来启动定时器/计数器运行。

(2)M1、M0——工作方式选择位

(3)C/T——计数器模式和定时器模式选择位

        C/T=0,为定时器模式。

        C/T=1,为计数器模式,计数器对外部输入引脚T0(P3.4脚)或T1(P3.5脚)的外部脉冲(负跳变)计数。

2、每500msLED闪烁一次

#include <reg51.h>
#define uchar unsigned char
#define uint unsigned int
	
uint time;
bit flag=0;
sbit P20=P2^0;

void init_timer0()
{
	TMOD=0x01;	//定时器0采用16位
	TH0=(65536-50000)/256;
	TL0=(65536-50000)%256;
	TR0=1;
	ET0=1;
	EA=1;
}

void main()
{
	init_timer0();
	while(1)
	{
		P20=flag;
	}
}

void timer1() interrupt 1
{
	TH0=(65536-50000)/256;
	TL0=(65536-50000)%256;
	time++;
	if(time>=10)
	{
		time=0;
		flag=!flag;
	}
}

定时器使LED闪烁

四、中断结合数码管显示及矩阵按键

 1、STC-ISP烧录软件

2、代码和仿真结果

#include <reg51.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
	
bit k_flag=0;
sbit P10=P1^0;
sbit P11=P1^1;
sbit P12=P1^2;
sbit P13=P1^3;
sbit P14=P1^4;
sbit P15=P1^5;
sbit P16=P1^6;
sbit P17=P1^7;
uchar key_num=0;
uchar code seg[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
uchar code place_code[8]={0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07};
uchar cache[8]={0,0,0,0,0,0,0,0};

void transfer(uchar a,b,c,d,e,f,g,h)
{
	cache[0]=a;
	cache[1]=b;
	cache[2]=c;
	cache[3]=d;
	cache[4]=e;
	cache[5]=f;
	cache[6]=g;
	cache[7]=h;
}

void Delay1us()		//@12.000MHz
{
	_nop_();
	_nop_();
	_nop_();
	_nop_();
}

void seg_show()
{
	char i;
	for(i=0;i<8;i++)
	{
		P0=place_code[i];
		P2=0xff;
		P2=seg[cache[i]];
		Delay1us();
	}
}

void key_scan()
{
	char kx=0,ky=0;
	if(k_flag==0)
	{
		P1=0x0f;
		if(P10==0||P11==0||P12==0||P13==0)
		{
			if(P10==0) kx=-1;
			if(P11==0) kx=3;
			if(P12==0) kx=7;
			if(P13==0) kx=11;
		}
		P1=0xf0;
		if(P14==0||P15==0||P16==0||P17==0)
		{
			if(P14==0) ky=4;
			if(P15==0) ky=3;
			if(P16==0) ky=2;
			if(P17==0) ky=1;
		}
		if(ky==0) k_flag=0;
		else
		{
			key_num=kx+ky;
			k_flag=1;
		}
	}
}

void init_timer0()
{
	TMOD=0x01;
	TH0=(65536-1000)/256;
	TL0=(65536-1000)%256;
	TR0=1;
	ET0=1;
	EA=1;
}

void main()
{
	init_timer0();
	while(1)
	{
		if(k_flag==1)
		{
			k_flag=0;
		}
		transfer(0,0,0,0,0,0,key_num/10,key_num%10);
	}
}

void timer0() interrupt 1 
{
	TH0=(65536-1000)/256;
	TL0=(65536-1000)%256;
	key_scan();
	seg_show();
}

中断结合数码管矩阵显示

五、数码管电子时钟

#include <reg51.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
	
bit k_flag=0;
uint time;
uchar hour,min,s;
bit flag=0;
sbit P10=P1^0;
sbit P11=P1^1;
sbit P12=P1^2;
sbit P13=P1^3;
sbit P14=P1^4;
sbit P15=P1^5;
sbit P16=P1^6;
sbit P17=P1^7;
uchar key_num=0;
uchar code seg[11]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xbf};
uchar code place_code[8]={0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07};
uchar cache[8]={0,0,0,0,0,0,0,0};

void transfer(uchar a,b,c,d,e,f,g,h)
{
	cache[0]=a;
	cache[1]=b;
	cache[2]=c;
	cache[3]=d;
	cache[4]=e;
	cache[5]=f;
	cache[6]=g;
	cache[7]=h;
}

void Delay1us()		//@12.000MHz
{
	_nop_();
	_nop_();
	_nop_();
	_nop_();
}

void seg_show()
{
	char i;
	for(i=0;i<8;i++)
	{
		P0=place_code[i];
		P2=0xff;
		P2=seg[cache[i]];
		Delay1us();
	}
}

void clock()
{
	s++;
	if(s>=60)
	{
		s=0;
		min++;
		if(min>=60)
		{
			min=0;
			hour++;
			if(hour>=24)
			{
				hour=0;
			}
		}
	}
	transfer(hour/10,hour%10,10,min/10,min%10,10,s/10,s%10);
}

void time_set(uchar a,b,c)
{
	hour=a;
	min=b;
	s=c;
}

void key_scan()
{
	char kx=0,ky=0;
	if(k_flag==0)
	{
		P1=0x0f;
		if(P10==0||P11==0||P12==0||P13==0)
		{
			if(P10==0) kx=-1;
			if(P11==0) kx=3;
			if(P12==0) kx=7;
			if(P13==0) kx=11;
		}
		P1=0xf0;
		if(P14==0||P15==0||P16==0||P17==0)
		{
			if(P14==0) ky=4;
			if(P15==0) ky=3;
			if(P16==0) ky=2;
			if(P17==0) ky=1;
		}
		if(ky==0) k_flag=0;
		else
		{
			key_num=kx+ky;
			k_flag=1;
		}
	}
}

void init_timer0()
{
	TMOD=0x01;
	TH0=(65536-1000)/256;
	TL0=(65536-1000)%256;
	TR0=1;
	ET0=1;
	EA=1;
}

void main()
{
	init_timer0();
	time_set(23,59,50);
	while(1)
	{
		if(k_flag==1)
		{
			k_flag=0;
		}
		if(flag==1)
		{
			clock();
			flag=0;
		}
	}
}

void timer0() interrupt 1 
{
	TH0=(65536-1000)/256;
	TL0=(65536-1000)%256;
	key_scan();
	seg_show();
	if(flag==0)
	{
		time++;
		if(time>=1000)
		{
			time=0;
			flag=1;
		}
	}
}

数码管电子时钟

五、计数器中断实现

#include <reg51.h>
#define uchar unsigned char
#define uint unsigned int
	
uint time;
bit flag=0,nflag=0;
sbit P20=P2^0;
sbit P21=P2^1;
void init_timer0()
{
	TMOD=0x61;	//定时器0 采用16位,计数器1 8位自动重装载入 0110 0001
	TH0=(65536-50000)/256;
	TL0=(65536-50000)%256;
	TR0=1;
	ET0=1;
	EA=1;
	TH1=256-3;	//装载初值
	TL1=256-3;	//装载计数的
	TR1=1;
	ET1=1;
}

void main()
{
	init_timer0();
	while(1)
	{
		P20=flag;
		P21=nflag;
	}
}

void timer0() interrupt 1
{
	TH0=(65536-50000)/256;
	TL0=(65536-50000)%256;
	time++;
	if(time>=10)
	{
		time=0;
		flag=!flag;
	}
}

void counter1() interrupt 3
{
	nflag=!nflag;
}

计数器

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值