中断知识点整理概要Word文档格式.docx
《中断知识点整理概要Word文档格式.docx》由会员分享,可在线阅读,更多相关《中断知识点整理概要Word文档格式.docx(24页珍藏版)》请在冰豆网上搜索。
设置工作方式寄存器TMOD(对于定时器中断来说的,外部中断不需要)
第二步:
设置控制寄存器TCON
第三步:
设置中断允许寄存器,开启相应的中断。
四:
相关寄存器介绍。
1.定时器/计数器工作方式寄存器TMOD。
TMOD共有8位,其高四位用来设置定时器1,低四位用来设置定时器0.
1.GATE门控制位GATE=0定时器/计数器的启动仅受TCON寄存器中TRX来控制
GATE=1,受TRX和外部中断引脚电平状态共同控制
2.C/T定时器和计数器模式选择位。
=0时定时器,=1计数器。
3.M1M0工作方式选择位。
M1M00013位定时器/计数器
0116位定时器/计数器方式一
108位初值自动重装的定时器/计数器二
综上:
使用定时器T0工作方式1时设置为TMOD=0x01
使用定时器T0工作方式2时设置为TMOD=0x02
2.定时器/计数器控制寄存器TCON
低四位用于外部中断;
高四位用于定时器/计数器
(1)关于外部中断0
IE0:
外部中断0中断请求标志位。
IT0:
外部中断0触发方式控制位。
当IT0=0时,为电平触发方式。
(默认为0,因此使用外部中断就开EA,开EX0)
当IT0=1时,为跳变沿触发方式(下降沿有效)。
【当第一个机器周期采样到INT0为低电平时,IE0置1。
IE0=1,表示外部中断0正在向CPU申请中断。
当cpu相应中断,转向中断服务时,IE0由硬件清0.】
(仔细研究下这玩意,尝试查询法)
IE1与IT1外部中断1,与此用法相同。
TF0:
定时/计数器T0溢出中断请求标志位。
【当定时器0计满溢出时,由硬件使TF0置1,并且申请进入中断,进入中断服务程序后,此位由硬件自动清零。
需要注意的是,如果使用定时器的中断,那么该位完全不用人为去操作。
但是如果使用软件查询方式的话,当查询到该位置1后,需由软件清0】
TR0:
定时器0运行控制位。
TR0=1;
启动定时器0,软件清0关闭定时器0
TR1,TF1是关于定时器1的,具体用法与定时器0同。
以上便是对定时器的设置。
接下来设置中断允许寄存器。
▪EA,全局中断允许(总允许)位。
▪EX0,外部中断0允许位,EX0=1;
开中断。
=0;
关中断。
EX1外部中断1允许位;
▪ET0,定时/计数器T0中断允许位;
ET1,定时/计数器T1
▪ES,串行口中断允许位;
IE是中断允许寄存器,其值为82时,二进制为10000010,IE.7位为1表示CPU开放中断,IE.1位也为1,表示允许定时器T0溢出中断
综上所述,便完成了对各种中断的设置和开启关闭。
再加上一个中断子函数就OK了。
备注:
外部中断0interrupt0
定时器中断0interrupt1
外部中断1interrupt2
定时器中断1interrupt3串口中断interrupt4
接下来是实战:
1.首先是外部中断0(电平触发方式)
#include<
reg52.h>
#defineucharunsignedchar
sbitd=P1^0;
uchari;
voidmain()
{//首先TMOD不是关于外部中断的,不需设置
EA=1;
//然后是TCON寄存器,TR0默认0,也不许设置
EX0=1;
//所以只需开总中断,开外部中断就可以了。
while
(1);
}
voidser()interrupt0
{
EX0=0;
//进入后就关闭中断,防止中断程序还未执行完毕就在此进入中断
i++;
//实际测试时最好加个延时,防止持续的低电平使单片机持续进入中断
if(i==1)//类似于按键消抖
d=0;
if(i==2)
d=1;
2.然后是外部中断0(跳变沿触发方式)
#defineuintunsignedint
sbitbeep=P2^3;
sbitt=P3^2;
voiddelay(uintz)
{
uintx,y;
for(x=z;
x>
0;
x--)
for(y=110;
y>
y--);
t=0;
IT0=1;
//设置TCON,设为跳变沿触发
while
(1)
{
t=1;
delay(5);
t=0;
}
{
beep=0;
delay(1000);
beep=1;
3.定时器0中断(方式1):
步骤还是以上说的那样,先设TMOD,再赋初值,再设TCON,然后启动总中断,开TR0.
但关于赋初值:
1.由计数产生中断,计满溢出便会进入中断。
不赋初值,默认为0,计65536个数,即耗费65536us.
2.若晶振为12MHZ,要计多长时间,就用(65536-t)这就是初值,在此基础上计时。
11.0592MHZ时,(65536-45872)/256;
(65536-45872)%256;
便是计时50毫秒。
3.需要计数的个数N=需要计数的时间t/机器周期T12个时钟周期为1个机器周期。
时钟周期便是频率的倒数。
unsignedchari;
TMOD=0x01;
//设定为定时器0工作方式是1
TH0=(65536-45872)/256;
TL0=(65536-45872)%256;
//50毫秒进入一次中断
TR0=1;
//设置TCON
ET0=1;
//开定时器0中断
if(i==20)
{
P1=0x00;
}
if(i==40)
i=0;
P1=0xff;
voidser()interrupt1
扩展:
1.定时器、计数器0方式0的应用:
通过设置M1M0位为00选择定时器方式0,计数位数是13位的,由TL0的低五位和TH0的8位组成,最多能装8192个数。
若晶振为11.0592MHZ,则机器周期为12*(1/11.0592)=1.0851us.若计时t=5ms,则需要计数N=5000/1.0851=4607。
则初值为TH0=(8192-4607)/32;
TL0=(8192-4607)%32;
计数时只使用了TL0的低五位,所以最多计32个数就会进1.
示例程序:
TMOD=0x00;
TH0=(8192-4607)/32;
//计时5ms
if(i==200)
d=~d;
2.定时器0中断(方式2):
自动重装
TMOD设置为0x02即可。
(TMOD=00000010转化为16进制为0x20)但方式2是8位的,计时的时间比较短。
方式2适合做比较精确地脉冲信号发生器(晶振为12M这样才不会有误差)
8位自动重装计数器,最多计256个数。
机器周期仍为1.0851us(12M便是1us),若每次计250个数,耗时1.0851*250=271.275us,要计1s的话,需要溢出1000000/271.275us=3686次。
初值为6。
/*
方式2适合做比较精确地脉冲信号发生器(晶振为12M这样才不会有误差)
8位自动重装计数器,最多计256个数。
机器周期仍为1.0851us(12M便是1us),
若每次计250个数,耗时1.0851*250=271.275us,
要计1s的话,需要溢出1000000/271.275us=3686次。
同理,12M晶振,250次,即为250us,溢出4000次即为1s
*/
unsignedintn;
//不能用uchar了哦
TMOD=0x02;
//定时器0方式2
TH0=6;
TL0=6;
if(n==3686)//计时1s需溢出3686次
n=0;
d=!
d;
n++;
//不需要赋初值哦
3.定时器0(方式3)的应用(方式3只适用于T0)
(1).M1M0设置为11即为方式3.
(2)方式3被分为两个独立的计数器,TL0为正常的8为计数器,计数器溢出后置位TF0,并向CPU申请中断,之后手动重装初值。
TH0也被固定为一个位计数器,但它将占用T1的中断请求标志TF1和定时器启动控制位TR1。
(3).因为方式3占用了T1的中断,所以使用方式3就不能使用T1的中断。
但T1仍然可以正常工作在方式0,1,2下。
通常这种情况下T1被用来当做串行口的波特率发生器。
sbitd1=P1^0;
sbitd2=P1^1;
unsignedintn1,n2;
TMOD=0x03;
//定时器0方式3
ET1=1;
//TH0占用T1的中断,所以也要打开
TR1=1;
//
if(n1>
=3686)//必须是>
=
n1=0;
d1=~d1;
if(n2>
=1843)//定时半秒
n2=0;
d2=~d