项目3外部中断
3.1项目任务和指标
本项目将完成通过按键中断控制LED灯任务。
通过本项目的实施,读者应掌握中断的概述、中断屏蔽寄存器和中断的处理方法及应用。
3.2项目的预备知识
3.2.1中断概述

CC2530有18个中断源,每个中断源都有它自己的、位于一系列特殊功能寄存器(Special Function Register,SFR)中的中断请求标志。每个中断可以分别使能或禁用。
中断是指计算机在执行期间,系统内发生任何非寻常的或非预期的急需处理的事件,使得CPU暂时中断当前正在执行的程序而转去执行相应的事件处理程序,待处理完毕后又返回原来被中断处继续执行的过程。
CC2530中断描述如表3.1所示。


表3.1CC2530中断概览



中断号码
描述
中断名称
中断向量
中断屏蔽,CPU
中断标志,CPU
0
RF发送FIFO队列空或RF接收FIFO队列溢出
RFERR
03h
IEN0.RFERRIE
TCON.RFERRIE

续表


中断号码
描述
中断名称
中断向量
中断屏蔽,CPU
中断标志,CPU
1
ADC转换结束
ADC
0Bh
IEN0.ADCIE
TCON.ADCIF
2
USART0 RX完成
URX0
13h
IEN0.URXOIE
TCON.URX0IF
3
USART1 RX完成
URX1
1Bh
IEN0.URX1IE
TCON.URX1IF
4
AES加密/解密完成
ENC
23h
IEN0.ENCIE
S0CON.ENCIF
5
睡眠定时器比较
ST
2Bh
IEN0.STIE
IRCON.STIF
6
端口2输入/USB
P2INT
33h
IEN2.P2IE
IRCON2.P2IF
7
USART0 TX完成
UTX0
3Bh
IEN2.UTX0IE
IRCON2.UTX0IF
8
DMA传送完成
DMA
43h
IEN1.DMAIE
IRCON.DMAIF
9
定时器1(16位)捕获/比较/溢出
T1
4Bh
IEN1.T1IE
IRCON.T1IF
10
定时器2
T2
53h
IEN1.T2IE
IRCON.T2IF
11
定时器3(8位)捕获/比较/溢出
T3
5Bh
IEN1.T3IE
IRCON.T3IF
12
定时器4(8位)捕获/比较/溢出
T4
63h
IEN1.T4IE
IRCON.T4IF
13
端口0输入
P0INT
6Bh
IEN1.P0IE
IRCON.P0IF
14
USART1 TX完成
UTX1
73h
IEN2.UTX1IE
IRCON2.UTX1IF
15
端口1输入
P1INT
7Bh
IEN2.P1IE
IRCON2.P1IF
16
RF通用中断
RF
83h
IEN2.RFIE
S1CON.RFIF
17
看门狗计时溢出
WDT
8Bh
IEN2.WDTIE
IRCON.WDTIF






3.2.2中断屏蔽
1. 中断屏蔽寄存器

中断屏蔽是指在中断请求产生之后,系统用软件方式有选择地封锁部分中断而允许其余部分的中断仍能得到响应。
中断使能是让中断可以被触发,可以进入中断服务程序; 如果是中断禁止状态的话,即使中断信号来了也不会触发中断,也就不会进入中断服务程序。中断使能寄存器有IEN0、IEN1和IEN2,通常用1表示中断禁止,用0表示中断使能。
每个中断请求可以通过设置中断使能寄存器IEN0、IEN1或者IEN2的中断使能位使能或禁止。某些外部设备会因为若干中断时间产生中断请求。这些中断请求可以作用于P0端口、P1端口、P2端口、DMA、计数器或者RF上。对于每个内部中断源对应的特殊功能寄存器,这些外部设备都有中断屏蔽位。寄存器IEN0、IEN1和IEN2如表3.2~表3.4所示。



表3.2IEN0——中断使能寄存器0



位
名称
复位
R/W
描述
7
EA
0
R/W
禁用所有中断

0: 无中断被禁用

1: 通过设置对应的使能位将每个中断源分别使能和禁止
6
—
0
RO
不使用,读出来是0
5
STIE
0
R/W
睡眠定时器中断使能

0: 中断禁止

1: 中断使能
4
ENCIE
0
R/W
AES加密/解密中断使能

0: 中断使能

1: 中断禁止
3
URX1IE
0
R/W
USART 1 RX中断使能

0: 中断使能

1: 中断禁止
2
URX0IE
0
R/W
USART 0 RX中断使能

0: 中断使能

1: 中断禁止
1
ADCIE
0
R/W
ADC中断使能

0: 中断使能

1: 中断禁止
0
RFERRIE
0
R/W
RF TX/RX FIFO中断使能

0: 中断使能

1: 中断禁止




表3.3IEN1——中断使能寄存器1



位
名称
复位
R/W
描述

7∶6
—
00
RO

没有使用,读出来是0
5
P0IE
0
R/W
端口0中断使能

0: 中断禁止

1: 中断使能
4
T4IE
0
R/W
定时器4中断使能

0: 中断禁止

1: 中断使能
3
T3IE
0
R/W
定时器3中断使能

0: 中断禁止

1: 中断使能
2
T2IE
0
R/W
定时器2中断使能

0: 中断禁止

1: 中断使能

续表


位
名称
复位
R/W
描述
1
T1IE
0
R/W
定时器1中断使能

0: 中断禁止

1: 中断使能
0
DMAIE
0
R/W
DMA传输中断使能

0: 中断禁止

1: 中断使能



表3.4IEN2——中断使能寄存器2



位
名称
复位
R/W
描述

7∶6
—
00
RO没有使用,读出来是0
5
WDTIE
0
R/W
看门狗定时器中断使能

0: 中断禁止

1: 中断使能
4
P1IE
0
R/W
端口1中断使能

0: 中断禁止

1: 中断使能
3
UTX1IE
0
R/W
USART1 TX中断使能

0: 中断禁止

1: 中断使能
2
UTX0IE
0
R/W
USART0 TX中断使能

0: 中断禁止

1: 中断使能
1
P2IE
0
R/W
端口2中断使能

0: 中断禁止

1: 中断使能
0
RFIE
0
R/W
RF一般中断使能

0: 中断禁止

1: 中断使能

在上面3个寄存器中,IEN0.EA对总中断进行中断使能控制,其余部分对所有中断源进行中断使能控制(包括P1、P2和P3三个端口中断的使能及外设中断使能)。
寄存器P0IEN、P11EN、P2IEN为P0、P1和P2端口每个引脚设置中断使能,如表3.5~表3.7所示。




表3.5P0IEN——端口0位中断屏蔽



位
名称
复位
R/W
描述

7∶0
P0_[7∶0]IEN
0x00
R/W
端口P0.7~P0.0中断使能

0: 中断禁用

1: 中断使能


表3.6P1IEN——端口1位中断屏蔽



位
名称
复位
R/W
描述
7∶0
P1_[7∶0]IEN
0x00
R/W
端口P1.7~P1.0中断使能

0: 中断禁用

1: 中断使能


表3.7P2IEN——端口2位中断屏蔽



位
名称
复位
R/W
描述
7∶6
—
00
R/W未使用
5
DPIEN
0
R/W
USB D+中断使能
4∶0
P2_[4∶0]IEN
0 0000
R/W
端口P2.4~P2.0中断使能

0: 中断禁用

1: 中断使能


2. 中断使能的步骤
按键中断控制的步骤如下: 
(1)  PxIEN: 在引脚中断功能配置时,常需要设置P0IEN,主要是开启/关闭引脚的中断功能。为1时开启,为0时关闭中断。例如,开启S1按钮中断为P0IEN|=BIT4。

(2)  PICTL: 可以控制Px口中断触发信号,上升沿触发、下降沿触发。由于按键在未按下时处于高电平,按下后为低电平,松开后又为高电平,所以会产生下降沿触发信号,配置为下降沿触发即可,PICTL|=BITO。
(3)  IEN1: 除了配置引脚,还需要开启端口引脚中断使能,如开启P0端口中断使能,IEN1|=BIT5。
(4)  PxIFG: 在开启中断前需要先清除中断标志,以免误入中断造成系统混乱,如P0IFG&=~BIT4。


图3.1中断使能的步骤
(5) 系统中断使能: 在任何中断操作时,都需要开启系统中断,如EA=1。
中断使能的步骤如图3.1所示。
(1) 使IEN0中IEN0.EA位为1,开中断。
(2) 设置寄存器IEN0、IEN1和IEN2中相应中断使能位为1。
(3) 如果需要,则设置P0、P1、P2各引脚对应的各中断使能位为1。
(4) 最后在寄存器PICTL中设置中断是上升沿还是下降沿触发。

3.2.3中断处理
当中断发生时,无论该中断使能或禁止,CPU都会在中断标志寄存器中设置终端标志位,在程序中可以通过中断标志来判断是否发生了相应的中断。如果当设置中断标志时中断使能,那么在下一个指令周期,由硬件强行产生一个长调用指令LCALL到对应的向量地址,运行中断服务程序,中断的响应需要不同的时间,取决于该中断发生时CPU的状态。当CPU正在运行的中断服务程序,其优先级大于或等于新的中断时,新的中断暂不运行,直至新的中断的优先级高于正在运行的中断服务程序。
TCON、SCON、S1CON、IRCON、IRCON2是CC2530的5个中断标志寄存器,如表3.8~表3.12所示。





表3.8TCON——中断标志寄存器1



位
名称
复位
R/W
描述

7
URX1IF
0
R/WH0
USART 1 RX中断标志。当USART 1 RX中断发生时设为1,当CPU指向中断向量服务例程时清除

0: 无中断未决

1: 中断未决
6
—
0
R/W没有使用
5
ADCIF
0
R/WH0
ADC中断标志。当ADC中断发生时设为1,当CPU指向中断向量服务例程时清除

0: 无中断未决

1: 中断未决
4
—
0
R/W
没有使用
3
URX0IF
1
R/WH0
USART 0 RX中断标志。当USART0中断发生时设为1,当CPU指向中断向量服务例程时清除

0: 无中断未决

1: 中断未决
2
IT1
1
R/W保留。必须一直设为1。设置为0将使能低级别中断探测,几乎总是如此(启动中断请求时执行一次)
1
RFERRIF
0
R/WH0
RF TX、RX FIFO中断标志。当RFERR中断发生时设为1,当CPU指向中断向量服务例程时清除

0: 无中断未决

1: 中断未决
0
IT0
1
R/W保留。必须一直设为1。设置为0将使能低级别中断探测,几乎总是如此(启动中断请求时执行一次)



表3.9S0CON——中断标志寄存器2



名称
复位
R/W
描述
—
0000 00
R/W没有使用
ENCIF_1
0
R/W
AES中断。ENC有两个中断标志。当AES协处理器请求中断时两个标志都要设置

0: 无中断未决

1: 中断未决
ENCIF_0
0
R/W
AES中断。ENC有两个中断标志。当AES协处理器请求中断时两个标志都要设置

0: 无中断未决

1: 中断未决




表3.10S1CON——中断标志寄存器3



位
名称
复位
R/W
描述
7∶2
—
0000 00
R/W没有使用
1
RFIF_1
0
R/W
RF一般中断。RF有两个中断标志,RFIF_1和RFIF_0,设置其中一个标志就会请求中断服务。当无线设备请求中断时两个标志都要设置

0: 无中断未决

1: 中断未决
0
RFIF_0
0
R/W
RF一般中断。RF有两个中断标志,RFIF_1和RFIF_0,设置其中一个标志就会请求中断服务。当无线电请求中断时两个标志都要设置

0: 无中断未决

1: 中断未决



表3.11IRCON——中断标志寄存器4



位
名称
复位
R/W
描述
7
STIF
0
R/W
睡眠定时器中断标志

0: 无中断未决

1: 中断未决
6
—

0
R/W必须写为0。写入1总是使能中断源
5
P0IF
0
R/W
端口0中断标志

0: 无中断未决

1: 中断未决
4
T4IF
0
R/WH0
定时器4中断标志。当定时器4中断发生时设为1,当CPU指向中断向量服务例程时清除

0: 无中断未决

1: 中断未决

续表


位
名称
复位
R/W
描述
3
T3IF
0
R/WH0
定时器3中断标志。当定时器3中断发生时设为1,当CPU指向中断向量服务例程时清除

0: 无中断未决

1: 中断未决
2
T2IF
0
R/WH0
定时器2中断标志。当定时器2中断发生时设为1,当CPU指向中断向量服务例程时清除

0: 无中断未决

1: 中断未决
1
T1IF
0
R/WH0
定时器1中断标志。当定时器1中断发生时设为1,当CPU指向中断向量服务例程时清除

0: 无中断未决

1: 中断未决
0
DMAIF
0
R/W
DMA完成中断未决

0: 无中断未决

1: 中断未决




表3.12IRCON2——中断标志寄存器5



位
名称
复位
R/W
描述

7∶5
—
000
R/W
没有使用
4
WDTIF
0
R/W
看门狗定时器中断标志

0: 无中断未决

1: 中断未决
3
P1IF
0
R/W
端口1中断标志

0: 无中断未决

1: 中断未决
2
UTX1IF
0
R/W
USART 1 TX中断标志

0: 无中断未决

1: 中断未决
1
UTX0IF
0
R/W
USART 0 TX中断标志

0: 无中断未决

1: 中断未决
0
P2IF
0
R/W
端口2中断标志

0: 无中断未决

1: 中断未决

P0IFG、P1IFG、P2IFG是端口0、端口1、端口2每一位的中断标志寄存器,如表3.13~表3.15所示。



表3.13P0IFG——端口0位中断标志位



位
名称
复位
R/W
描述
7∶0
P0IF[7∶0]
0x00
R/W0
端口0,位7~位0输入中断状态标志。当输入端口中断请求未决信号时,其相应的标志位将置1



表3.14P1IFG——端口1位中断标志位



位
名称
复位
R/W
描述

7∶0
P0IF[7∶0]
0x00
R/W0
端口1,位7~位0输入中断状态标志。当输入端口中断请求未决信号时,其相应的标志位将置1



表3.15P2IFG——端口2位中断标志位



位
名称
复位
R/W
描述
7∶6
—
0
R0
不用
5
DPIF
0
R/W
USB D+中断状态标志。当D+线有一个中断请求未决时设置该标志,用于检测USB挂起状态下的USB恢复事件。当USB控制器没有挂起时不设置该标志
4∶0
P2IF[4∶0]
0
R/W
端口2,位4~位0输入中断状态标志。当输入端口引脚有中断请求未决信号时,其相应的标志位将置1

3.3项目实施
1. 项目环境
(1) 硬件: ZigBee(CC2530)模块、ZigBee下载调试板、USB仿真器和PC。


图3.2按键接口原理图

(2) 软件: IAR Embedded Workbench for MCS51。

2. 项目原理
1) 硬件接口原理
按键接口如图3.2所示。

CC2530开发板有三个按键: 一个复位按键,其余两个按键可以通过编程进行控制。当按键按下时,相应的管脚输出低电平。在此采用下降沿触发中断的方式检测是否有按键按下。
2)  CC2530相关寄存器
P1SEL寄存器的详细信息如表3.16所示。




表3.16P1SEL寄存器



位
名称
复位
R/W
描述

7∶0
SELP1_[7∶0]
0x00
R/W
P1_7~P1_0功能选择

0: 通用I/O

1: 外设功能

P1DIR寄存器的详细信息如表3.17所示。



表3.17P1DIR寄存器



位
名称
复位
R/W
描述

7∶0
DIRP1_[7∶0]
0x00
R/W
P1_7~P1_0的I/O方向

0: 输入

1: 输出

P1INP寄存器的详细信息如表3.18所示。




表3.18P1INP寄存器



位
名称
R/W
描述
7∶2
MDP1_[7∶2]
R/W
P1_7~P1_2的I/O输出模式

0: 上拉/下拉

1: 三态
1∶0
MDP1_[1∶0]
RO
未使用

P2INP寄存器的详细信息如表3.19所示。




表3.19P2INP寄存器



位
名称
R/W
描述
7
PDUP2
R/W
端口2上拉/下拉选择,对所有端口2引脚设置为上拉/下拉输入

0: 上拉

1: 下拉
6
PDUP1
R/W
端口1的设置

0: 上拉

1: 下拉
5
PDUP0
R/W
端口0的设置

0: 上拉

1: 下拉
4∶0
MDP2_[4∶0]
R/W
P2_4~P2_0的输入模式

0: 上拉/下拉

1: 三态


PICTL寄存器的详细信息如表3.20所示。


表3.20PICTL寄存器



位
名称
复位
R/W
描述
7
PADSC
00
RO
控制I/O引脚在输出模式下的驱动能力,选择输出驱动能力补偿引脚DVDD的低I/O电压(为了确保在较低电压下的驱动能力和较高电压下的驱动能力相同)

0: 最小驱动能力增强,DVDD1/2等于或大于2.6V

1: 最大驱动能力增强,DVDD1/2小于2.6V
6∶4
—
000
RO
保留
3
P2ICON
0
R/W
端口2的P2.4~P2.0输入模式下的中断配置,该位为所有端口2的输入P2.4~P2.0选择中断请求条件

0: 输入的上升沿引起中断

1: 输入的下降沿引起中断
2
P1ICONH
0
R/W
端口1的P1.7~P1.4输入模式下的中断配置,该位为所有端口1的输入P1.7~P1.4选择中断请求条件

0: 输入的上升沿引起中断

1: 输入的下降沿引起中断
1
P1ICONL
0
R/W
端口1的P1.4~P1.0输入模式下的中断配置,该位为所有端口1的输入P1.4~P1.0选择中断请求条件

0: 输入的上升沿引起中断

1: 输入的下降沿引起中断
0
P0ICON
0
R/W
端口0的P0.7~P0.0输入模式下的中断配置,该位为所有端口0的输入P0.7~P0.0选择中断请求条件

0: 输入的上升沿引起中断

1: 输入的下降沿引起中断

3. 软件设计


/* 包含头文件 */

/****************************************************************/

#include "ioCC2530.h" // CC2530的头文件,包含对CC2530的寄存器、中断向量等的定义

/****************************************************************/

/****************************************************************

 * 函数名称: delay

 * 功    能: 软件延时

 * 入口参数: t  延时参数,值越大延时时间越长

 * 出口参数: 无

 * 返 回 值: 无

****************************************************************/

void delay(unsigned short t)

{

unsigned char i,j;

while(--t)

{

j = 200;

while(--j)

while(--i);

}

}

/*****************************************************************

 * 函数名称: EINT_ISR

 * 功    能: 外部中断服务函数

 * 入口参数: 无

 * 出口参数: 无

 * 返 回 值: 无

*****************************************************************/

#pragma vector=P1INT_VECTOR

__interrupt void EINT_ISR(void)

{

EA = 0;        // 关闭全局中断

/* 若是P2.0产生的中断 */

if(P1IFG & 0x40)

{ 

/* 切换LED1(绿色)的亮灭状态 */

if(P1_0 == 0)    // 若之前是控制LED1(绿色)点亮,则现在熄灭LED1

{

P1_0 = 1;

}

else             // 若之前是控制LED1(绿色)熄灭,则现在点亮LED1

{

P1_0 = 0;

} 

/* 切换LED2(红色)的亮灭状态 */

if(P1_1 == 0)    // 若之前是控制LED2(红色)点亮,则现在熄灭LED2

{

P1_1 = 1;

}

else             // 若之前是控制LED2(红色)熄灭,则现在点亮LED2

{

P1_1 = 0;

}   

/* 切换LED3(黄色)的亮灭状态 */

/* 等待用户释放按键,并消抖 */

while(P1_6 & 0x40);

delay(10);

while(P1_6 & 0x40); 

/* 清除中断标志 */

P1IFG &= ~0x40;   // 清除P1.6中断标志

IRCON2 &= ~0x08;  // 清除P1端口中断标志

}

if(P1IFG & 0x80)

{ 

/* 切换LED1(绿色)的亮灭状态 */

if(P1_0 == 0)    // 若之前是控制LED1(绿色)点亮,则现在熄灭LED1

{

P1_0 = 1;

}

else             // 若之前是控制LED1(绿色)熄灭,则现在点亮LED1

{

P1_0 = 0;

}    

/* 切换LED2(红色)的亮灭状态 */

if(P1_1 == 0)    // 若之前是控制LED2(红色)点亮,则现在熄灭LED2

{

P1_1 = 1;

}

else             // 若之前是控制LED2(红色)熄灭,则现在点亮LED2

{

P1_1 = 0;

}  

/* 切换LED3(黄色)的亮灭状态 */

/* 等待用户释放按键,并消抖 */

while(P1_7 & 0x80);

delay(10);

while(P1_7& 0x80); 

/* 清除中断标志 */

P1IFG &= ~0x80;   // 清除P1.7中断标志

IRCON2 &= ~0x08;  // 清除P1.0端口中断标志

}

EA = 1;          // 使能全局中断    

}

/*****************************************************************

 * 函数名称: main

 * 功    能: main函数入口

 * 入口参数: 无

 * 出口参数: 无

 * 返 回 值: 无

*****************************************************************/

void main(void)

{

/*

由于CC253x系列片上系统上电复位后,所有21个数字I/O均默认为具有上拉的通用输入I/O,因此本实验只需要改变作为LED控制信号的P1.0、P1.1和P1.4方向为输出即可。另外还需要将P2.0设置为输入下拉模式。

在用户的实际应用开发中,我们建议用户采用如下步骤来配置数字I/O: 

(1) 设置数字I/O为通用I/O; 

(2) 设置通用I/O的方向; 

(3) 若通用I/O的方向被配置为输入,可配置上拉/下拉/三态模式,在此实验中不需要配置; 

(4) 若通用I/O的方向被配置为输出,可设置其输出高/低电平。

*/

P1SEL=0;

/* 配置P1.0、P1.1和P1.4的方向为输出 */

P1DIR |= 0x03;  // 0x13 = 0B00010011

P1_0 = 1;  // P1.0输出低电平熄灭其所控制的LED1(绿色)

P1_1 = 1;  // P1.1输出低电平熄灭其所控制的LED2(红色)  

/* 配置P1端口的中断边沿下降沿产生中断 */

PICTL |= 0x02;

/* 使能P1.6和P1.7 中断 */

P1IEN |= 0xC0;

/* 使能P1端口中断 */

IEN2 |= 0x10;

/* 使能全局中断 */

EA = 1; 

while(1);

}




4. 实施步骤
(1) 启动IAR开发环境,新建工程。
(2) 在IAR开发环境中编译、运行、下载程序。
(3) 通过两个按键来控制两个LED的亮灭。