单片机C语言函数之中断函数(中断服务程序)
在开始写中断函数之前,我们来一起回顾一下,单片机的中断系统。
中断的意思(学习过微机原理与接口技术的同学,没学过单片机,也应该知道),我们在这里就不讲了,首先来回忆下中断系统涉及到哪些问题。
(1)中断源:中断请求信号的来源。(8051有3个内部中断源T0,T1,串行口,2个外部中断源INT0,INT1(这两个低电平有效,上面的那个横杠不知道怎么加上去))
(2)中断响应与返回:CPU采集到中断请求信号,怎样转向特定的中断服务子程序,并在执行完之后返回被中断程序继续执行。期间涉及到CPU响应中断的条件,现场保护,现场恢复。
(3)优先级控制:中断优先级的控制就形成了中断嵌套(8051允许有两级的中断嵌套,优先权顺序为INT0,T0,INT1,T1,串行口),同一个优先级的中断,还存在优先权的高低。优先级是可以编程的,而优先权是固定的。
80C51的原则是①同优先级,先响应高优先权②低优先级能被高优先级中断③正在进行的中断不能被同一级的中断请求或低优先级的中断请求中断。
80C51的中断系统涉及到的中断控制有中断请求,中断允许,中断优先级控制
(1)3个内部中断源T0,T1,串行口,2个外部中断源INT0,INT1
(2)中断控制寄存器:定时和外中断控制寄存器TCON(包括T0、T1,INT0、INT1),串行控制寄存器SCON,中断允许寄存器IE,中断优先级寄存器IP
具体的是什么,包括哪些标志位,在这里不讲了,所有书上面都会讲。
在这里我们讲下注意的事项
(1)CPU响应中断后,TF0(T0中断标志位)和TF1由硬件自动清0。
(2)CPU响应中断后,在边沿触发方式下,IE0(外部中断INT0请求标志位)和IE1由硬件自动清零;在电平触发方式下,不能自动清楚IE0和IE1。所以在中断返回前必须撤出INT0和INT1引脚的低电平,否则就会出现一次中断被CPU多次响应。
(3)串口中断中,CPU响应中断后,TI(串行口发送中断请求标志位)和RI(接收中断请求标志位)必须由软件清零。
(4)单片机复位后,TCON,SCON给位清零。
C51语言允许用户自己写中断服务子程序(中断函数)
首先来了解程序的格式:
void 函数名() interrupt m [using n]
{}
关键字 interrupt m [using n] 表示这是一个中断函数
m为中断源的编号,有五个中断源,取值为0,1,2,3,4,中断编号会告诉编译器中断程序的入口地址,执行该程序时,这个地址会传个程序计数器PC,于是CPU开始从这里一条一条的执行程序指令。
n为单片机工作寄存器组(又称通用寄存器组)编号,共四组,取值为0,1,2,3
中断号 中断源
0 外部中断0
1 定时器0
2 外部中断1
3 定时器1中断
4 串行口中断
这5个中断源的中断入口地址为:(在上一篇文章中讲到的ROM前43个存储单元就是他们,这40个地址用来存放中断处理程序的地址单元,每一个类中断的存储单元只有8B,显然不是中断处理的程序,而是存放着中断处理程序的真正地址)
INT0:0003H 0
T0: 000BH 1
INT1:0013H 2
T1: 001BH 3
串口: 0023H 4
中断向量(中断入口地址)= 中断号x8 +3
前面m意思很清楚,不同的m值表示这个函数是针对不同的中断源,比如m为1是表示它是定时器0的中断函数,
如void time0() interrupt 1{}
那么后面的using n 又是什么意思呢?在正在执行一个特定任务时,有更紧急的事情需要CPU来处理,涉及到中断优先权。高优先权中断低优先权正在处理的程序,所以最好给每个优先程序分配不同的寄存器组。
CPU正在处理某个事件,突然另外一个事件需要处理,于是进入中断后,而你不想将现在执行的程序的各寄存器状态入栈,那么可以把这个中断程序放入另一个寄存器组,如切换到1组,然后退出中断时,再切回到0组(原来的程序在0组)。
为了更好的了解这里意思,你可以看看工作寄存器组的作用是什么。
下面的注意事项转自网络上其他朋友的文章(整理下,重复的去掉了,写的非常好):
(1)中断函数不能进行参数传递
(2)中断函数没有返回值
(3)在任何情况下都不能直接调用中断函数
(4)中断函数使用浮点运算要保存浮点寄存器的状态。
(5)如果在中断函数中调用了其它函数,则被调用函数所使用的寄存器必须与中断函数相同,被调函数最好设置为可重入的。
(6)C51编译器对中断函数编译时会自动在程序开始和结束处加上相应的内容,具体如下:在程序开始处对ACC、B、DPH、DPL和PSW入栈,结束时出栈。中断函数未加using n修饰符的,开始时还要将R0~R1入栈,结束时出栈。如中断函数加using n修饰符,则在开始将PSW入栈后还要修改PSW中的工作寄存器组选择位。
(7)C51编译器从绝对地址8m+3处产生一个中断向量,其中m为中断号,也即interrupt后面的数字。该向量包含一个到中断函数入口地址的绝对跳转。
(8)中断函数最好写在文件的尾部,并且禁止使用extern存储类型说明。防止其它程序调用。
(9)在设计中断时,要注意的是哪些功能应该放在中断程序中,哪些功能应该放在主程序中。一般来说中断服务程序应该做最少量的工作,这样做有很多好处。首先系统对中断的反应面更宽了,有些系统如果丢失中断或对中断反应太慢将产生十分严重的后果,这时有充足的时间等待中断是十分重要的。其次它可使中断服务程序的结构简单,不容易出错。中断程序中放入的东西越多,他们之间越容易起冲突。简化中断服务程序意味着软件中将有更多的代码段,但可把这些都放入主程序中。中断服务程序的设计对系统的成败有至关重要的作用,要仔细考虑各中断之间的关系和每个中断执行的时间,特别要注意那些对同一个数据进行操作的ISR.
干货|一文读懂单片机里面的“中断”优先级
中断优先级的内容,有一般紧急的中断,有特别紧急的中断,这取决于具体的系统设计,这就涉及到中断优先级和中断嵌套的概念,今天先简单介绍一下相关寄存器,不做例程说明。
中断的产生背景,实际生活当中还有更复杂的,比如我正在看电视,这个时候来电话了,我要进入接电话的“中断”程序当中去,就在接电话的同时,听到了水开的声音,水开的“中断”也发生了,我们就必须要放下手上的电话,先把煤气关掉,然后再回来听电话,最后听完了电话再看电视,这里就产生了一个优先级的问题。
还有一种情况,我们在看电视的时候,这个时候听到水开的声音,水开的“中断”发生了,我们要进入关煤气的“中断”程序当中,而在关煤气的同时,电话声音响了,而这个时候,我们的处理方式是先把煤气关闭,再去接听电话,最后再看电视。
从这两个过程中,我们可以得到一个结论,就是最最紧急的事情,一旦发生后,我们不管当时处在哪个“程序”当中,我们必须先去处理最最紧急的事情,处理完毕后再去解决其它事情。
在我们的单片机程序当中有时候也是这样的,有一般紧急的中断,有特别紧急的中断,这取决于具体的系统设计,这就涉及到中断优先级和中断嵌套的概念,今天先简单介绍一下相关寄存器,不做例程说明。
中断优先级有两种,一种是抢占优先级,一种是固有优先级,先介绍抢占优先级。来看表1和表2。
表1: IP——中断优先级寄存器的位分配(地址0xB8、可位寻址)
表2: IP——中断优先级寄存器的位描述
IP 这个寄存器的每一位,表示对应中断的抢占优先级,每一位的复位值都是 0,当我们把某一位设置为 1 的时候,这一位的优先级就比其它位的优先级高了。
比如我们设置了 PT0位为 1 后,当单片机在主循环或者任何其它中断程序中执行时,一旦定时器 T0 发生中断,作为更高的优先级,程序马上就会跑到 T0 的中断程序中来执行。
反过来,当单片机正在 T0中断程序中执行时,如果有其它中断发生了,还是会继续执行 T0 中断程序,直到把 T0 中的中断程序执行完毕以后,才会去执行其它中断程序。
当进入低优先级中断中执行时,如又发生了高优先级的中断,则立刻进入高优先级中断执行,处理完高优先级级中断后,再返回处理低优先级中断,这个过程就叫做中断嵌套,也称为抢占。
所以抢占优先级的概念就是,优先级高的中断可以打断优先级低的中断的执行,从而形成嵌套。当然反过来,优先级低的中断是不能打断优先级高的中断的。
表3: 中断查询序列
那么既然有抢占优先级,自然就也有非抢占优先级了,也称为固有优先级。在表3中的最后一列给出的就是固有优先级,请注意,在中断优先级的编号中,一般都是数字越小优先级越高。
从表3中可以看到一共有 1~6 共 6 级的优先级,这里的优先级与抢占优先级的一个不同点就是,它不具有抢占的特性,也就是说即使在低优先级中断执行过程中又发生了高优先级的中断,那么这个高优先级的中断也只能等到低优先级中断执行完后才能得到响应。既然不能抢占,那么这个优先级有什么用呢?
答案是多个中断同时存在时的仲裁。比如说有多个中断同时发生了,当然实际上发生这种情况的概率很低,但另外一种情况就常见的多了,那就是出于某种原因我们暂时关闭了总中断,即 EA=0,执行完一段代码后又重新使能了总中断,即 EA=1,那么在这段时间里就很可能有多个中断都发生了,但因为总中断是关闭的,所以它们当时都得不到响应,而当总中断再次使能后,它们就会在同时请求响应了,很明显,这时也必需有个先后顺序才行,这就是非抢占优先级的作用了——如表3中,谁优先级最高先响应谁,然后按编号排队,依次得到响应。
抢占优先级和非抢占优先级的协同,可以使单片机中断系统有条不紊的工作,既不会无休止的嵌套,又可以保证必要时紧急任务得到优先处理。在后续的学习过程中,中断系统会与我们如影随形,处处都有它的身影,随着学习的深入,相信你对它的理解也会更加的深入。
相关问答
中断 服务 函数 的格式, 单片机 的知识点?首先可以肯定,中断服务函数可以写在其他文件中,并不一定要放在main.c中。中断服务函数如果有特定的关键字修饰,比如keilc51用interrupt,不仅可以放在任意文...
pic18f45k22 单片机 有几个 中断函数 ?你指的是响应中断时进入的函数,中断服务函数,这个型号的有两个一个是高优先级进入一个是低优先级进入你指的是响应中断时进入的函数,中断服务函数,这个型号的...
51 单片机中断 如何关闭?51的串口中断,接收和发送是共用一个中断向量的,没法单独关闭。一般在中断服务函数中检测TI标志并及时清零就可以了。1、在中断服务程序里,关闭中断允许标志当...
stm32 单片机 如何实现在外部 中断函数 ?一个间的外部中断程序控制LED亮灭首先,我们要了解中断是怎么执行的,打个比方,现在小明在家看电视,这时卧室里的电话响了,听到电话响的小明就暂停电视跑去卧...
MCS-51系列 单片机 的 中断 系统分为几个优先级?怎么设定?-ZOL问答3条回答:8051单片机的中断系统总共有两个优先级,有关设定在寄存器IE中,搞三位不用管,低5位分别是PX0,PT0,PX1,PT1,PS(由低到高),通过设置他们的状态0或者1,就可...
请说明51 单片机 中的 中断 入口地址的含义?1,51单片机中的中断入口地址的含义就是去执行中断连接的程序,一般在程序的末尾段。2,若51单片机使用C语言编程,51单片机中断号的排列顺序是按中断向量地址由...
51 单片机 有哪几个 中断源 ?各中断标志是如何产生的?当中断响应...51单片机有哪几个中断源?各中断标志是如何产生的?当中断响应后,中断标志是如何消除的?当CPU响应共5条回答1.2万浏览串口定时器01外部中断0.1中断标志除...
关于51 单片机中断函数 如何加入到主函数里面?当然不是。首先,中断函数分两部分:一部分是初始化部分,另一部分是中断触发后执行的部分。其次,先说初始化部分,初始化部分要么写在主函数里面,要么写成...
单片机中断 机制有哪些?谢邀!对于单片机的中断分这么几类,从中断源分部布上可分外部中断和内部中断、硬件中断及软件中断,芯片的开发者已给各类芯片的中断都有赋予各自的向量地址入...
单片机 标准 函数 概念?在单片机编程中,标准函数是指由单片机厂商提供的一组预定义函数,用于简化常见任务的实现。这些函数通常包含在单片机的开发环境或库文件中,可以直接调用和使用...