CC2530的中断系统是为了让CPU对内部或外部的突发事件及时地做出响应,并执行相应的终端程序。中断由中断源引起,中断源由相应的寄存器来控制。当需要使用中断时,需配置相应的中断寄存器来开启中断,当终端发生时将跳入中断服务函数中来执行此中断所需处理的事件。
CC2530有18个中断源,每个中断源都可以产生中断请求,中断请求可以通过设置中断使能SFR寄存器的中断使能位IEN0、IEN1或IEN2使能或禁止中断。
中断号码 | 描述 | 中断名称 | 中断向量 | 中断屏蔽 | 中断标志 |
0 |
RF TX RFIO下溢 或
RX FIFO溢出
|
RFERR | 03H | IEN0.RFERRIE | TCON.RFERRIF |
1 | ADC转换结束 | ADC | 0BH | IEN0.ADCIE | TCON.ADCIF |
2 | USART0 RX完成 | URX0 | 13H | IEN0.URX0IE | 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中断 | P2INT | 33H | IEN2.P2IE | IRCON2.P2IF |
7 | USART0 TX完成 | UTX0 | 3BH | IEN2.UTX0IE | IRCON2.UTX0IF |
8 | DMA传输完成 | DMA | 43H | IEN1.DMAIE | IRCON.DMAIF |
9 | Timer1(16位)捕获/比较/溢出 | T1 | 4BH | IEN1.T1IE | IRCON.T1IF |
10 | Timer2(MAC Timer) | T2 | 53H | IEN1.T2IE | IRCON.T2IF |
11 | Timer3(8位)捕获/比较/溢出 | T3 | 5BH | IEN1.T3IE | IRCON.T3IF |
12 | Timer4(8位)捕获/比较/溢出 | T4 | 63H | IEN1.T4IE | IRCON.T4IF |
13 | 端口0中断 | P0INT | 6BH | IEN1.P0IE | IRCON.P0IF |
14 | USART1 TX 完成 | UTX1 | 73H | IEN2.UTXIE | 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 |
中断服务程序的入口地址即中断向量,CC2530的18个中断源对应了18个中断向量,中断向量定义在头文件"ioCC2530.h"中,定义如下:
/* ------------------------------------------------------------------------------------------------
* Interrupt Vectors
* ------------------------------------------------------------------------------------------------
*/
//RF内核错误中断(RF TX RFIO下溢或RF FIFO溢出)
#define RFERR_VECTOR VECT( 0, 0x03 ) /* RF TX FIFO Underflow and RX FIFO Overflow */
//ADC转换结束
#define ADC_VECTOR VECT( 1, 0x0B ) /* ADC End of Conversion */
//USART0 RX完成
#define URX0_VECTOR VECT( 2, 0x13 ) /* USART0 RX Complete */
//USART1 RX 完成
#define URX1_VECTOR VECT( 3, 0x1B ) /* USART1 RX Complete */
//AES加密解密完成
#define ENC_VECTOR VECT( 4, 0x23 ) /* AES Encryption/Decryption Complete */
//睡眠定时器完成
#define ST_VECTOR VECT( 5, 0x2B ) /* Sleep Timer Compare */
//端口2中断
#define P2INT_VECTOR VECT( 6, 0x33 ) /* Port 2 Inputs */
//USART0 TX完成
#define UTX0_VECTOR VECT( 7, 0x3B ) /* USART0 TX Complete */
//DMA传输完成
#define DMA_VECTOR VECT( 8, 0x43 ) /* DMA Transfer Complete */
//Timer1(16位)捕获/比较/溢出
#define T1_VECTOR VECT( 9, 0x4B ) /* Timer 1 (16-bit) Capture/Compare/Overflow */
//Timer2(MAC Timer)
#define T2_VECTOR VECT( 10, 0x53 ) /* Timer 2 (MAC Timer) */
//Timer3(8位)捕获/比较/溢出
#define T3_VECTOR VECT( 11, 0x5B ) /* Timer 3 (8-bit) Capture/Compare/Overflow */
//Timer4(8位)捕获/比较/溢出
#define T4_VECTOR VECT( 12, 0x63 ) /* Timer 4 (8-bit) Capture/Compare/Overflow */
//端口0中断
#define P0INT_VECTOR VECT( 13, 0x6B ) /* Port 0 Inputs */
//USART1 TX 完成
#define UTX1_VECTOR VECT( 14, 0x73 ) /* USART1 TX Complete */
//端口1中断
#define P1INT_VECTOR VECT( 15, 0x7B ) /* Port 1 Inputs */
//RF通用中断
#define RF_VECTOR VECT( 16, 0x83 ) /* RF General Interrupts */
//看门狗计时溢出
#define WDT_VECTOR VECT( 17, 0x8B ) /* Watchdog Overflow in Timer Mode */
中断优先级将决定中断响应的先后顺序,在CC2530中分为6个中断优先组,即IPG0~IPG5,每一组中断优先组中有三个中断源:
组 | 中断 | 中断 | 中断 |
IPG0 | RFERR | RF | DMA |
IPG1 | ADC | T1 | P2INT |
IPG2 | URX0 | T2 | UTX0 |
IPG3 | URX1 | T3 | UTX1 |
IPG4 | ENC | T4 | P1INT |
IPG5 | ST | P0INT | WDT |
IP1_X | IP0-X | 优先级 |
0 | 0 | 0(优先级别最低) |
0 | 1 | 1 |
1 | 0 | 2 |
1 | 1 | 3(优先级别最高) |
//设置IPG0优先级组为最高优先级别
IP1_IPG0 = 1;
IP0_IPG0 = 1;
如果同时收到相同优先级或同一优先级组中的中断请求时,将采用轮流检测顺序来判断中断优先级别的响应。
中断向量编号 | 中断名称 | 优先级排序 |
0 | RFERR | 高 |
16 | RF | |
8 | DMA | |
1 | ADC | |
9 | T1 | |
2 | URX0 | |
10 | T2 | |
3 | URX1 | |
11 | T3 | |
4 | ENC | |
12 | T4 | |
5 | ST | |
13 | P0INT | |
6 | P2INT | |
7 | UTX0 | |
14 | UTX1 | |
15 | P1INT | |
17 | WDT | 低 |
中断发生时,CC2530硬件自动完成以下处理:
中断编程的一般过程如下:
CC2530所使用的编译器为IAR,在IAR编译器中用关键词_interrupt来定义一个中断函数。使用#progma vector来提供中断函数的入口地址,并且中断函数没有返回值,没有函数参数。中断函数的一般格式如下:
#progma vector = 中断向量
_interrupt void 函数名(void)
{
//中断函数代码
}
在中断函数的编写中,当程序进入中断服务程序之后,需要执行以下四个步骤:
一般情况下,中断函数的编写是根据实际项目中的需求来定的。以CC2530端口0的P0_4、P0_5外部中断为例,中断程序编写如下所示:
//中断函数入口地址
#pragma vector = POINT_VECTOR
//定义一个终端函数
_interrupt void P0_ISR(void)
{
//关端口P0_4、P0_5中断
P0IEN &= ~0x30;
//判断中断发生
if(P0IFG > 0)
{
//清中断标志
P0IFG = 0;
/***中断事件的处理***/
}
}