DSP F28335中断系统

DSP F28335中断系统一 中断概念 1 中断介绍 1 1 中断概念中断其实就是当 CPU 执行程序时 由于发生了某种随机的事件 外部或内部 引起 CPU 暂时中断正在运行的程序 转去执行一段特殊的服务程序 中断服务子程序或中

大家好,欢迎来到IT知识分享网。

一、中断概念

1.中断介绍

1.1 中断概念

      中断其实就是当 CPU 执行程序时,由于发生了某种随机的事件(外部或内部),引起 CPU 暂时中断正在运行的程序,转去执行一段特殊的服务程序(中断服务子程序或中断处理程序),以处理该事件,该事件处理完后又返回被中断的程序继续执行,这一过程就称为中断,引发中断的称为中断源。

DSP F28335中断系统

1.2 F28335中断概述

      F28335内部有16个中断线,其中包括2个不可屏蔽中断(RESET和NMI)与14个可屏蔽中断。

DSP F28335中断系统

DSP F28335中断系统

 (GPIO0-GPIO31对应XINT1和XINT2, GPIO32-GPIO63对应XINT3–XINT7)

1.3 F28335中断机制

       F28335的中断采用的是3级中断机制,分别是外设级中断、PIE级中断和CPU级中断,最内核部分为CPU级中断,即CPU只能响应从CPU中断线上过来的中断请求,但F28335中断源很多,CPU没有那么多中断线,在有限中断线的情况下,只能安排中断线进行复用,其复用管理就有了中间层的PIE级中断,外设要能够成功产生中断响应,就要首先经外设级中断允许,然后经PIE允许,最终CPU做出响应。

中断响应顺序为:外设中断接收中断响应信号,传送到PIE中断控制器,最后传递给CPU中断响应,做出响应的中断处理。

DSP F28335中断系统

 没个中断组中包含8个子中断,因此96=12*8DSP F28335中断系统

 不同类别的中断信号,需要找出相对应的中断组及该中断组所对应的子中断信号线,启动该中断时,需要设置对应的信号寄存器。DSP F28335中断系统

1.4 F28335中断向量

       CPU响应中断,就是CPU要去执行相应的中断服务程序,其响应过程是CPU将现执行程序的指令地址压入堆栈,跳转到中断服务程序入口地址,中断服务程序的入口地址就是中断向量,这个中断向量用2个16位寄存器存放。入口地址是22位的,地址的低16位保存在该向量的低16位;地址的高16位则保存在它的高6位,更高的10位保留。

1.5 中断向量映射方式

DSP F28335中断系统

2.中断操作

2.1 复位中断操作过程

2.2 使能/禁止复用外设中断的处理

       应用外设中断的使能/禁止标志位使能/禁止外设中断,PIEIER和CPU IER寄存器主要是在同一组中断内设置中断优先级。如果要修改PIEIER寄存器的设置,有两种方法。第一种方法是保护相应的PIE标志寄存器标志位,防止中断丢失。第二种方法是清除相应的PIE寄存器的标志位。

2.3 外设复用中断向CPU申请中断的流程

DSP F28335中断系统

3.中断相关寄存器

3.1 PIE控制寄存器(PIECTRL)

DSP F28335中断系统

4.中断配置

(1)使能外设对应的PIE中断:由于外设中断较多,它们是由PIE统一管理,所以要根据你所使用的外设中断选择对应的组,比如外部中断1,它是由PIE组1的第4线连接(查阅中断向量表),这个在前面中断介绍时讲解过。因此可由PIE控制寄存器中相应中断使能位来控制。

PieCtrlRegs.PIEIER1.bit.INTx4 = 1;    // 使能PIE组1的INT4

(2)使能外设中断:这个具体是由外设相关中断使能位来控制,比如外部中断1,这个可由外部中断1的控制寄存器中相应中断使能位来控制。

XIntruptRegs.XINT1CR.bit.ENABLE= 1;       // 使能XINT1

(3)指定中断向量表中断服务函数地址:这个通过对PIE中断向量表寄存器的相应位进行设置,中断服务函数名可自定义,但是要符合C语言标识符命名规则,在中断函数名前需加上地址符“&”。在对PIE中断向量表寄存器设置时要先声明EALLOW,修改完成后还要声明EDIS。比如外部中断1,其设置如下:

EALLOW;    // 修改被保护的寄存器,修改前应添加EALLOW语句 PieVectTable.XINT1 = &EXTI1_IRQn; EDIS;   // EDIS的意思是不允许修改被保护的寄存器

(4)使能CPU中断及全局中断:这个通过对IER和EINT寄存器相应位设置进行使能或者失能。比如外部中断1,其代码如下:

IER |= M_INT1;   // 使能CPU中断1(INT1) EINT;               // 开全局中断

(5)编写中断服务函数
配置好中断后如果有触发,即会进入中断服务函数,中断服务函数名在前面已定义好,所以要保证一致,否则将不会进入中断服务函数内执行。在DSP28335软件开发中,要在中断服务函数名前加上关键字interrupt。例如外部中断1的中断服务函数:

interrupt void EXTI1_IRQn(void) { ...功能程序 }

二、外部中断实验

1.外部中断介绍

1.1 外部中断简介

      F28335共支持7个外部中断XINT1-XINT7,其中XINT1-XINT2只能对GPIO0-GPIO31配置XINT3-XINT7只对GPIO32-GPIO63配置。XINT13还有一个不可屏蔽的外部中断XNMI共用中断源。每一个外部中断可以被选择为正边沿或负边沿触发(上升沿或下降沿触发),也可以被使能或者禁止(包括XNMI)。可屏蔽中断单元包括一个16位增计数器(一般不用),该计数器在检测到有效中断边沿时复位为0,同时用来准确记录中断发生的时间。

DSP F28335中断系统

1.2 外部中断相关寄存器

(1)外部中断控制寄存器(XINTnCR)。

DSP F28335中断系统

2.外部中断配置步骤

InitPieCtrl(); IER = 0x0000; //关闭CPU所有中断 IFR = 0x0000; InitPieVectTable();

(2)使能IO口时钟,配置IO口为输入
(3)设置 IO 口与中断线的映射关系
比如我们K1它是连接在GPIO12上,要使用外部中断功能可以是外部中断1或者外部中断2,假如使用外部中断1,代码如下:

EALLOW; GpioIntRegs.GPIOXINT1SEL.bit.GPIOSEL = 12;   // XINT1是GPIO12 EDIS;

(4)指定中断向量表中断服务函数地址
     比如外部中断1,其设置如下:

EALLOW;    // 修改被保护的寄存器,修改前应添加EALLOW语句 PieVectTable.XINT1 = &EXTI1_IRQn; EDIS;   // EDIS的意思是不允许修改被保护的寄存器

(5)使能外设对应的PIE中断
比如外部中断1,它是由PIE组1的第4通道连接

PieCtrlRegs.PIEIER1.bit.INTx4 = 1;    // 使能PIE组1的INT4 EDIS;

(6)设置外部中断触发方式并使能中断
外部中断的触发方式及中断使能是由XIntruptRegs寄存器控制,具体实现代码如下:

XIntruptRegs.XINT1CR.bit.POLARITY = 0;      // 下降沿触发中断 XIntruptRegs.XINT1CR.bit.ENABLE= 1;        // 使能XINT1

(7)使能CPU级中断及全局中断

IER |= M_INT1;  // 使能CPU中断1(INT1) EINT;           // 开全局中断 ERTM;            // 中断调试时使用

(8)编写外部中断服务函数
例如外部中断1的中断服务函数:

interrupt void EXTI1_IRQn(void) { ...功能程序 }

3.硬件设计

DSP F28335中断系统

 4.软件设计

        本章所要实现的功能是:使用外部中断1功能通过按键K1控制D2亮灭,K4按键控制D3亮灭,D1指示灯闪烁提示系统运行状态。

void EXTI1_Init(void) { EALLOW; SysCtrlRegs.PCLKCR3.bit.GPIOINENCLK = 1; // GPIO input clock EDIS; EALLOW; //KEY端口配置 GpioCtrlRegs.GPAMUX1.bit.GPIO12=0; GpioCtrlRegs.GPADIR.bit.GPIO12=0; GpioCtrlRegs.GPAPUD.bit.GPIO12=0; GpioCtrlRegs.GPAQSEL1.bit.GPIO12 = 0; // 外部中断1(XINT1)与系统时钟SYSCLKOUT同步 GpioCtrlRegs.GPBMUX2.bit.GPIO48=0; GpioCtrlRegs.GPBDIR.bit.GPIO48=1; GpioCtrlRegs.GPBPUD.bit.GPIO48=0; GpioDataRegs.GPBCLEAR.bit.GPIO48=1; EDIS; EALLOW; GpioIntRegs.GPIOXINT1SEL.bit.GPIOSEL = 12; // XINT1是GPIO12 EDIS; EALLOW; // 修改被保护的寄存器,修改前应添加EALLOW语句 PieVectTable.XINT1 = &EXTI1_IRQn; EDIS; // EDIS的意思是不允许修改被保护的寄存器 PieCtrlRegs.PIEIER1.bit.INTx4 = 1; // 使能PIE组1的INT4 XIntruptRegs.XINT1CR.bit.POLARITY = 0; // 下降沿触发中断 XIntruptRegs.XINT1CR.bit.ENABLE= 1; // 使能XINT1 IER |= M_INT1; // 使能CPU中断1(INT1) EINT; // 开全局中断 ERTM; } interrupt void EXTI1_IRQn(void) { Uint32 i; for(i=0;i<10000;i++); //键盘消抖动 while(!KEY_H1); LED2_TOGGLE; PieCtrlRegs.PIEACK.bit.ACK1=1; } void EXTI2_Init(void) { EALLOW; SysCtrlRegs.PCLKCR3.bit.GPIOINENCLK = 1; // GPIO input clock EDIS; EALLOW; //KEY端口配置 GpioCtrlRegs.GPAMUX1.bit.GPIO13=0; GpioCtrlRegs.GPADIR.bit.GPIO13=0; GpioCtrlRegs.GPAPUD.bit.GPIO13=0; GpioCtrlRegs.GPAQSEL1.bit.GPIO13 = 2; // 外部中断2(XINT2)输入限定6个采样窗口 GpioCtrlRegs.GPACTRL.bit.QUALPRD1 = 0xFF; // 每个采样窗口的周期为510*SYSCLKOUT GpioCtrlRegs.GPBMUX2.bit.GPIO48=0; GpioCtrlRegs.GPBDIR.bit.GPIO48=1; GpioCtrlRegs.GPBPUD.bit.GPIO48=0; GpioDataRegs.GPBCLEAR.bit.GPIO48=1; EDIS; EALLOW; GpioIntRegs.GPIOXINT2SEL.bit.GPIOSEL = 13; // XINT2是GPIO13 EDIS; EALLOW; // 修改被保护的寄存器,修改前应添加EALLOW语句 PieVectTable.XINT2 = &EXTI2_IRQn; EDIS; // EDIS的意思是不允许修改被保护的寄存器 PieCtrlRegs.PIEIER1.bit.INTx5 = 1; // 使能PIE组1的INT5 XIntruptRegs.XINT2CR.bit.POLARITY = 0; // 下降沿触发中断 XIntruptRegs.XINT2CR.bit.ENABLE = 1; // 使能XINT2 IER |= M_INT1; // 使能CPU中断1(INT1) EINT; // 开全局中断 ERTM; } interrupt void EXTI2_IRQn(void) { Uint32 i; for(i=0;i<10000;i++); //键盘消抖动 while(!KEY_H2); LED3_TOGGLE; PieCtrlRegs.PIEACK.bit.ACK1=1; }
#define M_INT1 0x0001 #define M_INT2 0x0002 #define M_INT3 0x0004 #define M_INT4 0x0008 #define M_INT5 0x0010 #define M_INT6 0x0020 #define M_INT7 0x0040 #define M_INT8 0x0080 #define M_INT9 0x0100 #define M_INT10 0x0200 #define M_INT11 0x0400 #define M_INT12 0x0800 #define M_INT13 0x1000 #define M_INT14 0x2000 #define M_DLOG 0x4000 #define M_RTOS 0x8000 //--------------------------------------------------------------------------- // InitPieCtrl: //--------------------------------------------------------------------------- // This function initializes the PIE control registers to a known state. // void InitPieCtrl(void) { // Disable Interrupts at the CPU level: DINT; // Disable the PIE PieCtrlRegs.PIECTRL.bit.ENPIE = 0; // Clear all PIEIER registers: PieCtrlRegs.PIEIER1.all = 0; PieCtrlRegs.PIEIER2.all = 0; PieCtrlRegs.PIEIER3.all = 0; PieCtrlRegs.PIEIER4.all = 0; PieCtrlRegs.PIEIER5.all = 0; PieCtrlRegs.PIEIER6.all = 0; PieCtrlRegs.PIEIER7.all = 0; PieCtrlRegs.PIEIER8.all = 0; PieCtrlRegs.PIEIER9.all = 0; PieCtrlRegs.PIEIER10.all = 0; PieCtrlRegs.PIEIER11.all = 0; PieCtrlRegs.PIEIER12.all = 0; // Clear all PIEIFR registers: PieCtrlRegs.PIEIFR1.all = 0; PieCtrlRegs.PIEIFR2.all = 0; PieCtrlRegs.PIEIFR3.all = 0; PieCtrlRegs.PIEIFR4.all = 0; PieCtrlRegs.PIEIFR5.all = 0; PieCtrlRegs.PIEIFR6.all = 0; PieCtrlRegs.PIEIFR7.all = 0; PieCtrlRegs.PIEIFR8.all = 0; PieCtrlRegs.PIEIFR9.all = 0; PieCtrlRegs.PIEIFR10.all = 0; PieCtrlRegs.PIEIFR11.all = 0; PieCtrlRegs.PIEIFR12.all = 0; } //--------------------------------------------------------------------------- // InitPieVectTable: //--------------------------------------------------------------------------- // This function initializes the PIE vector table to a known state. // This function must be executed after boot time. // void InitPieVectTable(void) { int16 i; Uint32 *Source = (void *) &PieVectTableInit; Uint32 *Dest = (void *) &PieVectTable; EALLOW; for(i=0; i < 128; i++) *Dest++ = *Source++; EDIS; // Enable the PIE Vector Table PieCtrlRegs.PIECTRL.bit.ENPIE = 1; } /* * 函 数 名 : main * 函数功能 : 主函数 * 输 入 : 无 * 输 出 : 无 */ void main() { int i=0; InitSysCtrl(); InitPieCtrl(); IER = 0x0000; IFR = 0x0000; InitPieVectTable(); LED_Init(); EXTI1_Init(); EXTI2_Init(); while(1) { i++; if(i%2000==0) { LED1_TOGGLE; } DELAY_US(100); } }

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/123072.html

(0)
上一篇 2025-10-11 21:15
下一篇 2025-10-11 21:26

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注微信