51单片机:开启中断和定时器

51单片机:开启中断和定时器


关于中断,需要用到中断允许寄存器:

在这里插入图片描述

开启定时器中断需要的条件:

  • 总中断EA:用来开启全局中断。
  • ET0、1、2:各个定时器中断位。
  • 使用中断位只用将其置1就行,例如EA=1;ET0=1;
  • 打开了中断开关只是完成了一半,还需要定时器控制寄存器:
    在这里插入图片描述
    使用方法也是和中断寄存器一样,
    定时器0运行控制位TR0:用来开启定时器0.
    把TR0置1,TR0=1;就开启了定时器。

设置中断服务程序:

在这里插入图片描述

中断服务程序:就是当计满TH0、TL0时溢出申请中断,然后单片机允许中断时,所要发生的事情。允许后就自动跳转到中断服务程序,并执行。
在服务程序中,如果不装入初值,那定时器中断服务完成后,就会从0开始重新计时,所以要在中断程序中重新计算并装入初值。
然后给一个变量(变量的意义为中断次数),变量+1,当中断次数达到20次的时候(50ms*20次=1000ms=1s),次数清零,并且让产生指令(例如让二极管亮呀,让I/O口发生什么事呀)

主函数:
在这里插入图片描述

由于有了初始化函数,所以直接调用即可,
另外:一般中断服务程序中不要写过多的处理语句,
否则程序会来不及执行代码,
下一次中断又来袭,结果程序久而久之就乱套了。
所以while处可以改成:把if处理语句写到while处。

在这里插入图片描述

附上完整程序:

在这里插入图片描述

二、各个定时器和工作方式:

先来看看工作方式:

在这里插入图片描述

  • 工作方式有四种:0、1、2、3。我们之前已经学习了方式1的工作方式,那么接下来就先来看看其他的工作方式:

方式0,的用法和方式1的用法一样,但是值得注意的是:

在这里插入图片描述

  • 方式0是13位的定时器,它的低位TL0是五位的,所以它的总值是28*25=8192。它能装的值也不能那么多了,于是就装入5ms:
    TH0(8192-5000)/32;
    TL0(8192-5000)%32;
    32是5位寄存器的容量。
    所以要中断200次才能达到1s。
    这个方式0可以用来做短时间中断。
  • 方式2:

方式0和方式1,当计数溢出后,计数器变为0,所以要反复重新装填初值,这会影响定时精度。但是方式2可以解决这个问题。

在这里插入图片描述
如图,其中低位TL0是8位定时器,而TH0是常数缓冲器,当低位TL0溢出时,在溢出标志位TF0置1的同时,自动将高位TH0的常数重新装入TL0中,让TL0从初值开始重新计数,这样就不用人为软件重新装入初值带来的误差,从而提高精度。
由于两个是分开的,所以计算初值可以不用求余取模:
TL0=总值-要计数的个数;
TH0=总值-要计数的个数;

  • 以11.0592MHz为晶振,那么机械周期为12x(1/11059200)≈1.085us,以计时1s为例,当要计250个数时耗时1.0851x250=271.275us,再来算计时1s要用多少次,即1000000/271.275≈3686次。
    那么就是:
    在这里插入图片描述
    TL0=256-250=6;
    TH0=256=250=6;
    由于方式2是自动装填,已经不用人为装填了,所以:
    在这里插入图片描述
    中断服务程序中只有一句num++
    整个过程就是:在这里插入图片描述
  • 方式3:

接下来介绍方式3,方式3不同于其他三个方式,它只能用于T0,也就是定时器0,和方式2差不多,也是把TL0、TH0分成两个独立的寄存器,但是TH0也参与计数,也就是两个独立的8位定时器/计数器。
普通的使用一样,TL0计数溢出后置位TF0,并申请中断,之后重装。但是由于TL0占用了TR0和TF0,所以TH0只能占用定时器 T1的TR1和TF1。所以定时器T1一定不要用在有中断的场合,当然,T1同样可以正常工作在方式0、1、2下。通常这种情况,T1都被用来当做串行口的波特率发生器。
首先把T0、T1的中断位和控制位打开:

在这里插入图片描述

然后分别给低位TL0和高位TH0设置中断服务程序:

在这里插入图片描述

可以注意到interrupt后面的数值,这个是编译器识别不同中断的唯一符号:

在这里插入图片描述> 然后到主函数:调用init();
在这里插入图片描述

可以看到if语句里面的符号是>=,为什么呢?因为当if语句的值到了时,主程序停止下来判断num1==3686是否为真,当它还在判断的时候,num2是还在走的,于是当主程序判断好num1的时候再去判断num2,为时已晚,num2这时可能已经是1844或者1845或者更高的数了,所以要变成>=