F28335中断系统详解及其应用

最近导师的项目中要应用到DSP F28335,由于之前一直对f28335的中断不是很理解,所以花了一点时间仔细看了一下《手把手教你学DSP:基于TMS28335》这本书讲解中断的章节,感觉有一定的收获,在此记录下来。

1 什么是中断

CPU进行正常程序处理时,有时会被要求接收更高级别的指令或实时性要求更高的任务,不得不中断当前的程序处理,而去响应后者,即进入中断服务程序,这就是中断。
当处理完这些任务之后,要继续刚才的处理,因此在执行中断服务程序的时候,必须保存执行现场以确保在完成更高级别任务或指令时能够再接着做刚才被打断的任务。

中断请求的分类

  1. 可屏蔽中断:根据目前处理任务的优先级别来考虑其是否优先处理
  2. 不可屏蔽中断:只要接到中断请求,就要做出中断处理,如RESET和NMI。

2 F28335中断概述及中断源

中断源类型

  1. 片内外设中断源:如PWM、CAP、QEP、定时器等;
  2. 片外中断源:外部中断输入引脚XINT1、XINT2引入的外部中断源。

F28335内部有16个中断线,其中包括2个不可屏蔽中断(RESET和NMI)与14个可屏蔽中断。
下图所示为F28335中断结构:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Emg5z7rF-1596698997718)(images/1.jpg)]

从上图可以看出:

  1. 定时器1和定时器2产生的中断请求通过INT13、INT14中断线到达CPU,实际上这两个中断已经预留给了实时操作系统;
  2. INT1~INT12可屏蔽中断可供外部中断和处理器内部的单元使用;
  3. F28335外设中断源有58个,PIE外部中断扩展将这58个外设中断源分配给这12个中断线(由后面要讲的中断向量表进行管理)。
  4. 外部中断源均通过PIE模块进行判断处理。

3 F28335的3级中断机制

在F28335中,产生一个完整的中断需要经过3个阶段,这就是3级中断机制,如下图所示,3级中断机制分别为外设级中断PIE级中断CPU级中断
在这里插入图片描述

从图中可以看出,外设要能够成功产生中断响应,就要首先经外设级中断允许,然后经PIE允许,然后经CPU允许,最终CPU做出响应。

3.1 外设级中断
  • 当外设产生了中断事件,那么该外设对应中断标志寄存器(IF) 相应的位将被 自动置位(不需要人为去对寄存器操作);
  • 如果该外设对应**中断使能寄存器(IE)**中相应的使能位正好置位,则外设产生的中断将向PIE控制器发出中断申请,从而进入到PIE级中断;
  • 如果IE一直没有被使能,则需要软件编程将IF复位;
  • 进入中断服务后,有部分硬件外设会自动复位中断标志寄存器,多数外设需要编程复位。
3.2 PIE级中断

PIE模块作用是在有限中断线的情况下用来管理多个中断源触发。
结构如下图所示:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kiqO0z4E-1596698997725)(images/3.jpg)]

从上图可知:

  • PIE将外设中断分成了12个组,分别对应CPU的12个可屏蔽中断线,每组由8各外设级中断组成,这8个外设中断分别对应相应外设接口的中断引脚;
  • CPU外设中断源为58个,而PIE能够支持的中断源为96个,能完美的解决CPU外设中断源数目多的问题。

PIE中断流程

  1. 一旦PIE控制器有中断产生,相应的中断标志位(PIEIFRx.y)将置1;
  2. 如果相应的PIE中断使能位也置1,则PIE将检查相应的PIEACKx以确定CPU是否准备响应该中断;
  3. 如果相应的PIEACKx位清零,PIE向CPU申请中断;
  4. 如果PIEACKx置1,PIE将等待到相应的PIEACKx清零才向CPU申请中断;

中断向量表
中断向量表记录着各个中断源对应的地址,当我们需要将某个外设设置中断时,就需要使能对应的中断源,参考中断向量表。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ywCZ1kqz-1596698997727)(images/4.jpg)]

3.3 CPU级中断

一旦CPU申请中断,CPU级中断标志位(IFR)将置1。中断标志位锁存到标志寄存器后,只有CPU中断使能寄存器(IER)或中断调试使能寄存器(DBGIER)相应的使能位和全局中断屏蔽位(INTM)被使能时才会响应中断申请。

4 中断应用示例(定时器中断为例)

中断的配置与PIE模块的响应机制完全对应。在此应用一个简单的示例,利用定时器0(timer0)产生中断,点亮led灯(使led灯闪烁)。
首先可以从上面的中断向量表中查找到,timer0对应的中断编号为INT1.7,并且我们还可以在TI提供的DSP2833x_PieVect.h文件中找到,名称为TINT0,如下所示:

// Group 1 PIE Peripheral Vectors:
      PINT     SEQ1INT;
      PINT     SEQ2INT;
      PINT     rsvd1_3;
      PINT     XINT1;
      PINT     XINT2;
      PINT     ADCINT;    // ADC
      PINT     TINT0;     // Timer 0
      PINT     WAKEINT;   // WD

// Group 2 PIE Peripheral Vectors:
      PINT     EPWM1_TZINT; // EPWM-1
      PINT     EPWM2_TZINT; // EPWM-2
      PINT     EPWM3_TZINT; // EPWM-3
      PINT     EPWM4_TZINT; // EPWM-4
      PINT     EPWM5_TZINT; // EPWM-5
      PINT     EPWM6_TZINT; // EPWM-6
      PINT     rsvd2_7;
      PINT     rsvd2_8;
...

中断配置步骤:
第一步
基础的初始化之后,对PIE模块进行指定,一般在InitPieVectTable();PIE模块初始化之后进行指定。

void main(void)
{
	 InitSysCtrl();		// 初始化系统控制
	 DINT;				// disable interrupt(屏蔽CPU中断)
	 InitPieCtrl();		// 初始化PIE控制寄存器
	 IER = 0x0000;		// 清除中断使能寄存器和中断标志寄存器
	 IFR = 0x0000;
	 InitPieVectTable();// 初始化中断向量表
	 EALLOW;			// 开启寄存器写操作
	 PieVectTable.TINT0 = &cpu_timer0_isr;	// 将中断函数的地址传入
	 EDIS;				// 关闭寄存器写操作

	InitCputTimers();	// 初始化CPU寄存器定时器
	ConfigCpuTimer(&CpuTimer0, 150, 500000);	// 配置timer0,时钟cpu频率为150MHz,定时500ms
}

第二步
打开PIE模块的时钟,打开定时器timer0中断需要使能INT1.7,如下所示:

void main(void)
{
// 第1步
	 InitSysCtrl();		// 初始化系统控制
	 DINT;				// disable interrupt(屏蔽CPU中断)
	 InitPieCtrl();		// 初始化PIE控制寄存器
	 IER = 0x0000;		// 清除中断使能寄存器和中断标志寄存器
	 IFR = 0x0000;
	 InitPieVectTable();// 初始化中断向量表
	 EALLOW;			// 开启寄存器写操作
	 PieVectTable.TINT0 = &cpu_timer0_isr;	// 将中断函数的地址传入
	 EDIS;				// 关闭寄存器写操作

	InitCputTimers();	// 初始化CPU寄存器定时器
	ConfigCpuTimer(&CpuTimer0, 150, 500000);	// 配置timer0,时钟cpu频率为150MHz,定时500ms
	
//第2步
	IER |= M_INT1;                         //全局使能INT1
	PieCtrlRegs.PIEIER1.bit.INTx7 = 1;     //使能INT1.7
	EINT;								   //使能中断INTM(全局中断屏蔽位),响应中断申请
	ERTM;								   //使能实时中断DBGM(实时调试)
	
	for(;;);							   //一直循环下去					
}

需要注意的是,咱们并没有设置PIEIFR标志位为1,那怎么能工作呢,其实中断响应的时候自动置1了。
第三步
在设置的中断中写函数,并在中断里面清除响应标志位PIEACK。如下所示:

interrupt void cpu_timer0_isr(void)
{
	Xint1Count++;
	GpioDataRegs.GPATOGGLE.bit.GPIO47 = 1; //每隔0.5s翻转一次高低电平

	PieCtrlRegs.PIEACK.all = PIEACK_GROUP1; //由于timer0在group1中,所以需要清除group1的响应标志位PIEACK,以便接收group1中更多的中断
}
  • 12
    点赞
  • 63
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值