一 中断的概念
CPU在处理某一事件A时,发生了另一事件B请求CPU迅速去处理(中断发生);
CPU暂时中断当前的工作,转去处理事件B(中断响应和中断服务);
待CPU将事件B处理完毕后,再回到原来事件A被中断的地方继续处理事件A(中断返回),这一过程被称为中断。
概念可能不好理解,举个例子:假如你是个老师,你在上课,突然电话响了,一看是你老婆打过来的,你不敢不接,于是你只好暂停讲课接听电话,挂完电话,你继续讲课。这个过程中实际发生了一次中断。
二 中断的响应条件
1.中断源有中断请求;
2.此中断源的中断允许位为1;
3.CPU开中断。
以上3条同时满足时,CPU才有可能响应中断。
三 中断的种类
52单片机共有六个中断源,分别是外部中断INT0、INT1,定时器\计数器中断T0、T1、T2,串行口中断TI\RI。
这里面还设计到一个中断优先级的概念:
| 中断源 | 级别 |
|---|---|
| INT1 | 最高 |
| T0 | 第二 |
| INT1 | 第三 |
| T1 | 第四 |
| TI\RI | 第五 |
| T2 | 最低 |
本次主要讲的定时器T0、T1功能。
四 定时器的使用
目前要实现定时功能主要有以下方式:软件定时(说简单点就是用for循环)、采用时基电路定时(555电路)、采用可编程芯片定时。本次主要讲述的就是第三种方法。
工作原理十分简单:当加到计数器全为1时,再输入一个脉冲就使得计数器回零,且计数器的溢出使TCON中TF0或TF1置1,向CPU发出中断请求。
定时器的工作方式又由寄存器TMOD决定。TMOD总共有八位,第四位用于T0、高四位用于T1。

各位功能如下:

M1M0的功能如下:

这里我们主要讲的方式1。
控制寄存器TCON:

定时器的使用步骤:
1.对TMOD赋值,以确定T0和T1的工作方式。
2.计算初值,并讲其写入TH0、TL0或TH1、TL1。
3.对中断允许寄存器IE赋值,开放中断。
4.使TR0、TR1置位。
接下来我们来写代码:
首先我们来看看中断函数怎么写:
void exter0() interrupt 1 //中断函数不能返回任何值,函数名字可以随便起
{ //interrupt后面跟的数字为中断优先级。
TH0=(65536-50000)/256; //往往后面还会带一个using + 一个数字。
TL0=(65536-50000)%256; //这个数字表示此中断使用四组工作寄存器哪一组。
tt++; //C51编译器自动分配工作组,因此这个using常常省略。
}
这就是中断函数,当加一计数器溢出时则会进入此函数。
初始化定时器:
void init()
{
tt=0;
TMOD=0X01;//设置定时器0为方式1
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
EA=1; //开总中断
ET0=1; //开定时器中断0
TR0=1; //启动中断
}
这里往往大家有疑问的是那个初值怎么赋值,从上面的知识点可知,每个定时器都有4种工作模式,可通过设置TMOD寄存器中的M1M0位来进行工作方式选择。这里我们主要讲16位的。
方式1的计数位数是16位,对T0来说,由TL0寄存器作为低8、TH0寄存器作为高8位,组成了16位加1计数器。
定时器一但启动(TR0、TR1=1),它便在原来的数值上开始加1计数,若在程序开始时,我们没有设置TH0和TL0,它们的默认值都是0,假设时钟频率为12MHz,12个时钟周期为一个机器周期,那么此时机器周期为1us,记满TH0和TL0就需要2的16次方 -1个数,再来一个脉冲计数器溢出,随即向CPU申请中断。因此溢出一次共需65536us,约等于65.6ms,如果我们要定时50ms的话,那么就需要先给TH0和TL0装一个初值,在这个初值的基础上记50000个数后,定时器溢出,此时刚好就是50ms中断一次,当需要定时1s时,我们写程序时当产生20次50ms的定时器中断后便认为是1s,这样便可精确控制定时时间啦。要计50000个数时,TH0和TL0中应该装入的总数是65536-50000=15536.,把15536对256求模:15536/256=60装入TH0中,把15536对256求余:15536/256=176装入TL0中。
以上就是定时器初值的计算法,总结后得出如下结论:当用定时器的方式1时,设机器周期为TCY,定时器产生一次中断的时间为t,那么需要计数的个数为N=t/TCY ,装入THX和TLX中的数分别为:
THX=(65536-N)/256 , TLX=(65536-N)%256 <x为0或1>。如果还不懂可以去看看B站上的课程。
以上图片来自于郭天祥老师2007年在哈尔滨授课的课件中。

4301

被折叠的 条评论
为什么被折叠?



