DSP中断设置简明教程修正版文档格式.docx
- 文档编号:18829997
- 上传时间:2023-01-01
- 格式:DOCX
- 页数:9
- 大小:22.37KB
DSP中断设置简明教程修正版文档格式.docx
《DSP中断设置简明教程修正版文档格式.docx》由会员分享,可在线阅读,更多相关《DSP中断设置简明教程修正版文档格式.docx(9页珍藏版)》请在冰豆网上搜索。
global.h"
到此,一个DSP的新工程框架制作完毕。
4.添加cmd链接文件
为了实现链接时内存配置,我们需要提供一个cmd文件,为了方便,可以从官方的示例程序中拷贝一份,再加以修改。
在安装目录下D:
\CCStudio_v3.1\tutorial\器件类型\hello1示例下,会找到一个hello1.cmd,将其拷贝到本工程目录下,并将其改名为link.cmd,最后将其添加到工程中。
由于此文件没有声明stack和heap,会产生警告,如果动态数据较多也容易溢出。
因此我们最好在此文件提供stack和heap的大小,其值可根据实际情况调整,修改后,此文件内容类似为:
-stack0x1000
-heap0x1000
MEMORY
ISRAM
:
origin=0x0,
len=0x1000000
SECTIONS
.vectors>
ISRAM
.text
>
.bss
.cinit
.const
.far
.stack
.cio
.sysmem
至此,工程建立完毕,可以编译一遍,观察是否正常。
---------------------------
intexample.pjt-Debug
---------------------------
[main.c]"
D:
\CCStudio_v3.1\C6000\cgtools\bin\cl6x"
-g-fr"
/intexample/Debug"
-d"
_DEBUG"
-mv6400-@"
Debug.lkf"
"
main.c"
[Linking...]"
-@"
<
Linking>
BuildComplete,
0Errors,0Warnings,0Remarks.
四、
定时器中断设计
首先,我们先实现一个定时器中断,因为它不受外部影响,容易测试。
在global.h文件中,加入控制寄存器和中断寄存器别名定义,另外为了使用定时器1,也应对其别名进行定义:
/*定义控制寄存器*/
externcregistervolatileunsignedintAMR;
/*AddressModeRegister
*/
externcregistervolatileunsignedintCSR;
/*ControlStatusRegister
externcregistervolatileunsignedintIFR;
/*InterruptFlagRegister
externcregistervolatileunsignedintISR;
/*InterruptSetRegister
externcregistervolatileunsignedintICR;
/*InterruptClearRegister
externcregistervolatileunsignedintIER;
/*InterruptEnableRegister
externcregistervolatileunsignedintISTP;
/*InterruptServiceTblPtr
externcregistervolatileunsignedintIRP;
/*InterruptReturnPointer
externcregistervolatileunsignedintNRP;
/*Non-maskableIntReturnPtr*/
externcregistervolatileunsignedintIN;
/*GeneralPurposeInputReg
externcregistervolatileunsignedintOUT;
/*GeneralPurposeOutputReg*/
/*定义中断选择寄存器*/
#defineMUXH
0x019C0000
#defineMUXL
0x019C0004
#defineEXTPOL
0x019C0008
/*定义定时器1寄存器*/
#defineCTL1
0x01980000
//Timer1controlregister
#definePRD1
0x01980004
//Timer1periodregister
#defineCNT1
0x01980008
//Timer1counterregister
之后,在main函数中对定时器进行初始化,在此我们使用Timer1,参数初始化函数如下:
voidTimer1_Init(void)
*(volatileunsignedint*)CTL1=0x00000201;
//计数器功能设置
*(volatileunsignedint*)PRD1=0x1000;
//计数器周期值
*(volatileunsignedint*)CTL1|=0x000000C0;
//计数器清零,启动
并在主函数中调用它。
随后我们设置中断寄存器参数。
DSP支持1个RESET中断,1个NMI(不可屏蔽中断),12个可屏蔽中断(INT4-15),它们具有优先级顺序,INT4最高,INT15最低。
每个中断号都可以设置任何中断来源。
在此我们选择中断INT10,即开启中断10,并设置其中断来源为定时器1,即在MUXH或MUXL中指定位上填写中断来源选择码:
中断来源选择码定义如下:
(此内容可以通过帮助中搜索INTSEL得到)
INTSEL(InterruptSelectionNumberDeion)
00000b
DSPINT
HostporthosttoDSPinterrupt
00001b
TINT0
Timer0interrupt
00010b
TINT1
Timer1interrupt
00011b
SD_INT
EMIFSDRAMtimerinterrupt
00100b
EXT_INT4
Externalinterrupt4
00101b
EXT_INT5
Externalinterrupt5
00110b
EXT_INT6
Externalinterrupt6
00111b
EXT_INT7
Externalinterrupt7
01000b
EDMA_INT
EDMAchannel(0-15)interrupt
01001-01011b
Reserved
01100b
XINT0
McBSP0transmitinterrupt
01101b
RINT0
McBSP0receiveinterrupt
01110b
XINT1
McBSP1transmitinterrupt
01111b
RINT1
McBSP1receiveinterrupt
10000-11111b
从中得到定时器1的中断选择码为00010。
MUXH和MUXL的寄存器定义如下:
(也可以通过帮助得到)
MUXH
位
中断来源
30-26
INTSEL15
25-21
INTSEL14
20-16
INTSEL13
14-10
INTSEL12
9-5
INTSEL11
4-0
INTSEL10
31,15位保留,填0
MUXL
中断来源
INTSEL9
INTSEL8
INTSEL7
INTSEL6
INTSEL5
4-0
INTSEL4
31,15位保留,填0
因此,我们设置MUXH的第4-0位为定时器1的中断选择码00010,其余位可以任意设置(在此可以填1)。
转换为16进制后,设置如下:
*(volatileunsignedint*)MUXH=0x7fff7fe2;
MUXL可以不设置。
开启中断到IE10,使能全局中断:
IER|=0x00000402;
//IE10=1
CSR
|=0x00000001;
//全局中断使能
以上就完成了中断参数的配置,中断启动并且可以进入了。
下面是中断的处理过程。
主要分为设计中断向量表和中断处理函数。
我们可以从DSPCCS的示例中复制一份向量表的雏形。
例如\CCStudio_v3.1\tutorial\dsk6416\hello1\vectors.asm
将其拷贝到本工程目录下并加入工程中。
中断向量表包含了16个中断处理单元,每个单元限制必须是8条指令。
如果不够8条,可以用nop填充,(但nop4算1条语句),如果服务程序过多,那么可以制作专门的中断服务程序,此时此表只起到跳转作用,这样CPU就可以正确寻址找到正确的中断服务入口。
首先分析一下此文件。
文件开始定义了一个宏,用于处理未用到的中断。
unused
.macroid
.globalunused:
id:
unused:
bunused:
;
nestedbranchestoblockinterrupts
nop4
nop
.endm
它的做法是让程序进入死循环,我认为这种做法未必最优,因此我建议使用直接返回的方式。
返回到被中断地址,对于可屏蔽中断为birp,因此将此宏部分替换成,注意一定要凑够8条。
birp
这样,即使我们误开启了此中断,也会顺利返回。
当然,如果我们确信的确没有开启,那么其内容是无意义的。
代码的正文部分用了一系列unusedn来插入此宏,起到占地的作用。
由于NMI的返回与可屏蔽中断不同,它在向量表中位于RESET之下,即unused1,我们将其删除,替换为
NMI:
bnrp
nop
为了实现定时器1中断的处理,我们将unused10删除,替换为我们自己的中断跳转程序,如下:
INT10:
stwb0,*--b15
mvkl_xint0_isr,b0
mvkh_xint0_isr,b0
bb0
ldw*b15++,b0
nop3
另外,需要和语句:
.ref_c_int00
;
Centrypoint
类似,添加处理程序的引用
.ref_xint0_isr
timer1interrupthandler
由于中断向量表的位置需要特定指明,且应对齐到400H,在此文件中,已经定义了段名:
.sect"
.vectors"
因此我们需要将此.vector代码段挂载到专门的一段指定内存区域。
修改link.cmd链接文件,加入INT区域,起点为0地址。
其大小为400H,将原先的ISRAM起始点修改。
并将SECTIONS中的.vector指向自己定义的内存区域。
INT
:
origin=0x00000000,
len=0x00000400
origin=0x00000400,
len=0x10000000
INT
…
中断向量表设置、安装完毕。
最后,设计中断服务函数,在main.c中添加:
interruptvoidxint0_isr(void)
注意,一定要标识interrupt关键字,用于产生中断返回语句birp,同时,此函数的入口参数和出口参数应为void。
如果需要更新变量,可以通过全局变量的方式。
另外,C语言函数名称与汇编相差一个“_”,请在设计中断向量表时注意添加。
经过上述步骤,整个定时器中断的制作过程就完成了。
此时可以在interruptvoidxint0_isr(void)上添加一个断点,运行后应该停在此处。
如果进入失败,可以先在vector.asm的INT10:
stwb0,*--b15一句上设置断点,如果没有进入此处,证明中断没有进来,可以检查是否在参数设置上出现了问题。
五、
外部中断设计
DSP6000系列提供了INT4-7四个中断输入管脚,因此可以通过此四个管脚的输入电平变化实现外部中断。
对于电平变化的极性,分为高到低,低到高两种,因此,DSP采用寄存器EXTPOL来设置。
EXTPOL只有低4位有效,分别代表INT4-7,对于每个位有:
0:
低->
高产生中断
1:
高->
低产生中断
因此设置它即可完成极性变化。
下面,以设置外部端口INT7中断,并将其挂载到12号中断为例,简述实现过程:
将12号中断设置为外部中断7,即MUXH(14:
10)=00111,此时MUXH设置为:
*(volatileunsignedint*)MUXH=0x7fff1fe2;
//0001111111100010
将IER的第12位开启。
IER|=0x00001402;
//IE10=1IE12=1
对vectors.asm的unused12替换为:
INT12:
mvkl_extint7_isr,b0
mvkh_extint7_isr,b0
并添加引用
.ref_extint7_isr
在main.c中加入服务函数:
interruptvoidextint7_isr(void)
在硬件上,对INT7/GPIO7管脚产生一个低->
高的信号,则可以触发出中断。
若改变此极性,可以设置EXTPOL第四位为1:
*(volatileunsignedint*)EXTPOL|=0x00000008;
此时,一个高->
低的信号可以产生中断。
需要注意的是,如果你对GPIO进行过初始化,一定要保证GPEN的中断引脚相应位为1。
如全部使能:
*(volatileunsignedint*)GPEN
=0x000000F0;
六、
MCBSP串口接收中断设计
在实际应用过程中,经常需要通过中断接收串口数据。
在此假设添加MCBSP0接收中断到11号。
首先,将MCBSP0别名添加到global.h文件。
设置MCBSP0参数并启用,其初始化函数为:
voidMCBSP0_Init(void)
*(volatileunsignedint*)McBSP0_SPCR
=0x00000000;
*(volatileunsignedint*)McBSP0_SRGR
=0x200000FF;
*(volatileunsignedint*)McBSP0_PCR
=0x00000800;
*(volatileunsignedint*)McBSP0_XCR
=0x000100A0;
*(volatileunsignedint*)McBSP0_RCR
*(volatileunsignedint*)McBSP0_MCR
*(volatileunsignedint*)McBSP0_SPCR
|=0x00C10001;
并在main函数中调用。
开启中断11:
IER|=0x00001C02;
//IE10=1IE11=1IE12=1
并将MUXH(9:
5)=01101,综合以上三个中断,此时MUXH为:
*(volatileunsignedint*)MUXH=0x7fff1da2;
//0001110110100010
当然,如果只考虑现在的中断,MUXH可以设置为:
*(volatileunsignedint*)MUXH=0x7fff7dbf;
//0111110110111111
制作中断服务程序,将数据取出:
interruptvoidrint0_isr(void)
intDotRev;
DotRev=*(volatileunsignedint*)McBSP0_DRR;
修改vectors.asm,替换unused11为:
INT11:
mvkl_rint0_isr,b0
mvkh_rint0_isr,b0
添加引用:
.ref_rint0_isr
mcbsp0receiveinterrupthandler
这时,所有的任务完成了,可以通过设置断点观察一下接收的数值。
另外需要注意一定要在服务程序中将数据取出,否则会停止接到新的数据。
七、
其他话题
1.设置中断向量表起始位置
上文讨论的都是将中断向量表放置在0地址,如果需要放置到任意地址(以400H对齐),那么就需要提供向量表起始地址。
比如我们的终端向量位置:
INT设置为:
len=0x0000400
origin=0x00000800,
那么我们在初始化中断时,应设置:
ISTP=0x00000400;
2.查看现在的中断位图
可以查看中断标志寄存器IFR相应位(15:
0)看是否有中断到达。
3.清除/设置原先的中断
如果需要清除原先的中断,可以通过对ICR寄存器相应位置位。
如果希望人工触发中断,可以设置ISR寄存器相应位置位,它们将更新IFR位图。
比如,我们在定时器中断服务程序中,通过设置ISR的第12位,人工触发外部INT7的12号中断。
ISR=0x00001000;
那么CPU将执行extint7_isr(void)处理此中断。
又比如,在上例的外部中断中,有时会出现刚一开机,没有发送信号就有中断进来的情况,那么怎样克服呢?
可以通过ICR克服。
对ICR置位可以清除可屏蔽中断。
对应位有效。
比如在设置中断初始化时清除所有原先的中断。
那么可以加入语句:
ICR=0xffffffff;
4.DSP/BIOS下的中断设置
在DSP/BIOS管理下,我们不需要自己设定中断向量表,以及中断初始化等等,一切通过BIOS的图形化设置即可完成。
添加一个DSP/BIOS
选择File->
New,在本测试下选择DSK6416,读者可根据自己实际需要选取。
保存为Configuration1.cdb。
将其添加到工程。
如上例需求,选择HWI的10,11,12号中断,右键选择Properties分别填写如下参数:
HWI_INT10
interruptsource=Timer_1
=_xint0_isr(注意下划线!
)
HWI_INT11
interruptsource=MCSP_0_Receive
=_rint0_isr
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- DSP 中断 设置 简明 教程 修正
![提示](https://static.bdocx.com/images/bang_tan.gif)