深圳市航顺芯片技术研发有限公司
直播中

李超

7年用户 1349经验值
私信 关注
[问答]

外部中断和定时器中断有哪些操作步骤

中断是什么意思?

什么是中断源?中断源有哪几种?
外部中断有哪些操作步骤?
定时器中断有哪些操作步骤?

回帖(1)

张强

2021-8-13 17:13:20
  中断概念
  中断时为了使单片机具有对外部或者内部随机发生的事件处理而设置的,中断功能的存在,很大程度上提高了单片机处理外部或者内部事件的能力。
  其实用生活中的例子,就是周六日,你的妈妈出门上班了,你们打开电脑玩起了游戏,玩的正好呢,你的妈妈突然回来拿东西,你马上把游戏关了,然后开始学习,等你把作业写完,你接着理直气壮的玩你的游戏。其实这个过程也算是完成了一次中断。
  对于单片机而言,中断就是指CPU在处理某一事件A的时候,发生了另一事件B,请求CPU迅速处理(中断发生);CPU暂时停止当前的工作(中断响应),转去处理事件B(中断服务);待CPU将事件B处理完毕后,再回到原来事件A被中断的地方继续处理事件A(中断完成),这一过程被称为中断。
  这两件事件对应的话,你打游戏就是主任务(嘿嘿,小打怡情,仅供娱乐,请勿当真哦),你的妈妈回来就是中断请求,你响应中断关闭电脑写作业,你写作业就相当于处理中断程序,等你写完作业接着打游戏,就相当于处理完中断程序回到主程序接着执行主程序。要注意的是,你的妈妈回来时随机发生的,无论她什么回来你都要去学习写作业。处理完接着打游戏。单片机在执行当前程序的时候,中断也可能随时发生,但无论任何时候发生,,只要发生,单片机就会停止当前程序去执行中断程序,处理完中断在返回到刚刚暂停处接着执行主程序。
  中断源
  中断源就是引起CPU中断的根源。 52单片机有6个中断源,符号、名称和产生条件及中断优先级如下:
  
  这里提一点,上面那个表一定要主要那个序号 ,因为写中断函数的时候要用,而产生条件作为了解就好,其实把中断源和序号结合起来记更容易的,还不会搞混哦。
  寄存器
  中断允许控制寄存器IE
  首先要说一个知识点:中断允许控制寄存器IE,这玩意是干啥的呢?说白了就是你要想使用中断你就必须打开对应得开关,而这些开关就在这些寄存器里面,只要对寄存器做一些处理,即可打开对应得开关。
  这里要说,置一打开,清零关闭,意思就是想要打开开关只要对应位符号或者位地址赋1即可,而关闭赋0就好。
  
  EA 对应得含义是总中断开关,它相当于一个总开关,想要使用中断首先必须打开总开关,也就是EA置一 。
  D0到D5这六位和52单片机的六个中断源对应,EX0为外部中断0,EX1为外部中断1,ET0为定时器/计数器0中断,ET1为定时器/计数器1中断,ET2为定时器/计数器2中断(52单片机独有),ES为串行口中断。
  上表D0–D5的顺序刚好和中断优先级对应,更容易记忆了。
  定时器/计数器控制寄存器TCON
  接着说这个定时器/计数器控制寄存器TCON ,这个寄存器就是对中断的启动(定时器/计数器)和产生条件(外部中断)的设置。虽然名字是定时器/计数器中断的,但是它的八位里也包括外部中断的。
  
  先说一些作为了解知道就行的位,D1位的IE0和D3位的IE1,这俩分别就是外部中断0和外部中断1的中断请求位,也就是通过这俩位来判断有没有外部中断,这个单片机会自己做,我们作为了解就行。D5位的TF0和D位的TF1,这俩就是定时器0和定时器1溢出标志位,就是定时器不断地加,加满溢出了之后给单片机一个中断,告诉加满了,而它也是有单片机处理的,会自动清0,我们无需关注。
  现在是有用的,应该说是要记住的位,也很简单,和上面的中断源是一一对应的,D0位的IT0和D2位的IT1 ,这俩就是外部中断0和外部中断1触发方式选择位,什么意思呢?之前说到中断源的外部中断0和外部中断1时,它俩产生条件里有低电平或者下降沿引起 这个条件,所以这俩位就是来选择你是怎么来触发外部中断的,置0位低电平,置1位下降沿,那啥叫个低电平触发或者下降沿触发呢?产生条件里还有有P3.2和P3.3端口引入,也就是,给P3.2和P3.3一个低电平(外部中断打开的前提),低电平触发就是只要是低电平就一直是外部中断,下降沿触发就是从高电平到低电平的那一小段过程触发外部中断。 我们一般都用低电平触发。 D4位的TR0和D6位的TR1,这俩位是定时器/计数器0和定时器/计数器1的运行控制位。也就是这俩位来启动和停止定时器的。
  定时器/计数器工作方式寄存器TMOD
  这个寄存器就是专门对定时器的,它就是来确定定时器的工作方式及功能选择。
  
  GATE位 门控制位,这个作为了解就行,它通常赋0,就是定时器/计数器的启动已停止只受TCON寄存器TR0或者TR1的控制。赋1的话,就多了一个条件是和外部中断引脚(INT0或者INT1)上的电平转台一起控制。
  C/T位 定时器模式或者计数器模式选择位。C/T=1 计数器模式,C/T=0 定时器模式。有一个记忆的技巧,定时(时间)的英语Time,如图,T上面有一个杠,表示低电平有效,也就是T(定时器模式)为0有效。
  M1MO 工作方式选择位
  
  一般我们选择01,也就是方式一,16位定时器/计数器 。
  要想使用中断最基础有俩部分,一是初始化,二是中断处理函数 ,当完成这俩步骤后,已经差不多了。
  外部中断
  多说无益,只要知道外部中断就只有外部中断INT0和INT1俩,而且它俩用法啊都差不多,当写会其中一个,把对应的标号换成另一个即可。
  整一个步骤,写外部中断按照这个步骤就好。以外部中断0为例,使用外部中断1,只需把0换位1即可。
  打开总中断(EA=1)
  打开外部中断(EX0=1;)
  设置中断触发方式(IT0=0;)
  咱写个外部中断产生之后数码管停止并点亮一个LED灯,代码如下:
  #include “reg52.h”
  ***it led=P2^0;
  #include “intrins.h”
  typedef unsigned int u16;
  typedef unsigned char u8;
  u8 smgduan[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
  0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
  //38译码器
  ***it LSA=P2^2;
  ***it LSB=P2^3;
  ***it LSC=P2^4;
  ***it led=P2^0;
  void Delay(u16 i) //11.0582HMz 100us
  {
  while(i--){
  unsigned char i;
  _nop_();
  i = 43;
  while (--i);
  }
  }
  //初始化外部中断
  INT_Init(){
  EA=1; //打开总中断
  EX0=1; //打开外部中断0,若想打开外部中断1,EX1=1; 即可
  IT0=0; //设置中断触发方式,可以不写,一般单片机默认为0,同上
  }
  void main(){
  INT_Init();
  while(1){ //函数停在这,等待外部中断发生
  u8 i;
  led=1;
  LSA=1;LSB=1;LSC=1;
  for(i=0;i《16;i++){
  P0=smgduan[i];
  Delay(1000);
  }
  }
  }
  //中断处理函数
  void INT() interrupt 0{ //如果想要用外部中断1,把0换成2
  led=0; //这里可以写你先要写的东西
  }
  注意的是:中断处理函数中不会有返回值,为void ;函数名可以自己起, interrupt 不能变,0就是中断源中的对应外部中断0的序号。interrupt和0之间要有一个空格。
  如何验证
  只是把程序下载进去单片机会发现啥变化也没有,既然是外部中断0,那它的产生条件里有由P3.2引入,我们设置了低电平触发方式,所以单片机成功下载之后,在51单片机芯片周围找到GND的一个引脚和P3.2的引脚,用杜邦线连接在一起即可。
  定时器中断
  直接说步骤吧。
  设置工作方式 TMOD
  设置初值 TH0和TL0(定时器1:TH1和TL1)
  打开总中断 EA=1;
  打开定时器中断 ET0=1;(定时器1:ET1=1;)
  启动定时器 TR0=1;(定时器1:TR1=1;)
  咱写一个用定时器0的方式1实现数码管第一位以一秒的时间间隔显示0-f,不断循环。代码如下:
  #include “reg52.h”
  #include “intrins.h”
  typedef unsigned int u16;
  typedef unsigned char u8;
  u8 smgduan[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
  0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
  //38译码器
  ***it LSA=P2^2;
  ***it LSB=P2^3;
  ***it LSC=P2^4;
  u8 num;
  void Timer0Init(){ //初始化 11.0582MHz 1ms
  TMOD|=0x01; //设置定时器0为工作方式1
  TH0=0xFC; //定时器0的高八位
  TL0=0x66; //定时器0的低八位
  ET0=1; //打开定时器0中断
  EA=1; //开总中断
  TR0=1; //启动定时器
  }
  void main(){
  Timer0Init();
  num=0; //数码管显示的数
  LSA=1;LSB=1;LSC=1;
  P0=smgduan[0];
  while(1);
  }
  void Time0() interrupt 1{
  static u16 i;
  TH0=0xFC; //重新置值
  TL0=0x66;
  i++;
  if(i==1000){
  i=0;
  num++;
  LSA=1;LSB=1;LSC=1;
  if(num==16)
  num=0;
  P0=smgduan[num];
  }
  }
  要注意的就是,因为TMOD的工作方式是方式1,所以必须手动重新赋初值,上面程序中i变量也可以设置为全局变量,而中断处理也可以写在主函数中。
  总结
  最主要就是理解那些步骤的含义。本来这是两篇,就是有些内容分开不好总结,所以合在一起,难免会遗漏一些东西。
举报

更多回帖

发帖
×
20
完善资料,
赚取积分