基于TI 28335
- 一、DSP28335的中断系统介绍
- 1.中断简介
- (1)外设级
- (2)PIE级(重要)
- (3)CPU级
- 2.中断向量表
- (1)中断优先级
- 二、中断寄存器介绍
- 1.PIE级中断寄存器
- (1)PIE中断使能寄存器(PIEIERx)
- (2)PIE中断标志寄存器(PIEIFRx)
- (3)PIE中断应答寄存器(PIEACKx)
- (4)PIE中断应答寄存器(PIECTRL)
- 2.CPU级中断寄存器
- (1) CPU 中断使能寄存器(IER)
- (2)CPU 中断标志寄存器(IFR)
- 3.外部中断相关寄存器
- (1)外部可屏蔽中断控制寄存器(XINTnCR)
- (2)外部不可屏蔽中断控制寄存器(XINTnCR)
- (3)外部中断x计数器(XINTxCTR)
- 二、软件实现
- 1.中断配置的步骤
- 2.外部中断实验
中断是一种暂停正在执行的程序,转而执行另外程序,等中断程序执行完毕,再回到主程序的过程
一、DSP28335的中断系统介绍
1.中断简介
F28335 内部有16个中断线,其中包括2个不可屏蔽中断(RESET和NMI)与14 个可屏蔽中断。
F28335的外部中断分为三个等级:外设级、PIE级和CPU级;如下图:
图中右上侧为CPU级,左下侧为PIE级,右侧为外设级
一个外设中断源想要让CPU产生中断必须经过这三个阶段,下面对这三个等级进行介绍
(1)外设级
CPU 正常处理程序过程中,外设产生了中断事件,那么该外设对应中断标志寄存器 IF响应的位将被自动置位,如果该外设对应中断使能寄存器IE中响应的使能位正好置位(需要软件控制),则外设产生的中断将向PIE控制器发出中断申请。
进入中断服务后,有部分硬件外设会自动复位中断标志寄存器,多数外设需要在中断服务中手动复位中断标志寄存器
(2)PIE级(重要)
PIE相当于一个对中断的管理器
由于CPU没有能力处理所有外设级的中断请求,因此F28335的CPU让出了12个中断线交给PIE模块进行复用管理
PIE将外设中断分成了12个组,分别对应着CPU的12个可屏蔽中断线,每1组由8个外设级中断组成,这8个外设中断分别对应相应外设接口的中断引脚,PIE通过一个8选1的多路选择器将这8个外设中断组成1组
具体的中断对应哪个PIE组的那条中断线呢?查手册有下表:
以外部中断1即XINT1为例,该中断分组为第一组 INT1.y的第四条 INTx.4中断线即 INT1.4
和外设级中断类似,在PIE模块内每组中断有相应的中断标志位(PIEIFRx)和使能(PIEIERx.y);除此之外,每组PIE中断(INT1~INT12)有一个响应标志位(PIEACK)。
这三个对应图中红色部分:
作用分别为:
PIE控制器有中断产生,相应的中断标志位(PIEIFRx.y)将置1。
如果相应的PIE中断使能位也置1,则PIE将检查相应的PIEACKx以确定CPU是否准备响应该中断。
PIEACKx主要作用在于选择哪个中断进入CPU;如果相应的PIEACKx位清零,PIE向CPU申请中断;
(3)CPU级
一旦CPU申请中断,CPU级中断标志位(IFR)将置1。中断标志位锁存到标志寄存器后,只有CPU中断使能寄存器(IER)或中断调试使能寄存器(DBGIER)相应的使能位和全局中断屏蔽位(INTM)被使能时才会响应中断申请。
综上,中断触发条件可总结为下表:
2.中断向量表
什么是中断向量?
中断服务程序的入口地址就是中断向量
在使用时,中断服务程序地址保存在SRAM中,我们不需要知道在哪(也用不到)
(1)中断优先级
28335的中断优先级定义比较简单,遵循以下原则:
a.同组内:同组内排在前面的优先级比排在后面的优先级高。
b.不同组内:排在前面组内的任何一个中断优先级要比排在后面组内的任何一个中断的优先级高。
(优先级举例:INT1.2 > INT1.7 > INT2.2)
二、中断寄存器介绍
1.PIE级中断寄存器
(1)PIE中断使能寄存器(PIEIERx)
PIE控制器一共有12个PIE中断使能寄存器PIEIERx,分别对应于PIE控制器的12个组,每组1个,用来设置组内中断的使能情况。
具体定义:
(2)PIE中断标志寄存器(PIEIFRx)
PIE控制器一共有12个PIE中断标志寄存器PIEIFRx,分别对应PIE控制器的12个组,每组1个。PIEIFR寄存器的每一位代表对应中断的请求信号
该位置1,表示相应的中断提出了请求,需要CPU响应。
CPU取出相应的中断向量的时候,也就是说,当CPU响应该中断的时候,该标志位被清0。
具体定义:
(3)PIE中断应答寄存器(PIEACKx)
如果PIE中断控制器有中断产生,则相应的中断标志位将置1。如果相应的PIE中断使能位也置1,则PIE将检查PIE中断应答寄存器PIEACK,以确定CPU是否准备响应该中断。
如果相应的PIEACKx清0,PIE便向CPU申请中断;
如果相应的PIEACKx置1,那么PIE将等待直到相应的PIEACKx清0才向CPU申请中断
具体定义:
(4)PIE中断应答寄存器(PIECTRL)
具体定义:
2.CPU级中断寄存器
(1) CPU 中断使能寄存器(IER)
CPU 中断标志寄存器(IFR)是一个16位的CPU寄存器,包含CPU级可屏蔽中断(INT1-INT14、DLOGINT 和 RTOSINT)的使能位。
用户可以通过读IER来定义使能中断或设置中断的级别,也可以通过写IER来激活中断。
用ORIER指令将相应的IER位置1可以使能中断,利用ANDIER指令将相应的IER位置0可以禁止一个中断
具体定义:
(2)CPU 中断标志寄存器(IFR)
CPU 中断标志寄存器(IFR)是一个16位的CPU寄存器,用于标志和清除被执行的中断。CPU中断寄存器(IFR)包含CPU级可屏蔽中断(INT1-INT14、DLOGINT和RTOSINT)的标志位。
当一个可屏蔽请求发生时,相应外设控制寄存器的标志位置1,如果相应的屏蔽位也是1,则该中断请求被送到CPU,并在IFR中相应的标志位置1,这表示中断未被执行或等待应答
具体定义:
3.外部中断相关寄存器
(1)外部可屏蔽中断控制寄存器(XINTnCR)
用于使能中断和定义触发方式
具体定义:
(2)外部不可屏蔽中断控制寄存器(XINTnCR)
具体定义:
(3)外部中断x计数器(XINTxCTR)
不常用
具体定义:
二、软件实现
1.中断配置的步骤
(1)失能CPU级中断,并初始化PIE控制器寄存器和PIE中断向量表
代码如下:
InitPieCtrl();
IER=0x0000;
IFR=0x0000;
InitPieVectTable();
该步骤中,InitPieCtrl();和 InitPieVectTable();函数是TI公司已经很封装 好的寄存器和向量表初始化函数。
IER(中断使能寄存器)清零表示暂时禁用所有CPU级别的中断
IFR(中断标志寄存器)清零表示清除所有挂起的中断标志
这两步是为初始化中断做准备,防止在初始化过程中发生中断导致初始化失败(相当于上电复位)
(2)使能IO口时钟,为中断配置IO口
以外部中断为例,本实验中以按键按下,下拉电平为中断源,所以要配置IO为输入,并配置相应的时钟
(3)设置IO口与中断线的映射关系
这一步是将IO与 中断线进行连接,以外部中断为例,XINT1-XINT2只能对GPIO0-GPIO31配置;XINT3-XINT7只对GPIO32-GPIO63配置;如下图:

代码如下:
EALLOW;
GpioIntRegs.GPIOXINT1SEL.bit.GPIOSEL=12; //XINT1是GPIO12
EDIS;
(4)指定中断向量表中断服务函数地址
这个通过对PIE中断向量表寄存器的相应位进行设置,中断服务函数名可自定义,但是要符合C语言标识符命名规则,在中断函数名前需加上地址符“&”。在对PIE中断向量表寄存器设置时要先声明EALLOW,修改完成后还要声明EDIS。
代码如下:
EALLOW; //修改被保护的寄存器,修改前应添加EALLOW语句
PieVectTable.XINT1=&EXTI1_IRQn;
EDIS; //EDIS的意思是不允许修改被保护的寄存器
(5)使能外设对应的PIE中断
由于外设中断较多,它们是由PIE统一管理,所以要根据你所使用的外设中断选择对应的组和该组内的通道,比如外部中断1,它是由PIE组1的第4通道连接INT1.4
代码:
PieCtrlRegs.PIEIER1.bit.INTx4=1; //使能PIE组1的INT4
(6)设置外部中断触发方式并使能中断
该步骤主要作用是进行对XINT1CR寄存器操作进行对触发方式和使能
代码:
XIntruptRegs.XINT1CR.bit.POLARITY=0; //下降沿触发中断
XIntruptRegs.XINT1CR.bit.ENABLE=1; //使能XINT1
(7)使能CPU级中断及全局中断
这个通过对IER和EINT寄存器相应位设置进行使能或者失能。
IER|=M_INT1; //使能CPU中断1(INT1)
EINT; //开全局中断
ERTM;
(8)编写外部中断服务函数
配置好中断后如果有触发,即会进入中断服务函数,中断服务函数名在前面已定义好,所以要保证一致,否则将不会进入中断服务函数内执行。在DSP28335软件开发中,要在中断服务函数名前加上关键字interrupt
interruptvoidEXTI1_IRQn(void)
{
...功能程序
}
2.外部中断实验
实现效果:通过按键1对第一个LED进行中断翻转电平操作
代码:
中断初始化和中断服务:
interrupt void EXTI1_IRQn(void)
{
GpioDataRegs.GPCTOGGLE.bit.GPIO68=1;
PieCtrlRegs.PIEACK.bit.ACK1 = 1;
}
void EXTI_Init(void)
{
//1.时钟初始化
EALLOW;
SysCtrlRegs.PCLKCR3.bit.GPIOINENCLK = 1;
EDIS;
//2.GPIO按键配置
EALLOW;
//12
GpioCtrlRegs.GPAMUX1.bit.GPIO12=0;
GpioCtrlRegs.GPADIR.bit.GPIO12=0;//配置为输入
GpioCtrlRegs.GPAPUD.bit.GPIO12=0;
GpioCtrlRegs.GPAQSEL1.bit.GPIO12 = 0;//配置为同步模式 即无滤波
//48
GpioCtrlRegs.GPBMUX2.bit.GPIO48=0;
GpioCtrlRegs.GPBDIR.bit.GPIO48=1;
GpioCtrlRegs.GPBPUD.bit.GPIO48=0;
GpioDataRegs.GPBCLEAR.bit.GPIO48 = 1;
EDIS;
//3.设置IO与中断线关系:XINT1->GPIO12
EALLOW;
GpioIntRegs.GPIOXINT1SEL.bit.GPIOSEL = 12;
EDIS;
//4.指定中断向量表中断服务函数地址
EALLOW;
PieVectTable.XINT1 = &EXTI1_IRQn;
EDIS;
//5.使能外设对应的PIE中断
PieCtrlRegs.PIEIER1.bit.INTx4 = 1;
//6.设置下降沿触发并使能XINT1
XIntruptRegs.XINT1CR.bit.POLARITY = 1;
XIntruptRegs.XINT1CR.bit.ENABLE = 1;
//7.使能CPU级全局中断
IER|=M_INT1;
EINT;
ERTM;
}
main.c
#include "DSP2833x_Device.h" // DSP2833x Headerfile Include File
#include "DSP2833x_Examples.h" // DSP2833x Examples Include File
#include "beep.h"
#include "Key.h"
#include "LED.h"
void main()
{
InitSysCtrl();
InitPieCtrl();
IER=0x0000;
IFR=0x0000;
InitPieVectTable();
Key_Init();
Led_Init();
EXTI_Init();
while(1)
{
GpioDataRegs.GPCCLEAR.bit.GPIO64=1;
}
}

