其中M0 Vector、M1 Vector为TI测试时使用,我们可以把它当做一般的存储空间来使用,BROM Vector中对我们有用的就一个复位中断,其它的可以暂不作深入研究。经常使用的为PIE Vector。
上电复位后,在InitBoot中将中断向量列表映射为BROM Vector,在复位和引导完成后,我们应将中断向量列表映射为PIE Vector并将其初始化。器件复位后中断向量列表的配置方法如下图:
F28335复位,在boot完成后,CPU开始执行用户程序,若我们的程序想要CPU相应某一外设的中断,则在我们的程序中我们应该将ENPIE设置为1,使中断向量表映射为PIE Vector,然后初始化PIE中断向量表,在外设级使能外设的相关中断,然后将外设对应的PIEIERx(PIE中断使能寄存器)的相关位设置为1,再将PIEIERx对应的CPU级中断使能寄存器IER的相关位设置为1,将INTM设置为0(开全局中断)。这样,完成这些初始化工作后,CPU就可以相应相关外设的中断了。
CPU相应某一外设的具体流程如下图所示: 在用户主程序的运行中,如果某一外设的中断事件发生,则其相应的中断标志位被置1,如果该外设的中断被使能,则会向PIE模块发出中断请求,PIE中断标志寄存器PIEIFRx相应位PIEIFRx.y被置1,如果相应的PIE中断被使能,即PIE中断使能寄存器PIEIER相应位PIEIERx.y被置1,则再检查PIE中断应答寄存器PIEACK相应为PIEACKx是否为0(PIEACKx为1表示CPU正在响应该组中断,禁止该组其他中断源向CPU发出中断请求;为0,表示该组的中断源可以向CPU发出中断请求),若PIEACKx为0,则置位PIEACKx和CPU中断标志寄存器IFR的相应位IFRx,向CPU发出中断请求,如果相应的CPU中断被使能,即相应的CPU中断标志寄存器IER的相应IERx位被置1,则CPU在查询全局中断屏蔽位INTM是否为0,即全局中断是否打开,若INTM为0,则清0相应的IFRx、IERx,置位INTM,EALLOW置
0,保护现场,读取中断向量,清0相应的PIEIFRx.y,跳转到相应的中断服务程序。在我们的中断服务程序中,我们应该向相应的PIEACKx写1使其清零,即允许同组的其他中断请求,然后将INTM清零,即重新打开全局中断。
用户应做的初始化工作:
这一部分通过CPU响应ePWM1模块由ePWM1Timer的zero event事件产生的EPWM1_INT中断为例来说明用户应做的工作,程序来自TI官网提供的例程epwm_timer_interrupts。 程序中的中文注释说明了用户该做的工作。
下面对工程中与中断有关的内容进行分析,Example_2833xEPwmTimerInt.c文件中与中断有关的内容如下:
进主函数前,声明了中断服务函数,也可以使用TI模板提供的中断服务函数,这里自己定义了中断服务函数,在main()函数前进行了声明:
// Prototype statements for functions found within this file. interrupt voidepwm1_timer_isr(void); 主函数:
void main(void) {
// Disable CPU interrupts
//第一步,关全局中断; DINT;
// Initialize the PIE control registers to their default state. // The default state is all PIE interrupts disabled and flags // are cleared.
//第二步,初始化PIE控制寄存器,禁止所有PIE中断并将所有PIE中断标志位清零。 //上述功能由InitPieCtrl()函数完成,函数的实现见 //DSP2833x_PieCtrl.c InitPieCtrl();
// Disable CPU interrupts and clear all CPU interrupt flags: // 第三步,禁止CPU中断并将所有CPU中断标志位清零。 IER =0x0000; IFR =0x0000; // Initialize the PIE vector table with pointers to the shell Interrupt // 第四步,初始化PIE中断向量表,使PIE中断向量表中的每个向量指向 //DSP2833x_DefaultIsr.c.文件中定义的每个中断处理函数。 //将ENPIE置1,使中断向量表映射为PIE Vector,
//上述功能由InitPieVectTable()函数完成,函数的实现见 //DSP2833x_PieVect.c. InitPieVectTable();
// Enable CPU INT3 which is connected to EPWM1_INT //第五步,使能CPU中断INT3,PIE中断EPWM1_INT连接在INT3, // M_INT=0x0004。 IER |= M_INT3;
// Enable EPWM1_INT
//第六步,使能EPWM1_INT。
PieCtrlRegs.PIEIER3.bit.INTx1 = PWM1_INT_ENABLE;
// Enable global Interrupts and higher priority real-time // debug events:
//第七步,开全局中断,开实时中断。
EINT; // Enable Global interrupt INTM
ERTM; // Enable Global realtime interrupt DBGM //第八步,将中断服务函数入口地址写入中断向量表中的EPWM_INT。 EALLOW;
PieVectTable.EPWM1_INT = &epwm1_timer_isr; EDIS;
//至此,初始化工作完成。 ……
}
中断服务函数中用户该做的工作:中断服务函数epwm1_timer_isr中与中断处理有关的内容如下:
interrupt voidepwm1_timer_isr(void) { ...
// Clear INT flag for this timer
//清除ETFLG寄存器中EPWM1_INT中断的中断标志位。 EPwm1Regs.ETCLR.bit.INT =1;
// Acknowledge this interrupt to receive more interrupts // from group 3
//向PIE中断应答寄存器PIEACK的第三位写1清零,以允许同组的其他中 //中断请求。PIEACK_GROUP3=0x0004。
PieCtrlRegs.PIEACK.all= PIEACK_GROUP3; }
3 自己编写或分析某一CMD文件,说明用户对存储器是如何使用的。 这一部分以TI官网提供的例程adc_seq_ovd_test为例,分析该工程的CMD文件,说明用户对存储器的使用。adc_seq_ovd_test工程的头文件包括两个28335_RAM_lnk.cmd 和
DSP2833x_Headers_nonBIOS.cmd,28335_RAM_lnk.cmd对除片内Flash和OTP的存储空间进行了配置,用于调试时将程序下载至RAM中的工程使用。DSP2833x_Headers_nonBIOS.cmd文件对所有外设帧及PIE中断向量表对应的存储空间进行配置,和各个外设的头文件及DSP2833x_GlobalVariableDefs.c文件一起使用,使用户可以方便的操作外设的相关寄存器。 首先,对adc_seq_ovd_test例程的28335_RAM_lnk.cmd文件进行分析,28335_RAM_lnk.cmd文件内容如下,分析见其中的中文注释部分。
/*划分存储空间*/
MEMORY {
PAGE 0 :
/* BEGIN is used for the \
BEGIN : origin = 0x000000, length = 0x000002 /* Boot to M0 will go here
在仿真模式下,boot to M0 的boot方式将使F28335从0x00 0000开始执行程序 在这里放一条跳转指令,指向用户程序的入口地址。 */
RAMM0 : origin = 0x000050, length = 0x0003B0 /*MO区除低80个存储空间外 的存储空间定义为程序存储空间,未使用*/
RAML0 : origin = 0x008000, length = 0x001000
/*片内SARAM L0区*/
RAML1 : origin = 0x009000, length = 0x001000 /*片内SARAM L1区用来存放程序代码*/
RAML2 : origin = 0x00A000, length = 0x001000 /*片内SARAM L2区,定义为程序空间,未使用*/
RAML3 : origin = 0x00B000, length = 0x001000
/*片内SARAM L3区,定义为程序空间,未使用*/
/* LO、L1、L2、L3可被映射到低64K空间,也可被映射到高64K空间,
在本例中,它们被映射到低64K空间*/
ZONE7A : origin = 0x200000, length = 0x00FC00
/* XINTF zone 7 - program space 片外存储空间XINTF zone 7的低63K空间,定义为程序存储空间*/
CSM_RSVD : origin = 0x33FF80, length = 0x000076
/* Part of FLASHA.
Program with all 0x0000 when CSM is in use. 片内FlashROM的一部分,
当CSM模块使用时全写0x0000 */
CSM_PWL : origin = 0x33FFF8, length = 0x000008
/* Part of FLASHA.
CSM password locations in FLASHA 密码安全模块密码的存储空间
*/
ADC_CAL : origin = 0x380080, length = 0x000009
/*ADC_cal()函数来给ADC参考电压选择寄存器ADCRENSEL,ADC校
正寄存器ADCCOFFTRIM根据所使用F28335芯片的需要写入相应的校正数据。boot to flash的boot方式,bootROM将自动
调用该函数,但仿真时,在程序调试时,选择boot to SARAM的boot方式,需要通过 ADC_CAL : origin = 0x380080, length = 0x000009 (1) .adc_cal : load = ADC_CAL, PAGE = 0, TYPE = NOLOAD (2) 及EALLOW; (3)
SysCtrlRegs.PCLKCR0.bit.ADCENCLK = 1; ADC_cal();
SysCtrlRegs.PCLKCR0.bit.ADCENCLK = 1 EDIS;
这三步来调用ADC_cal() */
RESET : origin = 0x3FFFC0, length = 0x000002 /*复位向量指向的空间*/
IQTABLES : origin = 0x3FE000, length = 0x000b50 IQTABLES2 : origin = 0x3FEB50, length = 0x00008c