Learning ADSP-TS201系列--Interrupt Pin


原创作品,转载请注明原作者及地址!

by 飞鸿惊雪

http://blog.csdn.net/niyufeng




Learning ADSP-TS201系列--索引


1 Learning ADSP-TS201系列--重要参考

2 Learning ADSP-TS201系列--EZ-KIT Lite评估板硬件资源

3 Learning ADSP-TS201系列--Flag Pins按键和LED灯

4  Learning ADSP-TS201系列--Interrupt Pin






Learning ADSP-TS201系列--Interrupt Pin



上一篇截图中还有另外的两个按键SW4和SW5,这两个按键涉及到中断,本篇就讲这个最简单的中断Interrupt Pin(IRQ0),后续再尝试其他的中断,例如timer定时计数器,DMA中断,LinkPort中断。。。 



1 电路中的Interrupt Pin


ADSP-TS201 EZ-KIT Lite评估板上每片DSP含有4个外部中断(IRQ3–0 ),其中IRQ0接到了一个按键上(SW4和SW5)。


Learning ADSP-TS201系列--Interrupt Pin_第1张图片




当按键按下时,表现为低电平(可采用高低电平触发中断的模式)。

Learning ADSP-TS201系列--Interrupt Pin_第2张图片




2 Interrupt Pin的寄存器



涉及到中断的主要有以下这几个寄存器:ILAT,IMASK,PMASK,以及SQCTL下的GIE位控制全局中断,和INTCTL控制IRQ3-0的触发方式、TIME1-0的启动。


ILAT,IMASK,PMASK这三者“相与”指明了正在执行的中断为哪一个。
ILAT:中断锁存寄存器,只要发生中断相应位置1;
IMASK:中断屏蔽寄存器,只有置1才允许响应相应的中断;
PMASK:锁存正在执行的中断,如果允许中断嵌套,只有在高于目前PMASK位的中断才可以响应。




2.1 ILAT  IMASK  PMASK (H)寄存器


我们本次要试验的IRQ0就在(H)寄存器中!


Learning ADSP-TS201系列--Interrupt Pin_第3张图片






2.2 ILAT  IMASK  PMASK (L)寄存器




Learning ADSP-TS201系列--Interrupt Pin_第4张图片






2.3 INTCTL寄存器


INTCTL控制IRQ3-0的触发方式、TIME1-0的启动。


Learning ADSP-TS201系列--Interrupt Pin_第5张图片






2.4 SQCTL寄存器



Learning ADSP-TS201系列--Interrupt Pin_第6张图片



SQCTL下的SQCTL_GIE位控制全局中断。
SQCTL还有两个别名SQCTLST和SQCTLCL。


和一般的单片机如MCS-51,MSP430,以及ARM处理器相比,DSP的中断很独特。
它的中断向量表是有专门的寄存器组来存储,而非像ARM处理、单片机那样放在存储器中,更不需要ARM那样复杂的地址映射之类操作。




3 中断服务程序


第一种在C中定义中断服务程序的方法:

1 首先编写一个C函数,返回值和参数都是void;
  void irq0_isr(void)
  {...}

2 将#pragma interrupt放在这个函数前面,定义这个函数为不可重入的中断服务;
  #pragma interrupt
  void irq0_isr(void)
  {...}

3 在main中通过__builtin_sysreg_write将服务程序的函数指针放入中断向量表中,例如IRQ0的服务程序为irq0_isr,则:
	__builtin_sysreg_write(__IVIRQ0, (int)irq0_isr);



第二种在C中定义中断服务程序的方法:

1 首先编写一个C函数,返回值是void(无返回),有一个参数int型;
  void isr_irq0(int signal)
  {...}

2 不需将#pragma interrupt放在这个函数前面!
3 添加#include<signal.h>头文件(其中包含了SIGIRQ0等各种中断信号的定义),在main中通过interrupt系列函数将服务程序的函数指针放入中断向量表中,例如IRQ0的服务程序为isr_irq0,则:
  interrupt(SIGIRQ0, isr_irq0);




4 编程实验


#include<stdio.h>
#include<builtins.h>
#include<sysreg.h>
#include<defts201.h>

#include<signal.h>

void isr_irq0(int dummy);

int main( void )
{
	
	//将FLAG2设为输出模式
	__builtin_sysreg_write(__FLAGREGST,FLAGREG_FLAG2_EN);
	
	
	
	//允许外部IRQ0
	int imaskh=0;
	imaskh = __builtin_sysreg_read(__IMASKH);
	imaskh |= (1<<INT_IRQ0_P);
	__builtin_sysreg_write(__IMASKH, imaskh);
	
	//设置IRQ0中断服务程序
	interrupt(SIGIRQ0, isr_irq0);
	
	//设置跳沿触发
	__builtin_sysreg_write(__INTCTL,0);
	//开全局中断使能
	__builtin_sysreg_write(__SQCTLST, SQCTL_GIE);
	
	
	while(1);
	
}



void isr_irq0(int signal)
{
	static int button=0;
	
	//按键按下进入本中断服务,每次都反转下button状态
	button = !button;
	
	if(0==button){
		__builtin_sysreg_write(__FLAGREGCL,~FLAGREG_FLAG2_OUT);
	} else {
		__builtin_sysreg_write(__FLAGREGST,FLAGREG_FLAG2_OUT);
	}
	
}


对比上一个中断程序的写法,再列出另一中中断服务完整程序。

#include<stdio.h>
#include<builtins.h>
#include<sysreg.h>
#include<defts201.h> 

void irq0_isr(void);

int main( void )
{
	int v;
	//将FLAG2设为输出模式
	__builtin_sysreg_write(__FLAGREGST,FLAGREG_FLAG2_EN);
	//设置IRQ0服务程序
	__builtin_sysreg_write(__IVIRQ0,(int)irq0_isr);
	//设置跳沿触发
	__builtin_sysreg_write(__INTCTL,0);
	//允许外部IRQ0
	v=__builtin_sysreg_read(__IMASKH);
	v|=(1<<INT_IRQ0_P);
	__builtin_sysreg_write(__IMASKH,v);
	//开全局中断使能
	__builtin_sysreg_write(__SQCTLST,SQCTL_GIE);
	
	while(1);
	
}



#pragma interrupt
void irq0_isr(void)
{
	static int button=0;
	button=!button;
	
	if(0==button){
		__builtin_sysreg_write(__FLAGREGCL,~FLAGREG_FLAG2_OUT);
	} else {
		__builtin_sysreg_write(__FLAGREGST,FLAGREG_FLAG2_OUT);
	}
	
}






          Learning ADSP-TS201系列--Interrupt Pin_第7张图片


ADSP-TS201 EZ-KIT Lite评估板上面有两个DSP处理器A和B。Emulator仿真时,如果不定义LDF链接文件,默认使用DSP_B。

最右边的两个LDE和3个Button按键就是DSP_B的,注意看右起第二个LED,可以使用按钮进行亮灭的控制。











你可能感兴趣的:(Learning ADSP-TS201系列--Interrupt Pin)