基于C语言设置TMS320 DSP中断向量表
DSP中断向量表和中断子向量表(精)

DSP中断向量表和中断子向量表DSP中断向量表和中断子向量表类别:单片机/DSP本案例在介绍数字PID控制器和模糊Pl控制器的DSP应用程序设计的同时,还介绍TI公司C2000系列DSP芯片开发时,中断向量表和中断子向量表的编写和配置方法。
一个实用DSP程序除包括主程序和系统初始化程序以及存储器配置文件之外,还需要有中断向量表和中断子向量表程序,对于一个DSP控制器来说,中断的使用和管理是不可缺少的。
在系统中,控制器的作用就是控制整个系统实时、有序地按照程序的要求运行,而DSP只有一个CPU,所以只有L个进程,当外部设各要求DSP控制时,就采用中断的方式,DSP根据中断的优先级,通过响应中断并执行中断服务子程序(ISR)来对外部设各进行控制。
一个正确的中断向量表和中断子向量表程序能够使系统正常运行,并能保证在系统不正常时自动恢复到程序初始化的状态,防止系统崩溃,提高工业控制的鲁棒性。
DSP LF2407有两级中断,第一级中断是CPU中断,共6个;第二级中断是外围设各中断,共46个。
由外设中断扩展控制器(PIE)和中断子向量表把外围设备中断映射到CPU中断,然后等待CPU的响应。
此外CPU中断向量表还包括19个软件中断和硬件复位中断(Reset)以及一个不可屏蔽申断(NMI)。
这种两级中断是采用集中化的中断扩展设计方法,特别适合有大量外设中断的工业控制系统。
以下就是采用通用定时器GPTI的比较操作来产生中断时,LF2407的中断向量表和申断子向量表程序。
当需要采用其他中断时,可以直接在此程序中根据需要修改。
该程序对LF2407来说是通用的,只是发生中断时,CPU要跳转的地址不一样而已。
对于一个实际的DSP系统来说,系统的中断管理是不可缺少的,因为目前任何DSP实时系统都具有中断,中断是DSP系统和外部世界发生实时联系的一个重要手段。
作为TI公司的C2000系列DSP,它是偏向于控制的DSP 芯片,因此它的中断管理更丰富和先进,读者理解起来也较困难。
TMS320F2812中断系统分析及其C语言编程

paper @mesnet. com. cn (投稿专用)
7 5 2008 年第 2 期 Microcontrollers & Embedded Systems
第 3 阶段 , 执行中断服务程序 。中断响应后 , F2812 根据中断向量表取出中断服务程序 ( ISR) 的入口地址 ,然 后转入 ISR 中执行 。
T M S 320 F2812 中 断 系 统 分析及其 C 语言编程
■华东交通大学 吴鹏 左丽霞
摘 要 关键词
中断处理是 DSP 应用系统中必不可少的一个重要环节 。本文阐述 DSP 芯片 TMS320 F2812 的中断机制 和中断处理过程 ,并给出用 C 语言编程实现中断处理过程的思路和实例 。
PIEAC K. bit . AC K2 ; 外设 级中 断 标志 寄 存 器 相 应 位 是
Eva Regs. EVAIFRA. bit . T1 PIN T ,中断使能寄存器相应
位是 Eva Regs. EVAIMRA. bit . T1 PIN T 。
参考程序如下 :
# include " DSP28_Device. h" / 3 定义了所需寄存器 3 /
说明 :定时器 1 周期中断 ( TIPIN T) , CU P 级中断对
应的是 IN T2 ; PIE 级中断标志寄存器相应位是 PieCt rl .
PIEIFR2. bit . IN Tx4 ,中断使能寄存器相应位是 PieCt rl .
PIEIER2. bit . IN Tx4 , 响 应 寄 存 器 相 应 位 是 PieCt rl .
括所有软件中断 ( IN TR 、TRA P 指令) 、硬件中断 NMI、非 法指令 中 断 ( ILL I GAL ) 和 硬 件 复 位 中 断 ( Reset ) 。当 F2812 检测到不可屏蔽中断时 ,会立即转入相应的中断服 务子程序 。
浅谈TMS320C6000系列中断设置问题

浅谈TMS320C6000系列中断设置问题本文只要是关于TMS320C6000和DSP的相关介绍,并着重对TMS320C6000系列中断设置问题进行了详尽的阐述。
DSP随着DSP(数字信号处理器)系统的广泛应用,其程序规模也随之不断扩大,使用芯片本身自带的Boot-loader通过Flash存储器来引导DSP程序,往往受到程序大小和结构的制约,比如程序很大超过厂商固化boot的范围,再如中断向量表的不同位置对程序boot 跳转的影响,等等,因此越来越需要更加灵活的引导方式。
系统上电后,由引导程序将DSP的应用程序从该存储器引导到DSP应用板上的高速存储器(如内部SRAM、SDRAM等)中。
由于Flash存储器具有电信号删除功能,且删除速度快,集成度高,因此已成为此种存储器的首选。
由于Flash存储器的存取速度较慢,写入Flash存储器的程序将在系统上电时被DSP装载到快速的存储器中运行,这个过程称为Boot loader。
不同的DSP有不同的引导方式。
DSP编程DSP系统的引导装载是指在系统加电后,系统自行将一段存储在外部非易失性存储器中的代码移植到内部DSP的高速RAM中并执行的过程。
因此,在引导装载系统中,外部非易失性存储器和DSP的性能显得尤为重要。
FLASH存储器是一种高密度、非易失性的电可擦写存储器。
而且单位存储比特的价格比传统的EPROM要低,所以十分适合于作为外扩存储器。
在系统加电之前,必须先将引导程序和用户程序写入FLASH中。
编程时,除了可以利用专用的硬件编程器实现对FLASH的编程之外,FLASH通常还支持DSP软件编程以实现同样的功能。
当系统加电之后,一般首先在FLASH中运行引导程序,并由其自行完成对用户程序的移植操作,然后再由DSP高速运行移人到DSP片内的用户程序。
DSP编程技巧mposerStudio)是TI公司开发的一个完整的DSP集成开发环境。
由于TI 的DSP使用非常广泛,使得CCS也就成为使用最为广泛的DSP开发软件之一。
基于C语言的TMS320DM6437 DSP中断向量表设置

基于C语言的TMS320DM6437 DSP中断向量表设置许丽华;李爱华【期刊名称】《邢台职业技术学院学报》【年(卷),期】2011(028)003【摘要】针对发展迅速的DSP技术,采用C语言开发DSP芯片,不仅大大提高了DSP芯片的开发速度,也使得程序的修改和移植变得十分方便。
在C64x+系列DSP芯片中,一般采用DSP/BIOS设置硬件中断,采用高级语言C语言设置DM6437中断向量表,给出了中断向量表的设置步骤,开发结果表明,它具有可读性、可移植性,易于维护和修改的特点。
%With the development of DSP technology,adopting C language to exploit DSP not only accelerates the evolution of DSP,but also makes the program modify and transplant easily.In C64x +series,DSP / BIOS is used to set hardware interrupt.In this paper,adopting C language to set DM6437 interrupt vector table,gives the setting steps for interrupt vector table.The application result shows that it has the characteristics of easy reading,good transferability,simple maintenance and modification.【总页数】5页(P91-95)【作者】许丽华;李爱华【作者单位】邢台职业技术学院机电工程系,河北邢台050035;军械工程学院电气工程系,河北石家庄050003【正文语种】中文【中图分类】TP312【相关文献】1.基于DSP和C语言的变压器振动信号采集与分析系统 [J], 陶新民;李震;姜述杰2.探析基于C语言的DSP程序设计 [J], 张新3.基于C语言的DSP嵌入式系统研究 [J], 张朝鑫4.基于DSP环境下C语言的编程优化 [J], 朱业腾5.基于C语言的DSP程序设计研究 [J], 刘智勇因版权原因,仅展示原文概要,查看原文内容请购买。
DSP(TMS320C6713)入门之旅三、中断的理解和使用

学习一个芯片的功能时,我的建议是先学会如何用C语言点亮一个LED灯,然后就是学习一下使用他的中断,因为在做芯片的时候,各个厂家有自己的一套自己的方法。
所以使用中断的就必须了解很多概念,比如如何打开中断,如何安装自己的中断子服务程序,等等!先介绍一下什么叫中断:你在下象棋,突然电话响了,你回屋接电话,然后回来继续下象棋,这个过程就叫做中断响应过程(中断过程)。
CPU执行正常任务———————下象棋保护现场———————————-你已经想好要―将军‖,先在脑海中记下来。
中断发生———————————-电话响-中断服务程序—————————-接电话恢复现场———————————-回来后恢复刚才想法中断返回———————————-你回来继续下象棋中断屏蔽———————————-Boss 正在训话,要求所有电话关机,你不能接电话了。
非屏蔽中断——————————-你内急,即使是Boss 在训话,你还是得到外面去嘘嘘。
可屏蔽中断——————————-你在―闭关修炼‖,可以不受外界干扰所以我们在使用中断之前先得告诉CPU,我们要使用那个中断,当中断发生的时候,你的执行程序的去向(也就是中断服务子程序),最后在返回我们被中断的函数。
这样就完成了我们的中断历程!看看6713执行中断的流程:一、使能了全局中断和子中断,那么CPU每执行一条指令之前就去查询一下有没有中断被置位,如果有产生的,那么CPU就要跳转!二、软件把CPU内部的寄存器A0~A15,B0~B15,等等这些寄存器的值推入堆栈保存,把当前PC寄存器的值放入IRP寄存器中以备中断返回能找到当前被打断的位置(保存现场,中断函数前面得加interrupt关键字)三、CPU的PC指针读出中断向量表的地址,也就是把(ISTP寄存器的值+子中断向量偏移量)装入PC寄存器,这样就执行跳转。
四、在中断向量表里一般有就用跳转指令,这样就可以跳转到我们用C语言编写的中断服务子程序中。
基于TMS320F28335外部中断配置过程

基于TMS320F28335外部中断配置过程TMS320F28335外部中断的配置关键void main(void){// Step 1. Initialize System Control:InitSysCtrl();// Step 3. Clear all interrupts and initialize PIE vector table: DINT; //禁止全局中断InitPieCtrl();//初始化PIE模块//清除CPU寄存器IER = 0x0000;IFR = 0x0000;//初始化中断服务表InitPieVectTable();//指向PIE向量。
表注意EALLOW和EDIS的使用,要不中间写的都无效的EALLOW; // This is needed to write to EALLOW protected registers PieVectTable.XINT1 = &xint1_isr;PieVectTable.XINT2 = &xint2_isr;EDIS; // This is needed to disable write to EALLOW protected registers // 清除计数Xint1Count = 0; // Count Xint1 interruptsXint2Count = 0; // Count XINT2 interruptsLoopCount = 0; // Count times through idle loop// Enable Xint1 and XINT2 in the PIE: Group 1 interrupt 4 & 5 // Enable int1 which is connected to WAKEINT:PieCtrlRegs.PIECTRL.bit.ENPIE = 1; // Enable the PIE blockPieCtrlRegs.PIEIER1.bit.INTx4 = 1; // Enable PIE Gropu 1 INT4PieCtrlRegs.PIEIER1.bit.INTx5 = 1; // Enable PIE Gropu 1 INT5 IER |= M_INT1; // Enable CPU int1EINT;//使能全局中断// Enable Global Interrupts//初始化GPIOEALLOW;GpioCtrlRegs.GPAMUX1.bit.GPIO15 = 0; // GPI15 修改GpioCtrlRegs.GPADIR.bit.GPIO15 = 0; // inputGpioCtrlRegs.GPAQSEL1.bit.GPIO15 = 0; // Xint1 Synch to SYSCLKOUT onlyGpioCtrlRegs.GPAMUX1.bit.GPIO1 = 0; // GPIO1GpioCtrlRegs.GPADIR.bit.GPIO1 = 0; // inputGpioCtrlRegs.GPAQSEL1.bit.GPIO1 = 2; // XINT2 Qual using 6 samplesGpioCtrlRegs.GPACTRL.bit.QUALPRD0 = 0xFF; // Each sampling window is510*SYSCLKOUTEDIS;//配置GPIO中断EALLOW;GpioIntRegs.GPIOXINT1SEL.bit.GPIOSEL = 15;//配置GPIO寄存器GPIOXINT1SEL把GPIO15作为Xint1中断GpioIntRegs.GPIOXINT2SEL.bit.GPIOSEL = 1; // XINT2 is GPIO1 //配置GPIO寄存器GPIOXINT2SEL把GPIO1作为Xint2中断EDIS;// Configure XINT1XIntruptRegs.XINT1CR.bit.POLARITY = 0; // Falling edge interrupt XIntruptRegs.XINT2CR.bit.POLARITY = 1; // Rising edge interrupt// Enable XINT1 and XINT2XIntruptRegs.XINT1CR.bit.ENABLE = 1; // Enable Xint1XIntruptRegs.XINT2CR.bit.ENABLE = 1; // Enable XINT2// Step 6. IDLE loop:for(;;){}}interrupt void xint1_isr(void){}interrupt void xint2_isr(void)}------------------------------------------------------------------------------------------------------------------------------------------ GpioDataRegs.GPBCLEAR.all = 0x4; // GPIO34 is low Xint2Count++; PieCtrlRegs.PIEACK.all = PIEACK_GROUP1; GpioDataRegs.GPBCLEAR.all = 0x4; // GPIO34 is low Xint1Count++;PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;void InitPieCtrl(void){// Disable Interrupts at the CPU level:DINT;// Disable the PIEPieCtrlRegs.PIECTRL.bit.ENPIE = 0;}//---------------------------------------------------------------------------// EnableInterrupts: // 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; // 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;//---------------------------------------------------------------------------// This function enables the PIE module and CPU interrupts//void EnableInterrupts(){// Enable the PIEPieCtrlRegs.PIECTRL.bit.ENPIE = 1;}const struct PIE_VECT_TABLE PieVectTableInit =PIE_RESERVED, // 0 Reserved spacePIE_RESERVED, // 1 Reserved spacePIE_RESERVED, // 2 Reserved spacePIE_RESERVED, // 3 Reserved spacePIE_RESERVED, // 4 Reserved spacePIE_RESERVED, // 5 Reserved spacePIE_RESERVED, // 6 Reserved spacePIE_RESERVED, // 7 Reserved spacePIE_RESERVED, // 8 Reserved spacePIE_RESERVED, // 9 Reserved spacePIE_RESERVED, // 10 Reserved spacePIE_RESERVED, // 11 Reserved spacePIE_RESERVED, // 12 Reserved space// Non-Peripheral InterruptsINT13_ISR, // XINT13 or CPU-Timer 1INT14_ISR, // CPU-Timer2DATALOG_ISR, // Datalogging interrupt // Enable Interrupts at the CPU level EINT; // Enables PIE to drive a pulse into the CPU PieCtrlRegs.PIEACK.all = 0xFFFF;RTOSINT_ISR, // RTOS interruptEMUINT_ISR, // Emulation interruptNMI_ISR, // Non-maskable interruptILLEGAL_ISR, // Illegal operation TRAPUSER1_ISR, // User Defined trap 1USER2_ISR, // User Defined trap 2USER3_ISR, // User Defined trap 3USER4_ISR, // User Defined trap 4USER5_ISR, // User Defined trap 5USER6_ISR, // User Defined trap 6USER7_ISR, // User Defined trap 7USER8_ISR, // User Defined trap 8USER9_ISR, // User Defined trap 9USER10_ISR, // User Defined trap 10USER11_ISR, // User Defined trap 11USER12_ISR, // User Defined trap 12// Group 1 PIE VectorsSEQ1INT_ISR, // 1.1 ADCSEQ2INT_ISR, // 1.2 ADCrsvd_ISR, // 1.3XINT1_ISR, // 1.4XINT2_ISR, // 1.5ADCINT_ISR, // 1.6 ADCTINT0_ISR, // 1.7 Timer 0WAKEINT_ISR, // 1.8 WD, Low Power// Group 2 PIE VectorsEPWM1_TZINT_ISR, // 2.1 EPWM-1 Trip ZoneEPWM2_TZINT_ISR, // 2.2 EPWM-2 Trip ZoneEPWM3_TZINT_ISR, // 2.3 EPWM-3 Trip ZoneEPWM4_TZINT_ISR, // 2.4 EPWM-4 Trip ZoneEPWM5_TZINT_ISR, // 2.5 EPWM-5 Trip ZoneEPWM6_TZINT_ISR, // 2.6 EPWM-6 Trip Zone rsvd_ISR, // 2.7 rsvd_ISR, // 2.8// Group 3 PIE VectorsEPWM1_INT_ISR, // 3.1 EPWM-1 InterruptEPWM2_INT_ISR, // 3.2 EPWM-2 InterruptEPWM3_INT_ISR, // 3.3 EPWM-3 InterruptEPWM4_INT_ISR, // 3.4 EPWM-4 InterruptEPWM5_INT_ISR, // 3.5 EPWM-5 InterruptEPWM6_INT_ISR, // 3.6 EPWM-6 Interruptrsvd_ISR, // 3.7rsvd_ISR, // 3.8// Group 4 PIE VectorsECAP1_INT_ISR, // 4.1 ECAP-1 ECAP2_INT_ISR, // 4.2 ECAP-2 ECAP3_INT_ISR, // 4.3 ECAP-3 ECAP4_INT_ISR, // 4.4 ECAP-4 ECAP5_INT_ISR, // 4.5 ECAP-5 ECAP6_INT_ISR, // 4.6 ECAP-6 rsvd_ISR, // 4.7rsvd_ISR, // 4.8// Group 5 PIE VectorsEQEP1_INT_ISR, // 5.1 EQEP-1 EQEP2_INT_ISR, // 5.2 EQEP-2 rsvd_ISR, // 5.3rsvd_ISR, // 5.4rsvd_ISR, // 5.5rsvd_ISR, // 5.6rsvd_ISR, // 5.7rsvd_ISR, // 5.8// Group 6 PIE VectorsSPIRXINTA_ISR, // 6.1 SPI-A SPITXINTA_ISR, // 6.2 SPI-A MRINTA_ISR, // 6.3 McBSP-A MXINTA_ISR, // 6.4 McBSP-A MRINTB_ISR, // 6.5 McBSP-B MXINTB_ISR, // 6.6 McBSP-Brsvd_ISR, // 6.7rsvd_ISR, // 6.8// Group 7 PIE VectorsDINTCH1_ISR, // 7.1 DMA channel 1DINTCH2_ISR, // 7.2 DMA channel 2 DINTCH3_ISR, // 7.3 DMA channel 3 DINTCH4_ISR, // 7.4 DMA channel 4 DINTCH5_ISR, // 7.5 DMA channel 5 DINTCH6_ISR, // 7.6 DMA channel 6 rsvd_ISR, // 7.7rsvd_ISR, // 7.8// Group 8 PIE VectorsI2CINT1A_ISR, // 8.1 I2CI2CINT2A_ISR, // 8.2 I2Crsvd_ISR, // 8.3rsvd_ISR, // 8.4SCIRXINTC_ISR, // 8.5 SCI-C SCITXINTC_ISR, // 8.6 SCI-Crsvd_ISR, // 8.7rsvd_ISR, // 8.8// Group 9 PIE VectorsSCIRXINTA_ISR, // 9.1 SCI-A SCITXINTA_ISR, // 9.2 SCI-A SCIRXINTB_ISR, // 9.3 SCI-B SCITXINTB_ISR, // 9.4 SCI-B ECAN0INTA_ISR, // 9.5 eCAN-A ECAN1INTA_ISR, // 9.6 eCAN-A ECAN0INTB_ISR, // 9.7 eCAN-B ECAN1INTB_ISR, // 9.8 eCAN-B// Group 10 PIE Vectorsrsvd_ISR, // 10.1rsvd_ISR, // 10.2rsvd_ISR, // 10.3rsvd_ISR, // 10.4rsvd_ISR, // 10.5rsvd_ISR, // 10.6rsvd_ISR, // 10.7rsvd_ISR, // 10.8// Group 11 PIE Vectorsrsvd_ISR, // 11.1rsvd_ISR, // 11.2rsvd_ISR, // 11.3rsvd_ISR, // 11.4rsvd_ISR, // 11.5rsvd_ISR, // 11.6rsvd_ISR, // 11.7rsvd_ISR, // 11.8// Group 12 PIE VectorsXINT3_ISR, // 12.1XINT4_ISR, // 12.2XINT5_ISR, // 12.3XINT6_ISR, // 12.4XINT7_ISR, // 12.5rsvd_ISR, // 12.6LVF_ISR, // 12.7LUF_ISR, // 12.8};//---------------------------------------------------------------------------// InitPieVectTable://---------------------------------------------------------------------------// This function initializes the PIE vector table to a known state. // This function must be executed after boot time.//void InitPieVectTable(void){} // Enable the PIE Vector Table PieCtrlRegs.PIECTRL.bit.ENPIE = 1; int16 i; Uint32 *Source = (void *) &PieVectTableInit; Uint32 *Dest = (void *) &PieVectTable; EALLOW; for(i=0; i < 128; i++) *Dest++ = *Source++; EDIS;。
DSP中断设置示例简明教程

DSP中断设置示例简明教程DSP中断设置简明教程作者:wuzhenzhi一、简述本文介绍TMS320C6000系列中断设置的简明方法。
通过示例定时器中断,MCBSP串口接收中断及外部中断这三种中断实现过程,介绍如何实现中断各个寄存器的配置,中断向量表书写以及中断服务函数。
最后提供一个简要的示例程序可供大家下载使用。
此示例在DSK6416的TI官方实验板上通过测试。
由于定时器和串口工作模式较繁,因此对中断无关部分不做介绍。
二、实现DSP中断需要做哪些通用工作设置允许哪些非屏蔽中断设置各个允许的非屏蔽中断的中断来源设置开启总中断设计中断向量表将中断向量表通过cmd文件挂载到指令内存提供中断处理函数如果中断向量表首地址挂载的不是0地址,那么需要设置中断向量表地址寄存器对于不同的中断源,需要做各个自己的工作,比如如果是外部中断,那么需要设置管脚极性,即由高->低产生中断抑或反之。
为了照顾知识较少的读者,下面将从一个新工程出发,引导大家建立一个中断示例程序。
如果您对建立工程很熟悉,可以跳过此步。
三、建立新工程1.点击Project->New,设置Project Name为intexample,Project Type为Executable,Target 选择您需要的器件,在此由于本人使用的是DSK6416评估板。
因此选择TMS320C64XX。
2.添加标准库rts6400.lib,以便自动产生c_int00等函数。
右击当前工程,选择“Add Files to Project”,选择库所在路径,一般为CCS 安装自带,可参考本CCS3.1版本的路径地址:\CCStudio_v3.1\C6000\cgtools\lib\rts6400.lib如果您使用的是其他器件类型,请在lib文件夹内选择其他器件库。
添加源文件,选择File->New->Source File,保存为main.c到工程路径下。
dsp 中断向量表

中断向量表单片机的程序一般情况下上电之后是从0x0地址开始运行的,而0x0后面是关于硬件的一些对应的中断的入口地址。
所以中断向量表其实就是硬件查表跳转表,相当于C语言的switch 语句。
如:Switch(i){Case 0: goto reset;Case 1: goto int0 ;….}关于I的值就是硬件给出的中断向量。
2406中断向量表:.ref _bad_trap.ref _c_int0.sect "vectors" ;自定义段名_vector: ;向量表地址标识RSVECT B _c_int0 ;C项目初始化入口地址INT1 B _bad_trap ;没有用到的中断跳转到非法中断陷阱INT2 B _bad_trapINT3 B _PM6 ;有用到的中断,则写其实际中断的地址或标号INT4 B _bad_trap ; PM 8 Int level 4 7INT5 B _bad_trap ; PM A Int level 5 8INT6 B _bad_trap ; PM C Int level 6 9……..endPAGE 0 : /* program memory */ VECS: origin = 00000h, length = 0007Fhvectors : > VECS PAGE = 0这样就可以把中断向量表写到正确的地址。
.ref _bad_trap 这个标号外部没有定义,为什么还用.ref,而不是用..global?因为_bad_trap在这里只是声明函数,它实际函数可能是.C文件里的bad_trap()函数。
CPU中断向量地址和外设中断向量PIV有什么不同?什么是外设中断向量PIV?一个CPU中断包括好几个外设中断,如INT1包括了PDPINTA、PDPINTB、ADCINT、XINT1、XINT2、SPIINT、RXINT、TXINT、CANMBINT、CANERINT。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
基于C语言设置TMS320 DSP中断向量表1、引言DSP(数字信号处理器)自二十世纪70年代末80年代初诞生以来,得到了突飞猛进的发展,在信号处理、通讯、雷达等方面应用越来越广泛,而且开发手段和开发设备也越来越多样化。
其中C语言在DSP开发应用中起着越来越重要的作用,以C语言编写的DSP应用程序具有可读性、可移植性,易于维护和修改。
另外在DSP应用系统中,中断是完成数据传递、实时处理等的重要手段,因而用C语言完成对DSP中断设置是DSP开发的重要内容。
DSP中断的设置主要包括中断服务程序的编写,中断向量表的设置,中断寄存器的初始化等内容。
本文以TI公司TMS320系列DSP为例,说明用C语言设置中断向量表的方法。
并给出实例进行说明。
2、中断向量表的定位中断服务程序的地址(中断向量)要装载到存储器的合适区域。
一般这些向量都定位在0x0开始的程序存储器中。
但有些处理器要求或者可以在其他的存储区域安装中断向量。
对于微处理器模式下的TMS320C25、TMS320C26、TMS320C28、TMS320C30、TMS320C31,中断向量定位于0x0开始的地址。
对于微计算机/程序引导模式下的TMS320C31的中断向量定位于0x809fc1,TMS320C26的中断向量定位于0xffa0。
TMS320C5X复位向量定位在0x0,其他中断向量可以定位于任何2K字的程序存储器中,中断向量表的定位是与PMST寄存器的IPTR位有关,有效的中断向量表的基地址是0x0,0x800,0x1000,0x1800,0x2000,…0xf800。
TMS320C4X的复位向量定位在四个地址之一,这四个地址由外部引脚RESETLOC0和RESETLOC1决定。
TMS320C4X的中断向量可存在于任何512字范围的存储器中,中断向量表的地址由中断向量表指针(IVTP)寄存器决定。
另外,TMS320C4X的自陷(trap)中断向量可存放在512字范围的存储器中,自陷向量表的地址由自陷向量表指针(TVTP)寄存器决定。
有效的中断或者自陷向量表的基地址是0x0,0x200,0x400,0x800,0xa00,0xc00,0xe00,0x1000,0x1200…0xfffffe00,如表1所示。
有两种方法可以初始化中断向量表,下面讲解这两种方法:方法一:利用已命名的ASM段生成向量表的最直接方法就是用汇编指令.sect来生成一个表。
这个表包含中断向量的地址和跳转指令。
表1处理器向量表基地址说明TMS320C2X 0x0 不包括微计算机/程序引导模式下的TMS320C26TMS320C26 0xffa0 微计算机/程序引导模式TMS320C30 0x0TMS320C31 0x0 微处理器模式TMS320C31 0x809fc1 微计算机/程序引导模式TMS320C4X 复位0x0,0x7fffffff,0x80000000,0xfffffff 外部引脚RESETLOC0和RESETLOC1决定中断向量任意512字范围IVTP寄存器决定自陷向量任意512字范围TVTP寄存器决定TMS320C5X 复位0x0中断向量任意2K字数据页PMST寄存器的IPTR位决定在微计算机/程序引导模式下TMS320C2X、TMS320C5X和TMS320C31 从中断向量的位置处执行代码,因而要用跳转指令来代替中断向量,如TMS320C31用24位指令BR来实现:INT1:BR _c_int01在微处理器模式下TMS320C30、TMS320C31和TMS320C4X,中断向量是下一条存取指令的地址,因而中断服务程序的地址用汇编指令.word存储在中断向量处。
例如,TMS320C4X 中断1 可用汇编语言定义如下:INT1:.word _c_int01因为中断服务的标识符在汇编语言模块外部被声明,所以标识符必须用.ref或.global 来声明。
下面的例子是一个汇编语言模块(vecs.asm)定义了一个包含TMS320C5X跳转指令的段。
.ref _c_int0, _c_int1 ;在外部定义中断向量.sect “vectors” ;声明一个一命名的段RS: b _c_int0 ;转至复位向量I1: b _c_int1 ;转至中断向量1处理保留和未使用的区域有时中断向量表中包含保留的地址,例如微计算机/程序引导模式下的TMS320C26或者TMS320C4X和TMS320C5X的复位和中断向量不连续的情形。
TMS320C31也会发生这种情形,系统中并不是所有的中断都能被用到。
为了处理向量映象中的保留地址,就要使用汇编指令.space。
注意对于定点设备.space保留的是位,对于浮点设备.space保留的字。
例如,微计算机/程序引导模式下TMS320C26,假设所有中断都是可用的.sect “vectors” ;为复位和中断向量定义已命名的段.space 2*16 ;保留的空间b _c_int1 ;INT0b _c_int2 ;INT1b _c_int3 ;INT2b _c_int4 ;TINTb _c_int5 ;RINTb _c_int6 ;XINTb _c_int7 ;TRAP注意.space指令为复位向量保留的位置在程序引导方式下不能使用,因为复位会启动程序引导功能。
使用.space时vectors段链接到0xfa00,不使用.space指令该段链接到0xfa02。
但是,如果定时器和自陷中断向量被使用时,可用.space指令对向量表进行如下的定义:.sect “vectors” ;为复位和中断向量定义已命名的段.space 2*4*16 ;保留的和3个未使用的向量b _c_int4 ;TINT.space 2*2*16 ;2个未使用的向量b _c_int7 ;TRAP注意在中断和自陷向量表中未使用的部分可用来存储数据。
但为了保证中断处理的正确,一定要确保中断和自陷向量不被破坏。
链接到存储器映象已命名段产生后,TMS320链接器就会把向量表链接到存储器的合适位置,共分三步进行:1. 链接汇编语言模块;2. 根据中断向量表的定位定义链接器的MEMORY段;3. 在链接器的SECTIONS命令中,定位这些已命名的段。
下面是TMS320C5X的命令文件,将vectors定位到040h。
-cvecs.objmain.obj-l rts50.libMENORY{PAGE0:VECTORS:origin = 0000h, length = 003fhROM :origin = 0040h, length = 007cfh}SECTIONS{“vectors” :{}> VECTORS.text :{}> ROM.}方法二:安装一个运行时的向量这种方法在开发和调试时很有用的,这种方法是用C语句在装载中断服务程序地址时建立一个运行时的向量。
该方法适用于微处理器模式下的TMS320C30和TMS320C31,以及TMS320C4X,因为它们只用地址,而不用跳转指令作为中断向量。
其重点就是将中断服务程序的地址放到合适的存储器空间,例如,TMS320C30地址0x1对应于外部中断0(INT0),在该地址安装中断服务程序c_int01。
使用如下语句“*((void (**) () )0x1) = c_int01;这里,0x1被转换成指向函数的指针,因为它包含函数c_int01的地址。
3、向量表指针TMS320C4X和TMS320C5X都可以不将中断向量表放在0x0开始的位置。
这两个系列的DSP 都是由寄存器来确定中断向量的位置。
TMS320C4X的复位向量地址是由处理器的引脚确定的四个地址中的一个。
中断能够被正确的处理,首先必须在接收到中断之前对中断向量表进行初始化。
下面几个例子是用来说明初始化与中断有关的寄存器的方法。
例1:在C中嵌入汇编语句这个例子,利用在C语言中嵌入汇编语句来设置TMS320C4X的中断向量,其起始地址为0x0,方法是通过将IVTP寄存器的值设置为0x0。
asm(“ PUSH R0”);asm(“ LDI 0h, R0”);asm(“ LDPE R0, IVTP”);asm(“ POP R0”);例2:利用TMS320C4X的PRTS这个例子,利用TMS320C4X的并行运行支持库来设置中断向量表,起始地址为0x02ff800,利用PRTS库函数set_ivtp()设置IVTP寄存器的值使向量表定位于RAM0存储器的开始地址。
当使用PRTS时,不需要用户命名中断向量段,而是在运行时使用PRTS函数install_int_vector()将向量定位在预先定义的段.vector中。
这种方法要求向量在运行时安装,以防止程序和数据被修改。
另外,首先要把PRTS库链接到程序,并在命令文件中预先定义.vector段,把.vector段定位在ROM0存储器的开始地址。
命令文件如下所示:-l prts40.libMEMORY{RAM0:org = 0x2ff800 , len = 0x400}SECTIONS{“.vector”: {} > RAM0}主程序中必须包含头文件intpt40.h。
函数set_ivtp()使用预定义的参量DEFAULT才能被调要,这样设置IVTP寄存器可使.vector段按命令文件中定义定位。
中断向量可使用函数install_int_vector()来安装,如下所示:#include <intpt40.h>void c_int99(void){for( ; ; );}void main(void){set_ivtp(DEFAULT);install_int_vector((void *) c_int99,2);例3:链接时指定TMS320C4X或TMS320C5X的符号当TMS320C5X的编辑器中没有PRTS库而不能设置向量表指针时,还有一个方便的方法可以达到同样的目的。
那就是使用在链接时指定符号的方法。
这种方法的主要思想是利用包含复位和中断向量的汇编语言段(.sect)以及用链接器映射中断向量在内存中的分布。
C程序可以获得这个地址并把它装载到中断向量表指针(TMS320C4X的IVTP寄存器或者TMS320C5X的PMST寄存器)。
本例为TMS320C5X芯片,中断向量定位于汇编语言模块中,标号IVECS指向中断向量表的基地址,下面说明如何获取中断向量地址。
.def IVECS.ref _c_int0, _c_int1, _c_int2.sect “reset”b _c_int0.sect “vectors”IVECS .space 2b _c_int1b _c_int2在链接器中,用链接器指定的标号初始化链接器定义的变量。