首页 > 其他分享 >51单片机中断服务

51单片机中断服务

时间:2023-11-01 09:33:45浏览次数:30  
标签:服务程序 定时器 优先级 中断向量 中断 51 单片机

1.中断的概念

在51单片机中,中断是一种机制,可以让单片机在执行某个任务时,暂停当前程序的执行,转而去执行另外一个优先级更高的任务,待该任务执行完毕后,再回到原来的任务继续执行。中断机制可以有效提高单片机的实时性和响应速度。在51单片机中,中断可以通过设置中断向量表来实现。

中断向量表是一个存储区域,它记录了所有中断服务程序的入口地址。当中断发生时,单片机会根据中断类型(外部中断、定时器中断、串口中断等)去中断向量表中查找对应的中断服务程序的入口地址,然后跳转到该地址执行中断服务程序。

让CPU产生中断信号的称为中断源(中断请求源),定时器/计数器实际上就是中断源。例如“当定时/延时50 ms的时间后,定时器内部总线自动向CPU发出一个中断请求:‘停止当前定时/计数的工作,转而去执行中断程序(如点亮一个LED灯)’”,执行完后,再返回接着执行原来的工作。

8051单片机提供了5个中断源,它们可以向CPU发送中断请求。如果一个中断源向它发出中断请求信号,它就会产生中断,但是如果同时有两个中断源发出中断请求信号,CPU会根据优先级决定接受哪一个中断请求,先接受高优先级的中断请求,再接受低优先级的中断请求。

中断源优先级中断入口地址中断编号
外部中断 INT0 0003H 0
定时器 T0 较高 000BH 1
外部中断 INT1 适中 0013H 2
定时器 T1 较低 001BH 3
串行通信中断R1或T1 0023H 4

2.中断子程序的写法

定义中断服务程序的入口地址:

1.定义中断服务程序的入口地址:
中断类型 中断服务程序名称() interrupt 中断类型号
{
  //中断服务程序的代码
}

2.中断服务函数的完整语法:
void 函数名(void)interrupt n [using r]
{
  //中断服务程序的代码
}

其中:
n(0~4)代表中断号,其编号意义如上表所示。
r(0~3)代表第r组寄存器,如果不声明,则默认第0组寄存器。有如下4个寄存器:
(1)定时器/计数器控制寄存器TCON;
(2)串行通信控制寄存器SCON;
(3)中断允许寄存器IE;
(4)中断优先级控制寄存器IP;
调用中断函数时,要求中断过程调用的函数所使用的寄存器组必须与其相同,逻辑上,一个中断服务程序不能传递参数进去,也不可返回值。

其中,中断类型可以是外部中断、定时器中断、串口中断等;中断服务程序名称是用户自定义的程序名称;interrupt 是51单片机中断向量表中的关键字,用于告诉单片机这是一个中断服务程序;中断类型号是中断向量表中对应的中断类型号。

3.设置中断向量表

void main()
{
  //设置中断向量表
  EA = 1;       //开总中断
  EX0 = 1;      //开外部中断0
  IT0 = 1;      //设置外部中断0为下降沿触发
  TMOD = 0x01;  //设置定时器0为模式1
  TH0 = 0xFC;   //设置定时器0初值
  TL0 = 0x67;   
  ET0 = 1;      //开定时器0中断
  TR0 = 1;      //启动定时器0
  while(1)
  {
    //主程序代码
  }
}

在main函数中,需要设置中断向量表,包括开总中断、开外部中断、设置外部中断触发方式、开定时器中断、设置定时器初值、启动定时器等。这些操作会在单片机中断发生时,使得单片机能够根据中断类型去中断向量表中查找对应的中断服务程序的入口地址。

4.编写中断服务程序

void external0_isr() interrupt 0
{
  //外部中断0服务程序的代码
}

void timer0_isr() interrupt 1
{
  //定时器0服务程序的代码
}

在中断服务程序中,需要根据实际需求编写对应的代码,实现对中断事件的响应。在中断服务程序的开头和结尾需要加上关中断和开中断的指示,确保中断服务程序执行过程中不会被其他中断打断。

5.关中断和开中断

void external0_isr() interrupt 0
{
  EA = 0;   //关总中断
  //外部中断0服务程序的代码
  EA = 1;   //开总中断
}

void timer0_isr() interrupt 1
{
  EA = 0;   //关总中断
  //定时器0服务程序的代码
  EA = 1;   //开总中断
}

在中断服务程序的开头和结尾,需要加上关中断和开中断的指示,以确保中断服务程序的执行过程中不会被其他中断打断。在开头处关中断,可以避免在执行中断服务程序时,又发生同样的中断事件,造成重复执行;在结尾处开中断,可以使得其他优先级更低的中断能够在该中断服务程序执行完毕后立即得到响应,提高单片机的实时性和响应速度。总的来说,编写51单片机中断子程序需要注意以下几点:

  • 定义中断服务程序的入口地址,包括中断类型、中断服务程序名称、中断类型号等。
  • 设置中断向量表,包括开总中断、开外部中断、设置外部中断触发方式、开定时器中断、设置定时器初值、启动定时器等。
  • 编写中断服务程序,根据实际需求编写对应的代码,确保中断服务程序执行过程中不会被其他中断打断。
  • 在中断服务程序的开头和结尾加上关中断和开中断的指示,以确保中断服务程序的执行过程中不会被其他中断打断。

6.中断优先级

在51单片机中,不同类型的中断有不同的优先级,而同一类型的中断则是按照中断产生的先后顺序决定优先级。如果同时有多个中断请求,优先级高的中断将被先响应,而优先级低的中断则需要等待优先级高的中断服务程序执行完毕后才能被响应。

当需要处理多个中断事件时,需要根据实际需求设置不同的中断优先级,以确保系统能够在高优先级中断事件发生时及时响应并处理,从而提高系统的实时性和可靠性。

7.中断嵌套

在51单片机中,允许中断嵌套,即在一个中断服务程序执行期间,又触发了另一个中断请求。为了避免中断服务程序被打断,需要使用嵌套中断的方式来处理多个中断事件。

当出现嵌套中断时,需要根据实际需求设置不同的中断优先级,以确保系统能够在高优先级中断事件发生时及时响应并处理,从而提高系统的实时性和可靠性。

总之,51单片机中断子程序的写法是非常重要的,它能够帮助我们实现单片机的实时响应和高可靠性运行。在编写中断子程序时,需要注意中断类型、中断服务程序名称、中断向量表、中断优先级和中断嵌套等相关问题,从而确保中断子程序的正确性和可靠性。

8.中断标志位的清除

在51单片机中,当一个中断事件被响应后,需要清除中断标志位,以允许下一个中断事件被响应。在编写中断服务程序时,需要根据实际需求清除对应的中断标志位。

例如,在使用定时器中断时,需要清除定时器中断标志位TF0,代码如下所示:

void timer0_isr() interrupt 1
{
  EA = 0;   //关总中断
  //定时器0服务程序的代码
  TF0 = 0;  //清除定时器0中断标志位
  EA = 1;   //开总中断
}

9.中断服务程序的调试

在编写中断服务程序时,需要注意调试的问题。由于中断服务程序不是在主程序中调用的,因此在调试时需要使用其他方法来检查中断服务程序的正确性和可靠性。一般来说,可以使用调试工具来监控中断服务程序的执行情况,并对中断服务程序的代码进行调试和优化。

总的来说,51单片机中断子程序的写法需要综合考虑多个因素,包括中断类型、中断服务程序名称、中断向量表、中断优先级、中断嵌套、中断标志位的清除和中断服务程序的调试等。只有在考虑到这些因素的基础上,才能编写出正确、可靠、高效的中断子程序,从而提高单片机的实时响应能力和可靠性运行。

10.中断服务程序的实现

在实现中断服务程序时,需要注意以下几个问题:

  • 中断服务程序需要满足特定的格式要求,包括使用特定的关键字、参数等。
  • 中断服务程序需要尽可能地简单,避免使用复杂的代码结构和算法。
  • 中断服务程序需要尽可能地快速执行,避免过长的执行时间。
  • 中断服务程序需要对共享资源进行保护,以避免出现竞态条件等问题。

例如,在使用定时器中断时,需要使用volatile关键字来声明变量,避免出现编译器优化导致的问题;同时,在修改共享资源时需要使用关中断的方式进行保护,避免出现竞态条件,代码如下所示:

volatile unsigned char count = 0;

void timer0_isr() interrupt 1
{
  unsigned char temp;
  EA = 0;   //关总中断
  temp = TH0;
  temp = TL0;
  TH0 = 0xFC;  //重新赋初值,1ms定时
  TL0 = 0x67;
  count++;
  EA = 1;   //开总中断
}

void main()
{
  unsigned char num;
  TMOD = 0x01;   //设置定时器0为模式1
  TH0 = 0xFC;    //给定时器0赋初值,1ms定时
  TL0 = 0x67;
  TR0 = 1;       //定时器0开始计时
  ET0 = 1;       //允许定时器0中断
  EA = 1;        //开总中断
  while(1)
  {
    if(count >= 10)   //10ms到达
    {
      count = 0;
      num++;
    }
  }
}

在上述代码中,中断服务程序只是简单地对计数器进行加1操作,并在主程序中使用计数器来实现10ms的计时功能。同时,中断服务程序也对共享资源计数器进行了保护,避免出现竞态条件等问题。

中断是单片机中实现实时响应的重要机制之一,可以在单片机运行过程中对外部事件进行及时处理。在51单片机中,中断子程序的编写需要考虑多个因素,包括中断类型、中断服务程序名称、中断向量表、中断优先级、中断嵌套、中断标志位的清除和中断服务程序的调试等。只有在考虑到这些因素的基础上,才能编写出正确、可靠、高效的中断子程序,从而提高单片机的实时响应能力和可靠性运行。

同时,在编写中断服务程序时,需要注意格式要求、简单性、执行速度和共享资源保护等问题。只有在考虑到这些问题的基础上,才能编写出正确、可靠、高效的中断服务程序,从而实现单片机的实时响应功能。

总的来说,中断子程序的编写是单片机编程中非常重要的一个方面,需要充分理解中断机制的原理和实现方式,结合具体的应用场景进行设计和实现。

11.汇总

 

标签:服务程序,定时器,优先级,中断向量,中断,51,单片机
From: https://www.cnblogs.com/yilangUAV/p/17802327.html

相关文章

  • CF1451
    CF1451SubtractorDivide显然如果为偶数那么我们将它变到\(2\)再\(-1\)即可如果为奇数我们先\(-1\)再转化为偶数的情况即可对于\(n\le3\)进行特判#include<bits/stdc++.h>usingnamespacestd;#defineendl'\n'#defineinlinline#defineebemplace_back......
  • 102102151黄靖数据采集实践三
    作业一(1)要求:使用单线程和多线程的方法爬取中国气象网的限定数量的图片(2)下面给出代码实现:weather.pyimportscrapyfrom..itemsimportWeatherItemclassweatherSpider(scrapy.Spider):page=0number=0user_agent="Mozilla/5.0(WindowsNT10.0......
  • 世微 60V高端电流采样降压恒流驱动IC LED电源驱动器AP51656
    1产品描述AP51656是一款连续电感电流导通模式的降压恒流源,用于驱动一颗或多颗串联LED输入电压范围从5V到60V,输出电流最大可达1.5A。根据不同的输入电压和外部器件,可以驱动高达数十瓦的LED。内置功率开关,采用高端电流采样设置LED平均电流,通过DIM引脚可以接受模拟调......
  • P2514 [HAOI2010] 工厂选址 题解
    目录DescriptionSolutionCodeDescription有\(m\)座煤矿,每一座煤矿有\(a_i\)吨煤,第\(i\)座煤矿到第\(j\)号发电厂的运费为\(c_{i,j}\)每吨。有一座发电厂(标号为0),需要恰好\(b\)吨煤矿发电,初始运行费用为\(h\)。还有\(n\)座待运行的发电厂(标号为1~n),每座发电厂初......
  • STM32-基于标准库的中断串口通信
    目录STM32-标准库实现中断方式的串口通信实验任务实验过程总结体会参考STM32-标准库实现中断方式的串口通信实验任务使用标准库方式,设置USART1波特率为115200,1位停止位,无校验位,采用中断方式完成下列任务:STM32系统给上位机(win10)连续发送“hellowindows!”;当上位机给stm32发......
  • 这是我在51CTO博客的第一篇博文Loki 实现 Kubernetes1.24 容器日志监控
    使用Loki实现Kubernetes1.24容器日志监控一、基本介绍1.Loki架构2.Loki工作原理二、使用Loki实现容器日志监控1.安装Loki2.安装Promtail3.安装Grafana4.验证一、基本介绍Loki是由GrafanaLabs团队开发的,基于Go语言实现,是一个水平可扩展,高可用性,多租户的日志聚合系......
  • 微机原理与接口技术中断实验
    ;*******************************;;*中断实验IRQ3*;;*******************************;includeio.inc.modelsmall;定义程序的存储模式.stack;定义堆栈段(默认是1KB空间).datamsgbyte'TPCAinterruptNo.3!',0dh,0ah,0c......
  • 这是我在51CTO博客的第一篇博文
    大家好,我是毕夏,从事医疗行业16年了,目前主要是口腔医院,之前做过竞价推广,前端设计,后台程序员,从入门是一枚程序员,现在还是一枚程序员,技术没长进,头发是掉了不少。医疗网站比较好解决,一个简单的CMS即可,我擅长PHP的!下面和大家分享一点技术,就是自动生成日志$file='../logs/'.date("Ymd")......
  • 32-TIM定时中断
    一16位计数器,功能:定时中断、内外时钟源选择、输入捕获、输出比较、编码器接口、主从触发 ......
  • P5108 仰望半月的夜空
    Day\(\mathbbP_1^2+\mathbbP_2^2+\mathbbP_3^2\)。不考虑左端点最小,如何求出一个字典序最小子串,只需要建出后缀数组后找最小的\(i\)满足\(n-\text{sa}_i+1\geL\),然后取\(S[\text{sa}_i,\text{sa}_i+L-1]\)即可。现在的问题在于可能存在一个\(j>i\)使得\(S[\tex......