一、C51中断系统

定时器一直是单片机比较难且重要的一部分,刚学51单片机时对定时器中断等部分学的一知半解,过了很长一段时间再回去理解了一遍方才恍然大悟,在此写下自己的拙见,欢迎指正。

STC89C52RC单片机的中断系统分为三大类五个中断(串口收发算1个):
在这里插入图片描述
本文主要讲外部中断定时器中断

二、晶振频率与周期

在这里插入图片描述
51单片机外部有一个晶振,就是金属壳的两只脚的上面标着11.0592,代表的就是单片机主震频率:$11.0592MHz=11.0592 \times 10^6Hz$。$HZ$是频率单位,它是每秒钟的周期性变动重复次数的计量。换个角度想知道了频率就等于知道了周期。即,$时钟周期=\frac {1} {11.0592 \times 10^6Hz}(s)$。对于定时模式,是对机器周期计数。51单片机一个机器周期12个时钟周期(查数据手册),即:
$机器周期=12\times 时钟周期T=\frac {12} {11.0592 \times 10^6}(s)=\frac {12} {11.0592 }(us)$
在这里插入图片描述
51单片机有两个定时器和两个外部中断口,T0、T1、INT0、INT1。定时器我们就挑一个讲,定时器0内部有两个寄存器TH0和TL0,都是一字节的,分别是定时器0高位寄存器(TH0),定时器0低位寄存器(TL0), 我们知道2字节=16位,T0最大能存65535。

在这里插入图片描述
每过一个机器周期$\frac {12} {11.0592 }$(us),寄存器的值+1,当加到溢出后发出一个溢出中断,我们的程序可以捕获到这个中断,就可以知道此时经历了n个机器周期,根据公式[所需时间t=n×机器周期]就可以知道经历多长时间。但是,当我们要指定一定时间产生中断时,可以通过事先设定初始值达到指定时间产生中断。我们拿定时器工作模式1来说,模式1时TH、TL两个寄存器的8位同时使用(后面会解释为什么),两个8位叠加一起就是16位。众所周知16位的最大值就是65535。就好像本来我们让水一滴一滴的滴入一个只能装载65535滴水的容器里,当超过则溢出,倒掉重新收集水。但是我们可以先在这个容器里填了与10000滴水等体积的水泥,然后让水再滴,这时候只需要滴入[(65535+1)-10000]滴水就会溢出了,之后就是像上面那样倒掉再滴水,但是却缩短了集满水的时间。

三、定时器的配置

知道了这些我们可以做什么呢,我们要做的事情就是拿定时器,去得到我们想要的时间。要做的第一步事情,就是配置寄存器,也叫定时器的初始化

定时器的设置需要参考单片机的使用手册:

在这里插入图片描述
TMOD寄存器是特殊功能寄存器,它是一个8位的寄存器,8个位对半分,高4位用来控制定时器1(T1),低4位用来控制定时器0(T0)。我们拿T0来说。
在这里插入图片描述
先说第0和1位(寄存器从右到左代表从低到高位)的M0M1M是模式的意思,用来设定定时器的工作模式。比如说模式0,13位定时器,二进制的13位最大可以存8191,最后到溢出后发出一个溢出中断。模式1是16位定时器,同理16位,最大能存65535
在这里插入图片描述
定时器工作模式0:在这里插入图片描述
在这里插入图片描述

GATE=0时或门必定输出1,且TR=1时则定时器开始计数,因此我们也可以用TR来控制定时器计数的启动停止

TR:定时器运行控制器。

在这里插入图片描述

标志位:
TF:定时器溢出标志。
IE:外部中断请求标志位。
IT:外部中断控制位。
EA:总允许开关。

源允许开关:
EX:外部中断源允许开关
ET:定时器中断源允许开关。
ES:串口中断源允许开关。

断优先级$^{[注2]}$设置: PX、PT、PS
=1:高优先级
=0:低优先级
$^{[注2]}$高优先级的程序可以打断低优先级的程序。

当其中一整条路上的开关都导通了,相当于从这条路发出了个中断指令。那么要启用指定的定时器的初始化程序就要设置相对应这条路上的各个开关变量。

下面用定时器0配置一个1毫秒中断一次的定时器。

/*定时器0初始化*/
void timer0_init(){
    TMOD |=0x01;			//定时器0为模式1,16位定时器,当
							/*1ms=1000us,由公式1得:n=所需时间t/机器周期
							=1000/(12/11.0592)=922*/
    TH0=(65535-922)/255;
    TL0=(65535-922)%255+1;
    TR0=1;					//定时器运行控制器。
    ET0=1;					//打开定时器0中断
    EA=1;						//总中断
}

TH0TL0寄存器和运行到溢出则中断标志位TF0=1(被硬件置1,当单片机接收到中断指令后又被硬件置0),整条路导通产生中断。

中断向量

中断的工作原理就是本来CPU在运行一条主程序(main函数)时,出现了个中断指令,让CPU先去处理另一个程序,那么CPU该怎么走到那个程序去,就需要一个向量给它指路。执行完后又循着那个向量的反方向回去原来的主程序。中断系统中,每个中断都配有一个向量,我们给每个向量编个号,让它们以次序排列。

中断向量表:

在这里插入图片描述
承接上面那个程序,来写中断服务函数。已经知道,定时器1ms发生一次中断,就要执行一次下面这个程序,那么如果想要它计时1秒然后显示出来,其实就是1000个定时器1的中断。可以在中断服务函数里对全局变量进行操作。

int s=ms=0;//定义全局变量
/*中断服务函数*/
 void timer0(void) interrupt 1  //这个(interrupt 1)定时器0的中断向量次序
 {
    TH0=(65535-922)/255;//重新装载进去
    TL0=(65535-922)%255+1;//  
    ms++;
    if(ms==1000) {s++;ms=0;}
 }
void mian()
{
   while(1)  display(s);//显示出来,不再做展示
}
posted on 2022-10-26 21:29  7i7i  阅读(934)  评论(0编辑  收藏  举报