DSP中断实验报告文档格式.docx
《DSP中断实验报告文档格式.docx》由会员分享,可在线阅读,更多相关《DSP中断实验报告文档格式.docx(22页珍藏版)》请在冰豆网上搜索。
当一个中断产生时:
⏹
SIC_IWR检查DSP内核是否从一个空闲状态中被中断唤醒
SIC_ISR记录中断请求,并且跟踪被激活但未被服务的系统中断
SIC_IMASK可以在系统级上屏蔽、使能外设的中断。
如果有一个中断A未被屏蔽,那么中断请求过程进入下一步
SIC_IARx寄存器组用来将外设中断映射到通用的内核中断组(IVG7-IVGl5),并且决定中断A的优先级
ILAT将中断A记录在内核中,但此时该中断还没有真正被响应
IMASK屏蔽、使能不同优先级的内核中断。
如果中断A对应的IVG事件没有被屏蔽,中断过程就进入下一步
访问事件向量表(EVT),查找中断A的中断服务程序(ISR)的中断矢量。
当中断A的事件矢量进入内核的流水线时,相应的IPEND位被置位,该位将清除对应的ILAT位。
因此,IPEND可以记录所有的被系统挂起的中断和正在服务的中断
在执行中断A的中断服务程序时,RTI指令就会清除相应的IPEND位。
但是,相关的SIC_ISR位不会被清除,除非中断服务程序清除了产生中断A的机制,或者服务中断的进程清除了该位。
系统中断过程如下图:
对于上述中断过程:
仿真、复位、NMI、异常事件、硬件错误和内核定时器中断请求在ILAT级上进入中断处理链,所以它们不受系统级的中断寄存器组(SIC_IWR,SIC_ISR,SIC_IMASK,SIC_IARx)的影响
◆如果有很多个中断源共享一个内核中断,那么中断服务程序就必须能识别产生中断的外设。
中断控制寄存器:
1.系统中断唤醒使能寄存器(SIC_IWR)
系统中断唤醒使能寄存器(SIC_IWR):
1唤醒使能,0唤醒使能禁止
通过设置该寄存器的相应位,任一外设都可以唤醒内核从空闲状态进入中断过程
⏹如果内核没有处于空闲状态,则该寄存器对内核没有影响
寄存器状态功能图如下:
2.系统中断状态寄存器(SIC_ISR)
系统中断状态寄存器(SIC_ISR):
1中断被激活,0中断未激活
寄存器每个有效位对应于一个外设中断源
⏹SIC发现一个中断被激活时,相应位被置位;
被撤销时,相应位被清除
⏹3.系统中断屏蔽寄存器(SIC_IMASK)
系统中断屏蔽寄存器(SIC_IMASK):
0中断屏蔽,1中断使能
该寄存器可以屏蔽SIC上的任何外设中断源,
⏹复位时所有外设的中断被屏蔽
⏹唤醒功能和中断屏蔽功能相互独立:
如果在SIC_ISR使能一个中断源,在SIC_IMASK中屏蔽该中断源,那么如果内核处于空闲状态,内核会被唤醒,但不会产生中断
4.系统中断设置寄存器(SIC_IARx)
通过将外设中断映射到内核中适当的通用中断级,可以设置外设中断的优先权
⏹映射受三个寄存器控制:
SIC_IRA0,SIC_IRA1,SIC_IRA2
设置外设到一个特定的IVG优先级时,写入SIC_IARx的值:
事件控制的寄存器:
事件控制器使用了3个寄存器来协调挂起事件的请求。
每一个寄存器都是16位的,并且寄存器中的每一位都对应事件向量表中的一个事件。
这些寄存器是:
Ø
1)ILAT-中断锁存寄存器
ILAT:
中断锁存寄存器中的每一位指示对应的中断是否被锁存
⏹0-没有锁存;
1-锁存
当一个事件被服务时,它在ILAT中的对应位就会被清除。
⏹指令RAISEN使ILAT寄存器中的第N位置位,并且只能被IVG15~IVG7、IVTMR、IVHW、NMI和RST等事件触发
⏹位0的复位值取决于是否处于硬件仿真,只有JTAG的TRST脚才可清除ILAT[0]
2)IMASK-中断屏蔽寄存器
IMASK:
中断屏蔽寄存器中的每一位指示对应的中断是否被使能
⏹0-中断屏蔽;
1-中断使能
⏹一个中断位在ILAT寄存器中设置后,只有在IMASK中也设置了这个位,内核才会接受这个位所控制的中断
3)IPEND-中断挂起寄存器
IPEND:
中断挂起寄存器记录当前所有的嵌套中断
⏹位0:
硬件仿真
⏹位4:
全局中断禁止
⏹其他位:
0-没有中断挂起,1-中断挂起或激活
⏹IPEND中的每一位指示一个中断是否被激活,或是否在某一级上被嵌套
⏹在进入或退出一个中断服务程序时,事件控制器使用IPEND[4]位暂时性地禁止中断
⏹当正在处理一个事件时,IPEND中相对应的位就会被置位
SIC_IPEND寄存器:
中断全局禁止和使能:
1)中断全局禁止指令CLIDreg
设置IMASK寄存器为全零来禁止普通中断,并将IMASK寄存器以前的值保存在指定的数据寄存器Dreg中
2)中断全局使能指令STIDreg
恢复以前保存的IMASK寄存器的值来允许普通中断,以前的IMASK寄存器的值保存在指定的数据寄存器Dreg中
**复位,NMI、仿真和异常事件都不能使用全局使能和禁止的方法
事件向量表EVT:
EVT包含每一个可能事件的入口。
当一个事件发生时,在该事件的EVT入口所指的地址处开始读取指令。
每一个事件在寄存器ILAT、IMASK和IPEND中都有对应的位
内核事件向量表:
3.本实验知识分析:
程序利用SW4-SW7产生中断12,改变LED1-LED4的闪烁频率,执行相应的中断服务程序(ISR)
•利用外部计时器timer0产生计时中断,中断程序中断LED的闪烁,使LED变灭(或可以重新点亮)
可编程窗口:
1)Blackfin的工作模式
三种模式:
a.用户模式
⏹不处于空闲状态、复位状态,不处理中断、NMI、异常和仿真事件
⏹处于用户模式的时候不能访问存储器映射寄存器(MMR)
b.监控模式
⏹对资源访问无限制
c.仿真模式
2)程序设计过程:
设置EVT(0~15),以设置EVT12为例
⏹P0.H=HI(EVT12);
⏹P0.L=LO(EVT12);
⏹R0.H=_FRE_SWH;
⏹R0.L=_FRE_SWH;
⏹[P0]=R0;
准备退出,保证顺利进入用户模式
⏹R0=0x8000(Z);
⏹STIR0;
⏹RAISE15;
⏹R0.L=wait_here;
⏹R0.H=wait_here;
⏹RETI=R0;
进入用户模式
⏹RTI;
停留在用户模式
⏹wait_here:
⏹JUMPwait_here;
根据之前程序:
R0=0x8000(Z);
被迫进入中断15
中断嵌套:
监控模式(15号中断)
⏹灯闪烁
灯的闪烁频率有P5设置,代码实现如下:
P5.L=0x0000;
P5.H=0x0e00;
//初始设置LED的闪烁频率
R1.L=0x000F;
BLINK:
W[P2]=R1.L;
//设置PF0-PF3为高电平输出
CALLDELAY_LOOP;
CSYNC;
//内核同步指令
W[P1]=R1.L;
//设置PF0-PF3为低电平输出
JUMPBLINK;
允许新的中断,通过按键激活新的中断
允许中断嵌套,保护现场
⏹[--SP]=RETI;
中断设置:
哪些灯闪烁?
⏹设置FIO_DIR
⏹P0.H=FIO_DIR>
>
16;
⏹P0.L=FIO_DIR&
0xFFFF;
⏹R0.H=0x000F;
⏹W[P0]=R0.H;
⏹CSYNC;
初始时显示什么?
设置FIO_FLAG_S和FIO_FLAG_C
⏹闪烁频率?
⏹将频率参数保存在一个寄存器Px
要有按键输入,触发新的中断
⏹设置FIO_EDGE和FIO_POLAR
⏹定义并使能响应的中断:
⏹FIO_MASKA_S
⏹SIC_IMASK
⏹IMASK
⏹如何让灯闪烁?
⏹改变FIO_FLAG_S和FIO_FLAG_C
⏹每一个亮灯状态的保持时间:
通过寄存器Px的值保持Delay周期
⏹改变闪烁频率:
设置寄存在Px中的闪烁频率
改变闪烁频率,先确保退路
⏹[--SP]=RETI;
⏹扫描每一个按钮,检测需要改到什么频率
⏹R5=W[P1];
⏹CC=BITTST(R5,4);
⏹IFCCJUMPRATE_i;
⏹RATE_i中改变频率并原路返回
⏹P5.H=0x0200;
⏹P5.L=0x0000;
⏹RETI=[SP++];
四.程序代码及注释:
#include"
defBF535.h"
.sectionl2_bank0;
.global_MAIN;
_SETUP:
SP.H=0xFFB0;
//设置监视模式下的堆栈起始地址,为了加快访问时间,
SP.L=0x0F00;
//SP应设置在scratchpad(0xFFB00000-0xFFB00FFF)中
//-----------------------------------------------------------------------------------//
P0.H=HI(EVT12);
P0.L=LO(EVT12);
R0.H=_SET_RATE;
R0.L=_SET_RATE;
[P0]=R0;
//将中断事件_SET_RATE入口地址写入中断向量列表(IVT)EVT12中
P0.H=HI(EVT11);
P0.L=LO(EVT11);
R0.H=_IDLE;
R0.L=_IDLE;
//将中断事件_SET_RATE入口地址写入中断向量列表(IVT)EVT11中
//由于系统在重启(reset)后进入事件setupevent,其优先级高于IVG7-IVG15,故其
//在监视模式下无法对IVG7-IVG15做出响应,但是我们可以在用户模式下使系统响应
//IVG15,然后使其转入监视模式,从而系统可以响应优先级高于IVG15的中断(中断嵌套)
//,从而完成本程序的功能。
//-----------------------------------------------------------------------------------//
P0.H=HI(EVT15);
P0.L=LO(EVT15);
R0.L=ISR15;
R0.H=ISR15;
//将中断事件ISR15的入口地址写入中断向量列表(IVT)EVT15中
R0=0x8000(Z);
STIR0;
//使能EVT15中断服务程序,中断允许指令
RAISE15;
//产生EVT15中断
P0.L=WAIT_HERE;
P0.H=WAIT_HERE;
RETI=P0;
//将中断返回地址放入RETI中
RTI;
//中断返回,转入用户模式
WAIT_HERE:
JUMPWAIT_HERE;
//等待中断服务程序ISR15运行
ISR15:
[--SP]=RETI;
//中断服务程序ISR15运行后,系统转入监视模式,压栈保护RETI
JUMP_MAIN;
//使ISR15支持中断嵌套调用
_MAIN:
P0.H=HI(FIO_DIR);
//FIO_DIR标志方向寄存器:
15~0PF管脚,逻辑1配置为输出,逻辑0配置为输入
P0.L=LO(FIO_DIR);
R0.L=0x000F;
W[P0]=R0.L;
//设置PF0-PF3为输出管脚,LED显示;
PF4-PF7为输入管脚,改变频率
//--------------------------------------------------------------------------------------------//
P1.H=HI(FIO_FLAG_C);
//标志清除寄存器
P1.L=LO(FIO_FLAG_C);
P2.H=HI(FIO_FLAG_S);
//标志置位寄存器
P2.L=LO(FIO_FLAG_S);
//用来检测设置为输入的PF管脚的电平和设置为输出管脚的状态,并可以用来清除由PF管脚引起的中断
//此处用来设置BLINK的时候灯亮灭的变化
P0.H=HI(FIO_EDGE);
//标志中断触发方式寄存器,用来配置每一个管脚的触发方式为电平触发或者边沿触发
P0.L=LO(FIO_EDGE);
//默认为0,电平触发;
1为边沿触发
R0.L=0x0000;
//设置PF4-PF7为边沿触发
P0.H=HI(FIO_POLAR);
//标志极性寄存器,用来标志输入源的极性;
如果选择高电平或者上升沿激活,
P0.L=LO(FIO_POLAR);
//在寄存器对应位写入0;
如果选择低电平或者下降沿激活,在寄存器对应位写入1
R2.L=0x0000;
//设置PF4-PF7为上升边沿触发
P0.H=HI(FIO_MASKA_S);
//标志中断屏蔽寄存器,1为使能对应位
P0.L=LO(FIO_MASKA_S);
R0.H=0x00f0;
W[P0]=R0.H;
//使能PF4-PF7中断,产生的中断事件为A类
//内核同步指令
P0.H=HI(SIC_IMASK);
//系统中断屏蔽寄存器,1为使能,0为屏蔽(V1.0以后版本取反)
P0.L=LO(SIC_IMASK);
R0=[P0];
BITCLR(R0,17);
//使能内核能够接受PF产生的A类中断
BITCLR(R0,14);
//使能内核能够接受Timer0中断
P0.L=LO(SIC_IWR);
//enablePLLWakeupInterrupt
P0.H=HI(SIC_IWR);
//系统中断唤醒使能寄存器
R0.H=0x0002;
//唤醒PF中断A,对应上一步中改变第十七位
P0.H=HI(IMASK);
//内核中断屏蔽寄存器
P0.L=LO(IMASK);
//使能中断处理模块查找中断向量列表,执行Programmable
BITSET(R0,12);
//使能中断12
BITSET(R0,11);
//使能中断11
//==============================Timer0设置===================================//
P0.H=HI(TIMER0_CONFIG);
//定时器设置寄存器,中断请求有效(第五位),设置为周期结束计数(第四位)
P0.L=LO(TIMER0_CONFIG);
R0.L=0x0019;
W[P0]=R0.L;
//设置为PWM_OUT模式(第一位和第二位),此时Timer0为输出管脚
R1.H=0xa000;
R1.L=0x0000;
P0.L=LO(TIMER0_PERIOD_HI);
W[P0]=R1.H;
P0.L=LO(TIMER0_PERIOD_LO);
//定时器周期寄存器
W[P0]=R1.L;
P0.L=LO(TIMER0_WIDTH_HI);
//定时器宽度寄存器
W[P0]=R2.H;
P0.L=LO(TIMER0_WIDTH_LO);
W[P0]=R2.L;
P0.L=LO(TIMER0_STATUS);
//定时器状态寄存器
R0.L=0x0100;
SSYNC;
//系统同步指令
//========================================================================================//
_MAIN.END:
//-------------------------------闪烁时延子程序---------------------------------------//
DELAY_LOOP:
//闪烁时延函数
LSETUP(L_BEGIN,L_END)LC0=P5;
L_BEGIN:
L_END:
NOP;
RTS;
//-----------------------------------IVG12HANDLER,----------------------------------//
_SET_RATE:
//响应_SET_RATE,扫描每一个PF是否按下,进行中断嵌套和响应并返回
R5=W[P1];
CC=BITTST(R5,4);
//检查PF4是否按下,产生中断,跳转到相应频率设置
IFCCJUMPSET_RATE_1;
CC=BITTST(R5,5);
//检查PF5是否按下,产生中断,跳转到相应频率设置
IFCCJUMPSET_RATE_2;
CC=BITTST(R5,6);
//检查PF6是否按下,产生中断,跳转到相应频率设置
IFCCJUMPSET_RATE_3;
CC=BITTST(R5,7);
//检查PF7是否按下,产生中断,跳转到相应频率设置
IFCCJUMPSET_RATE_4;
SET_RATE_1:
P5.H=0x0900;
RETI=[SP++];
//中断嵌套,返回地址
SET_RATE_2:
P5.H=0x0500;
SET_RATE_3:
P5.H=0x0100;
RT