目录
(3)TCON: 定时器/计数器中断控制寄存器 (可位寻址)
一、原理部分
1、什么是中断
中断指处理机处理程序运行中出现的紧急事件的整个过程.程序运行过程中,系统外部、系统内部或者现行程序本身若出现紧急事件,处理机立即中止现行程序的运行,自动转入相应的处理程序(中断服务程序),待处理完后,再返回原来的程序运行,这整个过程称为程序中断。
举个例子,你正在家看电影(主程序),突然电话响了,叫你去拿外卖(中断请求),你暂停电影(现场保护),出去拿(中断响应),拿完回来继续看电影(现场回复)。
2、中断服务函数
内核响应中断后执行的相应处理函数
3、中断向量
中断服务程序的入口地址,每个中断源对应一个固定的入口地址,当内核响应中断请求时,就会暂停当前程序执行,然后跳转到该入口地址执行代码。
4、蓝桥杯单片机的中断资源
这块芯片有如下中断源,常用的是外部中断、定时器中断以及串口中断
这节主要说说外部中断,定时器中断以及串口中断等放在定时器,串口篇章叙述。
5、配置中断
在配置之前,我们需要先了解一下与中断相关的寄存器:
(1)IE:中断允许寄存器
EA: CPU的总中断允许控制位,EA=1,CPU开放中断,EA=0,CPU屏蔽所有的中断申请。EA的作用是使中断允许形成两级控制。即各中断源首先受EA控制:其次还受各中断源自己的中断允许控制位控制。
ELVD: 低压检测中断允许位。ELVD=1,允许低压检测中断;ELVD=0,禁止低压检测中断EADC: A/D转换中断允许位。EADC=1,允许A/D转换中断,EADC=0,禁止A/D转换中断。ES: 串行口1中断允许位。ES=1,允许串行口1中断;ES=0,禁止串行口1中断。
ET1: 定时/计数器T1的溢出中断允许位。ET1=1,允许T1中断,ET1=0,禁止T1中断。
EX1: 外部中断1中断允许位。EX1=1,允许外部中断1中断:EX1=0,禁止外部中断1中断。
ET0: T0的溢出中断允许位。ETO=1,允许TO中断;ETO=0禁止TO中断。
EX0: 外部中断0中断允许位。EX0-1,允许中断;EXO-0禁止中断。
因而,在使用外部中断时,应该令EA=1,同时令EX0=1(外部中断0)
中断允许寄存器除了IE外还有IE,是用于SPI中断以及串口2中断的,感兴趣的可以自行查看芯片手册~
(2)IPH、IP:中断优先级控制寄存器
中断优先级遵循以下原则:
1.低优先级中断可被高优先级中断所中断,反之不能。
2.任何一种中断(不管是高级还是低级),一旦得到响应,不会再被它的同级中断所中断
IPH: 中断优先级控制寄存器高(不可位寻址)
IP: 中断优先级控制寄存器低 (可位寻址)
PPCAHPPCA: PCA中断优先级控制位。
当PPCAH=0且PPCA=0时,PCA中断为最低优先级中断(优先级0)
当PPCAH=0且PPCA=1时,PCA中断为较低优先级中断(优先级1)
当PPCAH=1且PPCA=0时,PCA中断为较高优先级中断(优先级2)
当PPCAH=1且PPCA=1时,PCA中断为最高优先级中断(优先级3)
PLVDH.PLVD:低压检测中断优先级控制位。当PLVDH=0日PLVD=0时,低压检测中断为最低优先级中断(优先级0)
当PLVDH=0日PLVD=1时,低压检测中断为较低优先级中断(优先级1)
当PLVDH=1日PLVD=0时,低压检测中断为较高优先级中断(优先级2)
当PLVDH=1日PLVD=1时,低压检测中断为最高优先级中断(优先级3)
PADCH.PADC: A/D转换中断优先级控制位。
当PADCH=0日PADC=0时,A/D转换中断为最低优先级中断(优先级0)当PADCH=0日PADC=1时,A/D转换中断为较低优先级中断(优先级1)
当PADCH=1且PADC=0时,A/D转换中断为较高优先级中断(优先级2)
当PADCH=1且PADC=1时,A/D转换中断为最高优先级中断(优先级3)
PSH.PS:串口1中断优先级控制位。
当PSH=0且PS=0时,串口1中断为最低优先级中断(优先级0)当PSH=0且PS=1时,串口1中断为较低优先级中断(优先级1)
当PSH=1且PS=0时,串口1中断为较高优先级中断(优先级2)
当PSH=1日PS=1时,串口1中断为最高优先级中断(优先级3)
PT1H,PT1: 定时器1中断优先级控制位。
当PT1H=0且PT1=0时,定时器1中断为最低优先级中断(优先级0)当PT1H=0且PT1=1时,定时器1中断为较低优先级中断(优先级1)
当PT1H=1日PT1=0时,定时器1中断为较高优先级中断(优先级2)
当PT1H=1且PT1=1时,定时器1中断为最高优先级中断(优先级3)
PX1H,PX1: 外部中断1优先级控制位
当PX1H=0日PX1=0时,外部中断1为最低优先级中断(优先级0)当PX1H=0且PX1=1时,外部中断1为较低优先级中断(优先级1)
当PX1H=1日PX1=0时,外部中断1为较高优先级中断(优先级2)
当PX1H=1且PX1=1时,外部中断1为最高优先级中断(优先级3)
PT0H,PT0:定时器0中断优先级控制位。
当PT0H=0且PT0=0时,定时器0中断为最低优先级中断(优先级0)当PT0H=0日PT0=1时,定时器0中断为较低优先级中断(优先级1)
当PT0H=1且PT0=0时,定时器0中断为较高优先级中断(优先级2)
当PT0H=1且PT0=1时,定时器0中断为最高优先级中断(优先级3)
PXOH.PXO: 外部中断0优先级控制位。
当PX0H=0且PX0=0时,外部中断0为最低优先级中断(优先级0)当PX0H=0且PX0=1时,外部中断0为较低优先级中断(优先级1)
当PX0H=1且PX0=0时,外部中断0为较高优先级中断(优先级2)
当PX0H=1且PX0=1时,外部中断0为最高优先级中断(优先级3)
中断优先级使用得比较少,了解一下即可,除了IPH、IP外,中断优先级控制寄存器还有IP2H,IP2,用于SPI中断,串口2中断优先级处理。
(3)TCON: 定时器/计数器中断控制寄存器 (可位寻址)
IE1: 外部中断1请求源 (INT1/P3.3) 标志。
IE1=1,外部中断向CPU请求中断,当CPU响应该中断时由硬件清“0”IE1。
IT1:外部中断1中断源类型选择位。IT1=0,INTI/P3.3引脚上的低电平信号可触发外部中断1。
IT1=1,外部中断1为下降沿触发方式。
IE0:外部中断0请求源 (INT0/P3.2) 标志。IE0=1外部中断0向CPU请求中断,当CPU响应外部中断时,由硬件清“0”IEO (边沿触发方式)
IT0:外部中断0中断源类型选择位。IT0=0,INTO/P3.2引脚上的低电平可触发外部中断0。
IT0=1,外部中断0为下降沿触发方式。
可以选择由低电平触发或者下降沿触发。
由原理图可知,P3.3和P3.2与按键S4,S5相连,则可以用于检测按键是否按下触发中断
此外,与中断相关的寄存器还有串行口控制寄存器SCON,这个放在串口部分叙述。
6、中断服务函数程序的编写
一般情况下,中断的处理函数有两个,其一为中断初始化函数,其二为中断服务函数。初始化函数就是一个普通的函数,而中断服务函数却有特殊的格式要求:
①中断函数没有返回值,也不能带参数。
② 函数名后面要跟一个关键字interrupt,说明这是一个中断服务函数。
③ 在关键字interrupt后面要跟上中断号,说明这个中断服务函数是为那个中断服务的。
void Init_INT0()//中断初始化函数
{
中断初始化;
}
void 函数名() interrupt 中断号 //中断服务函数
{
----函数体----
}
二、程序案例
例子:定义working()函数,使L1指示灯不停闪烁,将P3.2引脚定义为外部中断功能,按下S5按键就会产生中断信号,点亮L8指示灯,延时一段时间后熄灭。
#include "reg52.h"
sbit L1=P0^0;//定义LED指示灯引脚
sbit L8=P0^7;
unsigned char stat_int=0;//设置中断状态量
/*****************************************************************
*@Function: Delay //
*@Description: 延时函数 //
*@Input: 无//
*@Output: 无//
*@Return: 无 //
*@Others: 无 //
/*****************************************************************/
void Delay(unsigned int t)
{
while(t--);
}
/*****************************************************************
*@Function: SelectHC573 //
*@Description: 锁存器选择 //
*@Input:channel:选择通道 //
*@Output: 无//
*@Return: 无//
*@Others: 无 //
/*****************************************************************/
void SelectHC573(unsigned int channel)
{
switch (channel)
{
case 4:
P2=P2&0x1f|0x80;
break;
case 5:
P2=P2&0x1f|0xa0;
break;
case 6:
P2=P2&0x1f|0xc0;
break;
case 7:
P2=P2&0x1f|0xe0;
break;
}
}
/*****************************************************************
*@Function: working //
*@Description: 使得L1不停闪烁 //
*@Input: 无//
*@Output:无 //
*@Return: 无 //
*@Others: 无 //
/*****************************************************************/
void working()
{
SelectHC573(4);
L1=0;
Delay(60000);
L1=1;
Delay(60000);
}
/*****************************************************************
*@Function: Init_INTO //
*@Description: 初始化外部中断0 //
*@Input:无//
*@Output:无//
*@Return:无//
*@Others:无//
/*****************************************************************/
void Init_INTO()
{
IT0=1;//设置为下降沿触发
EX0=1;//允许外部中断0中断
EA=1;//CPU开放中断
}
/*****************************************************************
*@Function:ServiceINTO //
*@Description:外部中断0服务函数 //
*@Input: 无//
*@Output: 无//
*@Return: 无 //
*@Others:无 //
/*****************************************************************/
void ServiceINTO() interrupt 0
{
stat_int=1;//将中断状态量置1,表示进入中断
}
/*****************************************************************
*@Function: LEDINT //
*@Description: 若进入中断(stat_int==1),点亮L8,延时一段时间后熄灭 //
*@Input:无 //
*@Output:无 //
*@Return: 无 //
*@Others: 无 //
/*****************************************************************/
void LEDINT()
{
if(stat_int==1)
{
L8=0;
Delay(60000);
Delay(60000);
Delay(60000);
Delay(60000);
Delay(60000);
Delay(60000);
Delay(60000);
Delay(60000);
Delay(60000);
Delay(60000);
L8=1;
}
stat_int=0;
}
void main()
{
Init_INTO();//中断初始化
while(1)
{
LEDINT();
working();
}
}
中断系统与外部中断应用是很重要的一部分,需要好好掌握~
感谢大家的观看
欢迎大家提出问题并指正~