76
1 5 : 1 : 5 1/76 第第第 第第第第第第 第第第第第第第第第第第第第第第第第第第 第第第第第第第第 第第第第第第第第第第第第第第第第

第六章 中 断 本章学习目标 掌握单片机中断系统 掌握单片机中断处理过程 掌握中断程序设计 理解中断使用过程中需要注意的问题

  • Upload
    keefe

  • View
    224

  • Download
    0

Embed Size (px)

DESCRIPTION

第六章 中 断 本章学习目标 掌握单片机中断系统 掌握单片机中断处理过程 掌握中断程序设计 理解中断使用过程中需要注意的问题. §6.1 中断的概念. 中断是计算机中的一个很重要的技术 , 它既和硬件 有关,也和软件有关。正是因为有了中断技术,才使得 计算机的控制功能更加灵活、效率更高、使得计算机的 发展和应用大大的前进了一步,中断功能的强弱已成为 衡量一台计算机功能完善与否的重要指标。例如,下面 的情况下,就需要采用中断技术。 当计算机正在正常运行一个程序段的时候,如果有一个紧急的事件出现,又必须要立即处理这个紧急的事件; - PowerPoint PPT Presentation

Citation preview

15:11:55 1/76

第六章 中 断

本章学习目标掌握单片机中断系统掌握单片机中断处理过程掌握中断程序设计理解中断使用过程中需要注意的问题

15:11:55 2/76

§6.1 中断的概念 中断是计算机中的一个很重要的技术 , 它既

和硬件有关,也和软件有关。正是因为有了中断技术,才使得计算机的控制功能更加灵活、效率更高、使得计算机的发展和应用大大的前进了一步,中断功能的强弱已成为衡量一台计算机功能完善与否的重要指标。例如,下面的情况下,就需要采用中断技术。

当计算机正在正常运行一个程序段的时候,如果有一个紧急的事件出现,又必须要立即处理这个紧急的事件;计算机一边工作一边随时准备处理一个事件,但又不确定该事件出现的确切时刻,像处理防火防盗事件一样。

15:11:55 3/76

计算机采用中断技术,大大提高了工作效率和

处理问题的灵活性,主要表现在 3 个方面:可及时处理控制系统中许多随机发生的事件;较好的解决了快速 CPU 和慢速外设之间的矛盾,可使 CPU 和外设并行工作;具备了处理故障的能力,提高了系统自身的可靠性。

15:11:55 4/76

中断类似于主程序调用子程序,但它们又有区别,各自的主要特点如表所示。

中 断 调用子程序

产生时刻是随机的 程序中事先安排好的

既保护断点(自动),又保护现场(程序) 可只保护断点(自动)

处理程序的入口地址是单片机硬件确定的,用户不能改变

子程序的入口地址是程序编排的

表 6-1 中断和调用子程序之间的主要区别

15:11:55 5/76

一、中断源及其优先级管理1 、中断源 中断源是指能发出中断请求,引起中断的装置或事件。

STC15F2K60S2 单片机提供 14 个中断请求源 :5 个外部中断请求3 个片内定时 / 计数器溢出中断请求2 个片内异步串行口( UART )中断请求1 个 ADC 中断1 个 SPI 中断1 个低电压检测中断1 个 PCA 中断。

§6.2 单片机的中断系统及其管理

15:11:55 6/76

I E0

I E1

Ti mer0/ TF0

Ti mer1/ TF1

RI

TI

I NT0

I NT1

CF

EX0

ET0

EX1

ET1

ES

EA

EADC

I E、I NT_CLKO、I E2 I P、I P2

最低优先级中断

CCF0

CCF1EPCA

ECF

ECCF0

ECCF1

中断查询次序

ADC_FLAG

ES2

LVDFELVD

ESPI

SPI F

中断允许控制寄存器

中断优先级控制寄存器

EX2

EX3

ET2

EX4

表示上升沿和下降沿均可中断

TCON. 0/ I T0=0

TCON. 0/ I T0=1

TCON. 2/ I T1=1

TCON. 2/ I T1=0

串口1/ S1

CCF2ECCF2

串口2/S2S2RIS2TI

I NT2

I NT3

T2

I NT4

PX0

PT0

PX1

PT1

PS

PADC

PLVD

PPCA

PS2

PSPI

0

1

0

0

0

0

0

0

0

0

0

1

1

1

1

1

1

1

1

1

最高优先级中断

无中断优先级控制位中断优先级固定为0级

无中断优先级控制位

无中断优先级控制位

无中断优先级控制位

中断优先级固定为0级

中断优先级固定为0级

中断优先级固定为0级

≥ 1

≥ 1

≥ 1

&

&

&

&

图 6-1 STC15F2K60S2 单片机的

中断系统

15:11:55 7/76

( 1 )定时 / 计数器 T0 和 T1 的控制寄存器 TCON

该寄存器同时锁存了 T0 和 T1 的溢出中断请求标志及外部中断请求标志。TCON (地址为 88H ,复位值为 00H )的各位定义如下:

位号 D7 D6 D5 D4 D3 D2 D1 D0

位名称 TF1 TR1 TF0 TR0 IE1 IT1 IE0 IT0

15:11:55 8/76

位号 D7 D6 D5 D4 D3 D2 D1 D0

位名称 TF1 TR1 TF0 TR0 IE1 IT1 IE0 IT0

1 ) IT0 :外部中断触发方式控制位。可由软件置 1或清“ 0” 。

0 :电平触发方式。当输入低电平时,置位 IE0 。 1 :边沿触发方式。输入脚上电平由高到低的负跳变时,置位 IE0 。

2 ) IT1 :外部中断触发方式控制位,与 IT0 类似。

15:11:55 9/76

3 ) IE0 :外部中断 0 请求标志。当 IT0=0 即电平触发方式时,在每个指令周期的最后一个时钟周期采样 IT0 ,若为低电平,由硬件置位 IE0 。当 IT0=1 即边沿触发方式时,当某个指令周期的最后一个时钟周期采样到为高电平,下一个指令周期的最后一个时钟周期采样到为低电平时,由硬件置位 IE0 。IE0=1 表示向 CPU 请求中断。当 CPU 响应中断转向中断服务程序时,由硬件自动清 0 中断标志。

4 ) IE1 :外部中断 1 请求标志,其意义和 IE0 相同。

位号 D7 D6 D5 D4 D3 D2 D1 D0

位名称 TF1 TR1 TF0 TR0 IE1 IT1 IE0 IT0

15:11:55 10/76

4 ) TR0 :定时 / 计数器 T0 启动 / 停止控制位。5 ) TR1 :定时 / 计数器 T1 启动 / 停止控制位,详细介绍,请参考“定时器”一章。

位号 D7 D6 D5 D4 D3 D2 D1 D0

位名称 TF1 TR1 TF0 TR0 IE1 IT1 IE0 IT0

15:11:55 11/76

6 ) TF0 :定时 / 计数器 T0 溢出中断标志。 T0 启动计数后,从初值开始加 1 计数。当计数器产生进位时,由硬件置 TF0 为 1 ,向 CPU 申请中断,若 CPU 响应中断,在进入中断服务后, CPU 自动将 TF0 清 0 。 TF0 也可用软件清 0 (查询方式)。

7 ) TF1 :定时 / 计数器 T1 的中断标志,功能和TF0 类似。

位号 D7 D6 D5 D4 D3 D2 D1 D0

位名称 TF1 TR1 TF0 TR0 IE1 IT1 IE0 IT0

15:11:55 12/76

( 2 )串行口 1 控制寄存器 SCON

用于对串行口 1 的工作方式进行控制,其最低两位锁存串行口 1 发送中断标志 TI 和接收中断标志RI 。SCON (地址为 98H ,复位值为 00H )各位的定义如下:位号 D7 D6 D5 D4 D3 D2 D1 D0

位名称 SM0/FE SM1 SM2 REN TB8 RB8 TI RI

TI 或 RI 只要有一个为 1 ,表示串行口申请中断

15:11:55 13/76

1 ) RI :串行口 1 接收中断标志。 RI=1 表示串行口 1 接收器已经接收到数据,所以向

CPU 申请中断,以便将接收到的数据存到预先安排好的数据区。 RI 必须由用户在中断处理程序中用指令清 0 。

2 ) TI :串行口 1 发送中断标志。 TI=1 表示串行口发送器已经发送完上一个数据,所

以向 CPU 申请中断,以便发送下一个数据。 TI 必须由用户在中断处理程序中用指令清 0 。

15:11:55 14/76

( 3 )串口 2 控制寄存器 S2CON

寄存器 S2CON (地址为 9AH ,复位值为 00H )用于确定串口 2 的操作方式和控制串口 2的某些功能,并设有接收和发送中断标志( S2RI 及 S2TI )位。S2CON 各位的定义如下:

位号 D7 D 6 D 5 D 4 D 3 D 2 D 1 D 0

位名称 S2SM0 S2SM1 S2SM2 S2REN S2TB8 S2RB8 S2TI S2RI

15:11:55 15/76

S2TI 和 S2RI 是串口 2 的发送中断标志和接收中断标志,与寄存器 SCON 对应位的含义和功能类似,在此,不做详细描述。

位号 D7 D 6 D 5 D 4 D 3 D 2 D 1 D 0

位名称 S2SM0 S2SM1 S2SM2 S2REN S2TB8 S2RB8 S2TI S2RI

15:11:55 16/76

( 4 )电源控制寄存器 PCON

电源控制寄存器 PCON (地址为 87H ,复位值为 30H )寄存器的各位定义如下:

位号 D7 D6 D5 D4 D3 D2 D1 D0

位名称 SMOD SMOD0 LVDF POF GF1 GF0 PD IDL

与中断有关的位是 LVDF 。 LVDF 是低电压检测标志位,同时也是低电压检测中断请求标志位。

15:11:55 17/76

( 5 ) PCA 控制寄存器 CCON

CCON (地址为 D8H ,复位值为 00xx x000B

位号 D7 D6 D5 D4 D3 D2 D1 D0

位名称 CF CR - - - CCF2 CCF1 CCF0

1 ) CF : PCA 计数器溢出标志位。 当 PCA 计数器溢出时, CF 由硬件置位。如 CMOD 寄存器的 ECF 位置位, CF 标志可用来产生中断。CF 位可通过硬件或软件置位,但只能通过软件清 0 。2 ) CCF2/CCF1/CCF0 : PCA 各个模块的标志。

15:11:55 18/76

( 6 ) SPI 状态寄存器 SPSTAT

SPSTAT (地址为 CDH ,复位值为 00xx xxxxB )各位的定义如下:

位号 D7 D6 D5 D4 D3 D2 D1 D0

位名称 SPIF WCOL - - - - - -

15:11:55 19/76

SPIF 是 SPI传输完成标志。 当一次传输完成时, SPIF被置位。此时,如果 SPI 中断被打开( ESPI=1 , EA=1 ),将产生中断。 SPIF 标志通过软件向其写入 1而清 0 。WCOL 位的作用以及 SPI模块在 “数据通信”一章中介绍。

位号 D7 D6 D5 D4 D3 D2 D1 D0

位名称 SPIF WCOL - - - - - -

15:11:55 20/76

( 7 ) ADC 控制寄存器 ADC_CONTR

ADC_CONTR (地址为 C5H ,复位值为 0XX00000B )各位的定义如下:

位号 D7 D6 D5 D4 D3 D2 D1 D0

位名称 ADC_POWER SPEED1 SPEED0 ADC_FLAG ADC_START CHS2 CHS1 CHS0

位 ADC_FLAG 是 A/D 转换结束标志。 A/D 转换完成后, ADC_FLAG=1 。此时,若允许 A/D 转换中断( EADC=1 , EA=1 ),则由该位申请产生中断。也可由软件查询该标志位判断A/D 转换是否结束, ADC_FLAG 一定要软件清“ 0”

15:11:55 21/76

2 、中断的允许、禁止及优先级( 1 )中断的允许和禁止 STC15F2K60S2 单片机中没有专门的开中断和关中断指令,中断的允许和禁止是通过设置 IE 、IE2 和外部中断允许和时钟输出寄存器 INT_CLKO 的相应位实现的。

单片机对中断源的允许和禁止由两级控制组成,即总控制和对每个中断源的分别控制。

15:11:55 22/76

1 )中断允许寄存器 IE

中断允许寄存器 IE (地址为 A8H ,复位值为 00H )

位号 D7 D6 D5 D4 D3 D2 D1 D0

位名称 EA ELVD EADC ES ET1 EX1 ET0 EX0

1 ) EA :中断允许总控制位。 0 :禁止中断系统,所有中断源的中断请求均被禁止,称为关中断。 1 :允许中断系统,所有中断源的中断请求均可以被允许,称为开中断;某一个中断源的请求是否允许,还要由该中断源所对应的中断允许控制位决定。

15:11:55 23/76

2 ) ELVD :低电压检测中断允许控制位。 1 :允许低电压检测中断; 0 :禁止低电压检测中断。3 ) EADC : ADC 中断允许控制位。 1 :允许 ADC 中断; 0 :禁止 ADC 中断。

位号 D7 D6 D5 D4 D3 D2 D1 D0

位名称 EA ELVD EADC ES ET1 EX1 ET0 EX0

15:11:55 24/76

4 ) ES :串行口 1 中断允许控制位。 1 :允许串行口 1 中断; 0 :禁止串行口 1 中断。5 ) ET1 :定时器 1 中断允许控制位。 1 :允许定时器 1 中断; 0 :禁止定时器 1 中断。

位号 D7 D6 D5 D4 D3 D2 D1 D0

位名称 EA ELVD EADC ES ET1 EX1 ET0 EX0

15:11:55 25/76

6 ) EXl :外部中断中断允许控制位。 1 :允许外部中断 1 中断; 0 :禁止外部中断 1 中断。7 ) ET0 :定时器 0 中断允许控制位。 1 :允许定时器 0 中断; 0 :禁止定时器 0 中断。8 ) EX0 :外部中断源中断允许控制位。 1 :允许外部中断 0 中断; 0 :禁止外部中断 0 中断。

位号 D7 D6 D5 D4 D3 D2 D1 D0

位名称 EA ELVD EADC ES ET1 EX1 ET0 EX0

15:11:55 26/76

2 )中断允许寄存器 IE2

(地址为 AFH ,复位值为 XXXXXX00B )位号 D7 D6 D5 D4 D3 D2 D1 D0

位名称 ET2 ESPI ES2

① ET2 :定时器 2 的中断允许位。 1 :允许定时器 2 产生中断; 0 :禁止定时器 2 产生中断。

② ESPI : SPI 中断允许控制位。 1 :允许 SPI 中断; 0 :禁止 SPI 中断。

③ ES2 :串行口 2 中断允许控制位。 1 :允许串行口 2 中断; 0 :禁止串行口 2 中断。

15:11:55 27/76

3 )外部中断使能和时钟输出寄存器 INT_CLKO

外部中断使能和时钟输出寄存器 INT_CLKO(地址为 8FH ,复位值为 X0000000B ,不能进行位寻址)各位的定义如下:

位号 D7 D6 D5 D4 D3 D2 D1 D0

位名称 - EX4 EX3 EX2 LVD_WAKE T2CLKO T1CLKO T0CLKO

15:11:55 28/76

①EX4 :外部中断 4 中断允许位。 1 :允许外部中断 4 中断; 0 :禁止外部中断 4 中断。外部中断 4 下降沿触发。②EX3 :外部中断 3 中断允许位。 1 :允许外部中断 3 中断; 0 :禁止外部中断 3 中断。外部中断 3 下降沿触发。③EX2 :外部中断 2 中断允许位。 1 :允许外部中断 2 中断; 0 :禁止外部中断 2 中断。外部中断 2 下降沿触发。

15:11:55 29/76

4 ) PCA比较 /捕获寄存器 CCAPMn ( n=0,1,2, 下同。地址分别对应 DAH, DBH 和 DCH ,复位值均为 X0000000B ),各位的定义如下:

位号 D7 D6 D5 D4 D3 D2 D1 D0

位名称- ECOMn CAPPn CAPNn MATn TOGn PWMn ECCFn

ECCFn :使能 CCFn 中断。寄存器 CCON 的比较 / 捕获标志 CCFn 用来产生中断。

15:11:55 30/76

5 ) PCA 工作模式寄存器( CMOD )CMOD (地址为 D9H ,复位值为 0XXX0000B )各位

的定义如下:

ECF : PCA 计数器溢出中断使能位。 ECF=1时,允许寄存器 CCON 中 CF 位的中断。 ECF=0 时,禁止寄存器 CCON 中 CF 位的中断。

位号 D7 D6 D5 D4 D3 D2 D1 D0

位名称 CIDL - - - CPS2 CPS1 CPS0 ECF

15:11:55 31/76

STC15F2K60S2 单片机复位后,各中断允许寄存器控制位均被清“ 0” ,即禁止所有中断。如果需要允许某些中断,可在程序中将相应中断控制位置为 1 。用户可通过对 IE 、 IE2 和 INT_CLKO 中相应的位进行置 1 或清 0 的操作来允许或禁止各中断源的中断申请。禁止某个中断源申请中断,也称为屏蔽某个中断源。欲使某中断源允许中断,必须同时使 EA=1 ,即同时使 CPU允许中断。所以 EA 相当于中断允许的“总开关”。

15:11:55 32/76

( 2 )中断的优先级

外部中断 2 、外部中断 3 、定时器 T2 和外部中断 4 ,不能设置为高优先级,其他中断源通过特殊功能寄存器( IP 和 IP2 )中的相应位,可设为高、低二级优先级,实现二级中断嵌套,与传统 8051 单片机两级中断优先级完全兼容。

15:11:55 33/76

STC15F2K60S2 单片机对中断优先级的处理原则

低优先级中断可被高优先级中断所中断,反之不能。任何一种中断(不管是高优先级还是低优先级),一旦得到响应,不会再被它的同级中断所中断。

15:11:55 34/76

同一优先级的中断源同时申请中断时,按照事先约定的硬件查询顺序响应中断。这相当于在每个优先级内,还同时存在另一个辅助优先级结构(称为默认的优先级)STC15F2K60S2 单片机各中断默认的优先级如表 6-2 所示。其中,默认中断优先级次序号越小,优先级越高。

15:11:55 35/76

1 )中断优先级寄存器 IP

中断优先级寄存器 IP (地址为 B8H ,复位值为00H )各位的定义如下:

位号 D7 D6 D5 D4 D3 D2 D1 D0

位名称 PPCA

PLVD PADC PS PT1 PX1 PT0 PX0

每一位对应其相应的中断源的优先级控制位。 1 :高优先级; 0 :低优先级。

15:11:55 36/76

2 )第二中断优先级低字节寄存器 IP2

第二中断优先级低字节寄存器 IP2 (地址为 B5H ,复位值为 XXXXXX00B ):

位号 D7 D6 D5 D4 D3 D2 D1 D0

位名称 PSPI PS2

1 ) PSPI : SPI 中断优先级控制位。 1 : SPI 中断为高优先级; 0 : SPI 中断为低优先级。2 ) PS2 :串口 2 中断优先级控制位。 1 :串口 2 中断为高优先级; 0 :串口 2 中断为低优先级。

15:11:55 37/76

IP 、 IP2 一起确定 STC15F2K60S2 单片机的二个中断优先级 。

15:11:55 38/76

例如, 如果要允许外部中断 0 中断,需要将 EX0 和 E

A

都置 1 。 如果要允许 A/D转换中断,则需要将 EADC和

EA都置 1 。

15:11:55 39/76

二、单片机中断处理过程1 、单片机响应中断的条件和过程 当中断源向 CPU 发出中断请求时,如果中断的条件满足, CPU 将进入中断响应周期。单片机响应中断的条件是:

中断源有请求。相应的中断允许位设置为 1 。无同级或高级中断正在处理;CPU 中断开放( EA=1 )。

15:11:55 40/76

在每个指令周期的最后一个时钟周期, CPU对各中断源采样,并设置相应的中断标志位。CPU 在下一个指令周期的最后一个时钟周期按优先级顺序查询各中断标志,如查到某个中断标志为 1 ,将在下一个指令周期按优先级的高低顺序响应中断并进行处理。

15:11:55 41/76

CPU 响应中断时,将执行如下操作:当前正被执行的指令执行完毕;PC 值被压入堆栈;现场保护;阻止同级别其他中断;将中断服务程序的入口地址(中断向量地址)装载到程序计数器 PC ;执行相应的中断服务程序。

15:11:55 42/76

每个中断服务程序的入口地址之间只相隔 8 个单元,一般中断服务程序的长度都超过 8 个字节,这时可以将中断服务程序存放到存储器的其他区域,然后在中断入口处安排一条转移指令 LJMP ,转向中断服务程序。例如:

ORG 0003H ; 外部中断 0 入口地址 LJMP X0_ISR

··· ; 其他程序代码 X0_ISR: ; 外部中断 0 服务程序

··· RETI

15:11:55 43/76

使用 C语言编写单片机中断应用程序时,用中断号

区分每一个中断。例如,

void X0_ISR(void) interrupt 0{} // 外部中断 0 中断函数void T0_ISR (void) interrupt 1{} // 定时器 T0 中断函数void X1_ISR(void) interrupt 2{} // 外部中断 1 中断函数void T1_ISR (void) interrupt 3{} // 定时器 T1 中断函数void UART1_ISR (void) interrupt 4{} // 串行口 1 中断函数void ADC_ISR (void) interrupt 5{} //ADC 中断函数void LVD_ISR (void) interrupt 6{} // 低电压检测 LVD 中断函数

15:11:55 44/76

void PCA_ISR (void) interrupt 7{} //PCA 中断函数void UART2_ISR (void) interrupt 8{} // 串行口 2 中断函数void SPI_ISR (void) interrupt 9{} //SPI通信中断函数void X2_ISR(void) interrupt 10{} // 外部中断 2 中断函数void X3_ISR(void) interrupt 11{} // 外部中断 3 中断函数void T2_ISR (void) interrupt 12{} // 定时器 T2 中断函数void X4_ISR(void) interrupt 16{} // 外部中断 4 中断函数

15:11:55 45/76

在程序的运行过程中,并不是任何时刻都可以响应中断请求。出现下列情况时, CPU 不会响应中断请求:

中断允许总控制位 EA = 0 或发出中断请求的中断源所对应的中断允许控制位为 0 。CPU 正在执行一个同级或高级的中断服务程序。当前执行指令的时刻不是指令周期的最后一个时钟周期。正在执行的指令是中断返回指令 RETI 或者是访问 IE 或 IP 的指令时, CPU至少要再执行一条指令才能响应中断请求。

15:11:55 46/76

2 、中断服务中断服务程序从入口地址开始执行,直到执行返回指令 RETI 为止。 RETI 指令表示中断服务程序的结束。中断服务程序由四个部分组成,即保护现场、中断服务、恢复现场以及中断返回。由于在主程序中一般都会用到累加器 A 和程序状态字寄存器 PSW ,所以在现场保护时一般都需要保护 A 和 PSW ,其他寄存器根据使用情况决定是否需要保护。在 C语言程序中不需要进行现场保护。

15:11:55 47/76

在编写中断服务程序时应注意以下两点:单片机响应中断后,不会自动关闭中断系统。如果用户程序不希望出现中断嵌套,则必须在中断服务程序的开始处关闭中断,禁止更高优先级的中断请求中断当前的服务程序。为了保证保护现场和恢复现场能够连续进行,可在保护现场和恢复现场之前先关中断,当现场保护或现场恢复结束后,再根据实际需要决定是否需要开中断。

15:11:55 48/76

三、中断请求的撤除 中断源向 CPU 发出中断请求后,中断请求信号分别锁存在特殊功能寄存器中。 当某个中断源的请求被 CPU 响应后,应将相应的中断请求标志清除。 CPU 在处理中断结束并返回到主程序后,如果中断请求标志没有及时清除,会引起 CPU多次甚至反复响应该中断源的中断请求,从而使 CPU 进入死循环的现象;而撤除过早,有可能中断尚未响应,造成请求信号的丢失。所以,及时撤除中断请求是很重要的。

15:11:55 49/76

1 、定时器 / 计数器 T0 、 T1 中断请求的撤除当 CPU 响应 T0 或 T1 的中断请求后,由硬件自动清除相应的中断请求标志 TF0 或 TF1 。所以在处理定时器 / 计数器的中断时,无需关心清除中断请求标志的问题。

2 、外部中断请求的撤除CPU 响应外部中断 0 和外部中断 1 后,由硬件自动清除中断请求标志 IE0 和 IE1 。外部中断 2 、 3 和 4 的中断请求标志对用户不可见, CPU 响应外部中断 2~4 后,由硬件自动清除中断请求标志,无需用户清 0 。

15:11:55 50/76

3 、串行口中断请求的撤除 CPU 响应串行口中断后,不能由硬件自动清除串行口中断标志( UART1 为 TI 和 RI , UART2 为S2TI 和 S2RI )。由于串行口的发送中断和接收中断使用相同的入口地址,所以, CPU 响应串行中断后,首先应检测这两个中断标志位,以判断是发送中断还是接收中断。当检测结束后,应通过软件将串行口中断标志清 0 。

15:11:55 51/76

4 、 ADC 中断请求的撤除 ADC 中断请求标志位 ADC_FLAG 不能自动清除,需要在 ADC 中断服务程序中用软件将其清0 。5 、 SPI 中断请求的撤除 SPI 中断请求标志位 SPIF 不能自动清除,需要

在 SPI 中断服务程序中用软件清 0 。

15:11:55 52/76

6 、 PCA 中断请求的撤除 PCA 中断请求标志位 CF/CCF0/CCF1 不能自动

清除,需要在 PCA 中断服务程序中用软件将相应的标志位清 0 。7 、低电压检测中断请求的撤除 低电压检测中断请求标志位 LVDF 不能自动清除,需要在低电压检测中断服务程序中用软件清0 。

15:11:55 53/76

四、中断程序编程举例【例 6-1】利用 INT0 引入单脉冲,每来一个负脉冲,将连接到 P1 口的发光二极管循环点亮。解:利用的下降沿触发中断。

15:11:55 54/76

汇编语言程序如下: ORG 0000H

LJMP MAINORG 0013HLJMP INT_X1ORG 0100H

MAIN:MOV SP,#60HMOV A,#01HMOV P1,#00HSETB IT1 ; 设置下降沿触发中断SETB EX1 ; 开放外部中断 1SETB EA ; 开放总中断SJMP $ ;等待,本条指令相当于“ HERE: LJMP HERE”

INT_X1:MOV P1,ARL ARETIEND

15:11:55 55/76

对应的 C语言版本如下:#include "stc15.h" //包含寄存器定义头文件unsigned char i=0x01;void main(void){

P1=0;IT0=1;EX0=1;EA=1;while(1); //循环等待

}void X0_ISR(void) interrupt 0{

i<<=1;if (i==0) i=1; //移位 8次后, i将变为 0,因此需要重新

赋值P1=i;

}

15:11:55 56/76

【例 6-2】利用上升沿和下降沿均可触发中断的外部中断,可以检测脉冲跳变的次数,也可以检测按键的按下与弹起操作。下面的例子可以统计从 INT1 引脚输入脉冲的跳变次数。

15:11:55 57/76

汇编语言程序如下: ; 主程序: ORG 0000H ; 主程序入口 LJMP MAIN ORG 0013H ; 外部中断 1 入口 LJMP INT_X1 ORG 0100H ; 主程序MAIN: MOV SP,#7FH

CLR A ;假设脉冲的跳变次数保存在累加器 ACC 中 CLR IT1 ; 设外部中断 1 为上升沿和下降沿均可触发的方

式 SETB EX1 ; 外部中断 1 开中断 SETB EA ;CPU 开中断 SJMP $ ;原地踏步,等待中断发生 ; 外部中断 1 处理子程序:INT_X1: INC A ; 统计脉冲跳变次数

; 可以在这个地方读入 INT1/P3.3 引脚的电平,; 从而判断本次中断是上升沿中断还是下降沿中

RETI ;返回 END

15:11:55 58/76

对应的 C语言程序如下:#include “stc15.h” //包含寄存器定义头文件unsigned char p_cnt=0; // 统计脉冲跳变次数变量void main (void) {

IT1=0; // 外部中断 1 为上升沿和下降沿均可触发的方式

EX1=1; //允许外部中断 1EA =1; //允许总的中断while(1); //等待中断

}void X1_ISR (void) interrupt 2 // 外部中断 1函数{

p_cnt++; // 统计脉冲跳变次数}

15:11:55 59/76

【例 6-3】外部中断 2 的使用。外部中断 2~4 的使用方法与外部中断 0 和 1的使用方法类似,区别在于外部中断 2~4 只能是下降沿触发,并且,要注意开放中断的方法。

15:11:55 60/76

$INCLUDE (STC15.INC) ;包含 STC15F2K60S2 寄存器定义文件 ; 主程序: ORG 0000H ; 主程序入口 LJMP MAIN ORG 0053H ; 外部中断 2 入口 LJMP INT_X2 ORG 0100H ; 主程序MAIN: MOV SP,#7FH ORL INT_CLKO, #10H ; 开放外部中断 2 SETB EA ;CPU 开中断 SJMP $ ;原地踏步,等待中断发生 ; 外部中断 2 处理子程序:INT_X2:

; 在这里编写中断处理程序 RETI ;返回 END

15:11:55 61/76

对应的 C语言程序如下:#include “stc15.h” //包含寄存器定义头文

件void main (void) {

INT_CLKO |= 0x10; //允许外部中断 2EA =1; //允许总的中断while(1); //等待中断

}void X2_ISR (void) interrupt 10 // 外部中断 2函数{

// 在这里编写中断处理程序}

15:11:55 62/76

【例 6-4】外部中断源扩展。 当外部中断源多于两个时,可采用硬件申请与软件查询结合的方法,把多个中断源通过硬件“线或”或经或非门引入外中断源输入端(或),同时又连到某 I/O 口。这样,每个源都可能引起中断,在中断服务程序中通过软件查询便可确定哪一个是正在申请的中断源,其查询的次序则由中断源优先级决定,这就可实现多个外部中断源的扩展。

15:11:55 63/76

如图所示的中断线路可实现系统的故障显示,当系统的各部分工作正常时, 4 个故障源输入端全为低电平,指示灯全熄灭。若当某部分出现故障,则对应的输入线由低电平变为高电平,从而引起单片机中断,试设计判定故障源的程序,并进行相应的灯光显示。

STC15F2K60S2

P2. 0

P2. 2

P2. 1

P2. 3

LED2

LED3

R0

R1

R2

R3

+5VLED0

LED1

I NT0

P1. 0

P1. 2P1. 3

P1. 1

故障信号输入端

≥ 1

图 6-3 利用中断线路显示系统故障

15:11:55 64/76

解:通过或非门,将上升沿转换为下降沿,利用下降沿中断方式实现。

ORG 0000HLJMP MAIN ;转主程序ORG 0003HLJMP INT_X0 ;转中断服务程序ORG 0100H

MAIN: MOV SP,#7FHMOV P2,#0FFH ; 指示灯全熄灭

SETB IT0 ; 为边沿触发中断方式SETB EX0 ;允许中断SETB EA ;CPU 开中断SJMP $ ;等待中断

INT_X0: MOV A,P1 ; 对应关系: LED0--P2.0--P1.0 ,其他类推

CPL AANL A,#0FHMOV P2,A

RETIEND

15:11:55 65/76

对应的 C语言版程序:#include “stc15.h” //包含寄存器定义头文件void main (void) {

unsigned char i;P2=0x0f; //熄灭所有的指示灯IT0=1; //外部中断 0 为下降沿触发

方式EX0=1; //允许外部中断 0EA =1; //允许总的中断while(1); //等待中断

}void X0_ISR (void) interrupt 0 //外部中断函数{

P2=~P1;}

15:11:55 66/76

五、中断使用过程中需要注意的问题 在嵌入式系统中,中断是一种很有效的事件

处理方式。但是,如果使用中断不当,往往会出现一些意想不到的结果。为了获得正确的结果可能要花费大量的调试时间,而且中断复位子程序的错误是比较难于被发现和纠正的。为了避免发生类似的问题,下面介绍中断使用过程中需要注意的问题。

15:11:55 67/76

1 、寄存器保护由于中断请求的发生时刻是随机的,所以在主程序的

执行过程中,在任何地方都有可能发生中断请求并进入中断处理程序,因此,必须保证在任何时候都要做好中断现场的保护工作。例如,主程序是:

CLR CMOV A,#25HADDC A,#10H

……中断处理程序是:

MOV A,#0FFH ADD A,#41H

RETI

15:11:55 68/76

例如,在中断处理程序中应当修改为类似于下面的代码:PUSH ACC ;保护现场PUSH PSW

MOV A,#0FFH

ADD A,#41H

MOV 30H,A ; 将运算结果保存在 30H 中POP PSW ;恢复现场POP ACC

RETI

15:11:55 69/76

结论 通常情况下,在中断处理子程序中,需要保护那些在主程序中用到、而其中的数值在从中断返回后还需要继续使用的、因而不应被中断处理子程序修改内容的寄存器。例如,如果在主程序中用到DPTR ,并且不想被别的子程序修改内容,在中断处理程序中也用到 DPTR ,此时,就应该在中断处理子程序中使用 PUSH 和 POP 指令对 DPTR 加以保护和恢复。

15:11:55 70/76

PUSH DPH

PUSH DPL

; 其他代码 POPDPL

POPDPH

RETI

如果用 C语言编写中断处理程序,通常开发环境本身会自动进行寄存器保护,因此用户不必再编写现场保护代码。

15:11:55 71/76

2 、使用中断常出现的问题 如果使用了中断之后,整个程序出现不能正

确的执行或不能达到预期的目标的现象,应该检查与中断有关的内容,主要是在以下几个方面。

15:11:55 72/76

1 )寄存器保护 保证所有前面提及的寄存器被保护。如果忘记保护主程序使用的寄存器,可能会产生错误结果。如果寄存器未按预期的愿望改变其中的值或者出现错误的值,这很可能是因为寄存器没有被保护。

15:11:55 73/76

2 )忘记恢复被保护的值 中断返回前忘记将保护数据从堆栈中弹出。例如将 ACC 、 B 、和 PSW 压入堆栈进行保护,随后在中断返回前后忘记恢复 B 中的值,因此将

在堆栈中留下 B 中的数值作为栈顶的数值。在使

用 RETI 指令的时候,单片机将使用 B 中的值作为返回地址,将产生不可预料的混乱结果。

15:11:55 74/76

3 )中断返回使用了 RET而不是 RETI 指令。 中断返回应使用 RETI 指令,而有时错用了RET 指令。注意: RET 指令不能结束中断。通常

情况下,使用 RET 指令代替 RETI 指令会引起主

程序的混乱。若发现中断仅仅执行了一次,而无法进行第二次的中断处理,那么应该检查子程序是否正确使用了 RETI 指令。

15:11:55 75/76

4 )中断程序尽量短小 中断处理子程序应该尽量短小,这样其执行速度更快。例如,接收串行中断的处理程序应该从 SBUF 中读一个字节,并且将其复制到用户定

义的临时缓冲区中,然后退出中断程序,缓冲区中的数据的进一步处理应由主程序来处理。中断的时间消耗越少,那么在中断发生时就可以更快的响应和处理其他的中断。

15:11:55 76/76

5 )注意中断标志的清除问题 某些中断的中断标志不是在响应相应中断时

由硬件自动清除的,用户需要在中断处理程序返回前,使用指令将中断标志位清“ 0” ,否则,中

断返回后,还将产生一次新的中断。例如串行通信中断、 ADC 中断、 SPI 中断、低电压检测中断

以及 PCA 中断。