STC15外部中断

STC15W104支持的中断,不明白外部中断是什么意思,外部中断有什么很重要的作用吗

一,中断请求源

外部中断的触发方式

主要是检测电平的上升沿和下降沿来触发中断。

外部中断0:支持上升沿和下降沿两种触发方式

外部中断2,3,4:只支持下降沿触发

检测中断是否发生通过检测中断标志位,是 否允许中断发生设置中断控制

二,中断相关寄存器

寄存器配置

//中断特殊功能寄存器
sfr IE          =   0xA8;   //0000,0000 中断控制寄存器
sbit EA         =   IE^7;
sbit ELVD       =   IE^6;
sbit EADC       =   IE^5;
sbit ES         =   IE^4;
sbit ET1        =   IE^3;
sbit EX1        =   IE^2;
sbit ET0        =   IE^1;
sbit EX0        =   IE^0;
sfr IP          =   0xB8;   //0000,0000 中断优先级寄存器
sbit PPCA       =   IP^7;
sbit PLVD       =   IP^6;
sbit PADC       =   IP^5;
sbit PS         =   IP^4;
sbit PT1        =   IP^3;
sbit PX1        =   IP^2;
sbit PT0        =   IP^1;
sbit PX0        =   IP^0;
sfr IE2         =   0xAF;   //0000,0000 中断控制寄存器2
sfr IP2         =   0xB5;   //xxxx,xx00 中断优先级寄存器2
sfr INT_CLKO    =   0x8F;   //0000,0000 外部中断与时钟输出控制寄存器

中断允许寄存器 IE IE2 INT_CLKO

开启中断第一步找到中断源对应的控制位并开启

第二步开启中断总控制位 EA=1;

中断优先控制寄存器IP IP2

传统8051单片机 所有中断源可以申请:高优先级和低优先级 可以实现两级中断嵌套

任何一种中断不会被他同级的中断所中断

测试代码




#include "STC15WXX.H"


sbit LED1 = P3^1;
sbit LED2 = P3^0;




void Delay500ms()		//@11.0592MHz
{
	unsigned char i, j, k;

//	_nop_();
//	_nop_();
	i = 22;
	j = 3;
	k = 227;
	do
	{
		do
		{
			while (--k);
		} while (--j);
	} while (--i);
}


//-----------------------------------------------
//中断服务程序     关门动作
void exint2() interrupt 10          //INT2中断入口
{
    LED1 = 1;
	Delay500ms();
	Delay500ms();
	Delay500ms();
	
} 


中断服务程序      开门关门,两个中断同时触发
//void exint3() interrupt 11          //INT3中断入口
//{
//    LED1 = 0;
//	LED2 = 1;
//    
  INT_CLKO &= 0xDF;               //若需要手动清除中断标志,可先关闭中断,此时系统会自动清除内部的中断标志
  INT_CLKO |= 0x20;               //然后再开中断即可
//}




void main()
{
    P0M0 = 0x00;
    P0M1 = 0x00;
    P1M0 = 0x00;
    P1M1 = 0x00;
    P2M0 = 0x00;
    P2M1 = 0x00;
    P3M0 = 0x00;
    P3M1 = 0x00;
    P4M0 = 0x00;
    P4M1 = 0x00;
    P5M0 = 0x00;
    P5M1 = 0x00;
    P6M0 = 0x00;
    P6M1 = 0x00;
    P7M0 = 0x00;
    P7M1 = 0x00;
	
	LED1 = 0;

    INT_CLKO |= 0x10;               //(EX2 = 1)使能INT2中断
    EA = 1;

    while (1)
	{
		LED1 = 0;
	
	}
		
}

额,采雷区了,不能在中断函数使用延时函数,这个需要优化,可是原因是什么

而且我已经猜到肯定使用定时器代替,但是这两者的区别是什么

在delay的这段时间,CPU处于死等的状态,这会导致中断处理的整体时间拉长,若还有其他低优先级的中断,会延误其他中断的处理,导致反应不够灵敏。但是使用定时器就不一样,在定时器计数的这段时间里,不会影响CPU去执行其他的事情,然后根据优先级去处理不同的中断。

优化方案一定时器





#include "STC15WXX.H"


sbit LED1 = P3^1;
sbit LED2 = P3^0;







//-----------------------------------------------
//中断服务程序     关门动作
void exint2() interrupt 10          //INT2中断入口
{
    LED1 = 1;
	//100ms后关闭LED1,额最大计数单位就是ms,
	TH0 = 0x4C;
	TL0 = 0x00;
	TR0 = 1;                        //定时器0开始计时
    ET0 = 1;                        //使能定时器0中断
	
	
	
} 

/* Timer0 interrupt routine */
void tm0_isr() interrupt 1
{
	LED1 = 0; 
}



void main()
{
    P0M0 = 0x00;
    P0M1 = 0x00;
    P1M0 = 0x00;
    P1M1 = 0x00;
    P2M0 = 0x00;
    P2M1 = 0x00;
    P3M0 = 0x00;
    P3M1 = 0x00;
    P4M0 = 0x00;
    P4M1 = 0x00;
    P5M0 = 0x00;
    P5M1 = 0x00;
    P6M0 = 0x00;
    P6M1 = 0x00;
    P7M0 = 0x00;
    P7M1 = 0x00;
	
	LED1 = 0;

    INT_CLKO |= 0x10;               //(EX2 = 1)使能INT2中断
    EA = 1;
	
	AUXR &= 0x7f;                   //定时器0为12T模式
	TMOD = 0x00;                    //设置定时器为模式0(16位自动重装载)

	
	

    while (1);
		
}

优化方案二标志位

我倒是有个问题,为什么低功耗的产品的I/O状态需要中断来检测,如果使用中断检测的话,我倒是能理解使用两个I/O口





#include "STC15WXX.H"


sbit LED1 = P3^1;
sbit LED2 = P3^0;
sbit Door_GUAN = P3^4;
sbit Door_KAI = P3^5;


unsigned int door_flag; //1=开门 1亮   2=关门  2亮  0=无变化


void Delay1ms()		//@11.0592MHz
{
	unsigned char i, j;

	i = 11;
	j = 190;
	do
	{
		while (--j);
	} while (--i);
}


//-----------------------------------------------
//中断服务程序     关门动作
void exint2() interrupt 10          //INT2中断入口
{
  	door_flag = 2;
	
} 

//中断服务程序
void exint3() interrupt 11          //INT3中断入口
{
	door_flag = 1;

}




void main()
{
    P0M0 = 0x00;
    P0M1 = 0x00;
    P1M0 = 0x00;
    P1M1 = 0x00;
    P2M0 = 0x00;
    P2M1 = 0x00;
    P3M0 = 0x00;
    P3M1 = 0x00;
    P4M0 = 0x00;
    P4M1 = 0x00;
    P5M0 = 0x00;
    P5M1 = 0x00;
    P6M0 = 0x00;
    P6M1 = 0x00;
    P7M0 = 0x00;
    P7M1 = 0x00;
	
	LED1 = 0;
	door_flag=0;

    INT_CLKO |= 0x10;               //(EX2 = 1)使能INT2中断
	INT_CLKO |= 0x20;
	
    EA = 1;
	


	
	

    while (1)
	{
		if(door_flag == 1)   //door_flag=1时,说明已经检测到下降沿的低电平端,接下来就是消抖  
		{
			door_flag = 0;
			Delay1ms();
			if( Door_GUAN == 0)
			{
				LED1 = 1;
				LED2 = 0;
			}
			
			
		}
		else if( door_flag == 2)
		{
			door_flag = 0;
			Delay1ms();
			if( Door_KAI  == 0)
			{
				LED1 = 0;
				LED2 = 1;
			}
			
		}
		
		
	}
	
		
}

三,电池低压检测电路

分析完电路后,为什么通过外部检测电路来检测I/O口的变化,而不是直接读取I/O口,由原理图可知由外部中断INT1检测

检测代码

经检测电池电压6v左右才算低压,既然给予这个临界线,表示变量还有一个的状过渡状态

高电平:严格意义上是 VCC (2.2V以上)

低电平: 严格意义上是 GND (0.8V以下)




#include "STC15WXX.H"


sbit LED1 = P3^1;
unsigned int vlot_low;  // 0 表示电池未低压  2表示低压  1表示检测低压的状态  
//未低压I/O端口为高电平,低压为低电平




void Delay1ms()		//@11.0592MHz
{
	unsigned char i, j;

	i = 11;
	j = 190;
	do
	{
		while (--j);
	} while (--i);
}



void Delay500ms()		//@11.0592MHz
{
	unsigned char i, j, k;

	i = 22;
	j = 3;
	k = 227;
	do
	{
		do
		{
			while (--k);
		} while (--j);
	} while (--i);
}



//-----------------------------------------
//中断服务程序
void exint1() interrupt 2       //INT1中断入口
{
	
	vlot_low = 1;
}

//-----------------------------------------------

void main()
{
    P0M0 = 0x00;
    P0M1 = 0x00;
    P1M0 = 0x00;
    P1M1 = 0x00;
    P2M0 = 0x00;
    P2M1 = 0x00;
    P3M0 = 0x00;
    P3M1 = 0x00;
    P4M0 = 0x00;
    P4M1 = 0x00;
    P5M0 = 0x00;
    P5M1 = 0x00;
    P6M0 = 0x00;
    P6M1 = 0x00;
    P7M0 = 0x00;
    P7M1 = 0x00;


    IT1 = 1;                    //设置INT1的中断类型 (1:仅下降沿 0:上升沿和下降沿)
    EX1 = 1;                    //使能INT1中断
    EA = 1;

    while (1)
	{
		if(vlot_low == 1)
		{
			Delay1ms();
			if(P33 == 0)
			{
				vlot_low = 2;
			}
		}
		if(vlot_low == 2)
		{
			LED1 = 1;
			Delay500ms();
			LED1 = 0;
			Delay500ms();
			
		}
	}
}

那么这样的话,为什么不直接读取I/O口的状态

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值