TMS320c6747的外部中断

1.初始化

6747的GPIO模块初始化步骤如下:

1.1    执行必要的引脚复用设置,如将引脚设置为中断模式或GPIO模式(查阅具体的数据手册)

1.2    对电源与睡眠控制器(PSC,Power and Sleep Controller)进行编程以使能GPIO模块,关于PSC的细节,见“电源与睡眠控制器”一章。

1.3    对方向(direction),数据(data)和中断(interrupt)控制寄存器编程,对要用的引脚的配置进行设置。

完成上述步骤即可开始进行数据传输。6747的所有GPIO引脚均可配置用于产生中断,硬件复位以后要进行GPIO的初始化。

2.使能GPIO中断事件

通过设置GPIO中断组使能寄存器(GPIO interrupt per-bank enable register,BINTEN)的相应位(bit)可以使能相应的GPIO中断事件,中断组使能寄存器中的一位控制一组(bank)GPIO的中断事件,对应16个GPIO脚的中断事件。例如,要使能第0组(bank 0)的所有中断(来自GP0[15-0]引脚的事件),就设置BINTEN的第0位(0 bit);使能第3组(bank 3)的所有中断,就设置BINTEN的第3位(bit 3)。

3.配置GPIO中断边沿触发

       每个GPIO中断源(interrupt source)都可以配置成上升沿(rising edge)触发,下降沿(falling edge)触发,上下边缘触发,或者上下边缘都不触发。当相应的信号边沿到达时,中断源产生中断信号。边沿检测(edge detection)同步到GPIO外设模块时钟。

以下4个寄存器控制GPIO中断边沿检测的配置:

1.    GPIO上升沿中断置位寄存器(GPIO set rising edge interrupt register,SET_RIS_TRIG)使能上升沿触发。

2.    GPIO上升沿中断清零寄存器(GPIO clear rising edge interrupt register,CLR_RIS_TRIG)关闭上升沿触发。

3.    GPIO下降沿中断置位寄存器(GPIO set falling edge interrupt register,SET_FAL_TRIG)使能下降沿触发。

4.    GPIO下降沿中断清零寄存器(GPIO clear rising edge interrupt register,CLR_FAL_TRIG)关闭下降沿触发。

设置GPIO上升沿触发,往SET_RIS_TRIG寄存器相应的位写1,CLR_FAL_TRIG写1.

设置GPIO下降沿触发,往SET_FAL_TRIG寄存器相应的位写1,CLR_RIS_TRIG写1.

设置GPIO上下边沿触发,往SET_RIS_TRIG寄存器相应的位写1,SET_FAL_TRIG写1.

关闭某个GPIO中断,往CLR_RIS_TRIG寄存器相应的位写1,CLR_FAL_TRIG写1.

注意GPIO信号的方向不一定要是输入才能产生中断事件。当中断信号配置为输出的时候,可以通过软件改变GPIO信号的状态,从而产生中断。这对调试中断信号连通性很有用。

4.GPIO中断状态(GPIO InterruptStatus)

       可以通过读GPIO中断状态寄存器(interrupt status register,INTSTAT)来监控GPIO中断事件的状态。挂起的(Pending)GPIO中断会在相应的位显示1,不挂起的中断会在相应的位显示0。

       对直接接到DSP子系统的GPIO中断,可以通过读CPU相应的中断标志(interrupt flag)来确定中断状态。对GPIO组中断(bank interrupts),INTSTAT可以用于确定哪个GPIO中断发生了。软件中应该要确保所有挂起的GPIO中断都得到适当的处理。

       挂起的GPIO中断标志位可以通过往INTSTAT相应的位写1清除。

5.GPIO中断状态寄存器(GPIOInterrupt Status Registers,INTSTATn)

GPIO中断事件的状态可以通过读GPIO中断状态寄存器来进行监控。在相应的位,挂起的GPIO中断会显示1,不挂起的中断显示0。GPIO中断状态寄存器有INTSTAT01,INTSTAT23, INTSTAT45, INTSTAT67, INTSTAT8。如下所示:

(用户手册P855)

(数据手册P836)

程序中,当进入中断服务程序时,说明该中断已得到响应,中断挂起标志INSTAT应清除,否则当退出时又会重新执行此段程序。当执行Ex2INT中断服务程序时,说明GPIO bank2发生中断,具体是GPIO bank2的哪个引脚,需要通过GPIO中断状态寄存器INISTAT来判断。如果GPIO_INSTAT23(GPIO bank2和bank3的中断状态寄存器)的最低位为1,即GP2P0为1,说明中断是通过GPIO bank2的引脚0(pin0)发生的,则执行相应的操作,否则说明是GPIO bank2其他引脚发生了中断。

(数据手册P836)

(TMS320C674x DSP Megamodule Reference Guide P178)

(sprufk5a P178)

C6000家族DSP外设集可以有多达32个中断源,但是CPU可用的中断只有12个。中断选择器可以从这32个中断源中挑选12系统所需的中断源并进行设置其优先级。

(TMS320C6000 DSP Interrupt Selector ReferenceGuide P7)

中断选择器(interrupt selector)含有中断复用寄存器,6747共有3个中断复用寄存器,在中断复用寄存器(Interrupt Mux Registers,INTMUXn,n=1-3)中可以设置12个可用的CPU中断对应的中断源。程序中这句话,设置INTSEL4=0x31(49dec),INTSEL5=34(52dec),INTSEL6=36(54dec)。查找数据手册中断源对应的中断事件(event)的数字,如下:

(数据手册P76)

可见,这里设置了CPU中断4(INT4)的中断源为GPIO Bank2 Interrupt,中断5(INT5)的中断源为GPIO Bank 3 Interrupt,中断6(INT6)的中断源为GPIO Bank 4 Interrupt,

这里这样设置是要对应linkercmd文件中memory段vecs部分地址的设置,在链接文件linkercmd文件中,vecs定义了中断向量表放到以CPU逻辑地址0x80000000为起始地址(origin,o),长度为0x00000f00的区域中,所以ISTP也应该指向这个地址。见下图:

(注意linker.cmd链接文件中vecs的地址)

这是vector.asm这个汇编文件中所放的各中断服务程序的地址,注意67行定义了该段为vectors段,即上面链接文件中定义的0x80000000开始的那片区域。当某个中断事件发生,该中断源引发对应的CPU中断,例如假设将CPU中断4的中断源设置为GPIO_bank2的中断,当发生gpio_bank_2的中断时,CPU就会执行对应中断号为4的中断服务程序,在vectors段中可见,中断号为4的中断服务程序对应的入口(VEC_ENTRY)为Ex2INT,即CPU将执行函数名为Ex2int的程序。再细看一下,0x80000000地址处于空白部分,即不与6747其它任何外设的映射地址冲突,见下图:

(TMS320C6745/C6747Fixed/Floating-Point Digital Signal Processors (Rev. F)P25)

ISTP(Interrupt service table pointer,中断服务表指针)指向中断向量表的起始地址,当中断事件发生时,会寻找相应中断处理程序的首地址,该地址等于中断事件的偏移量加上ISTP。

(TMS320C674x DSP CPU and Instruction Set Reference Guide P706)

ISTP的作用简介:

(TMS320C674xDSP CPU and Instruction Set Reference Guide P45)

ICR(Interrupt Clear Register,中断清除寄存器)用于清除中断标志寄存器(interrupt flag register,IFR)中可屏蔽中断(INT15-INT4)的中断标志。

(TMS320C674x DSP CPU and InstructionSet Reference Guide P41)

ISR(Interrupt set register,中断置位寄存器)用于手动设置IFR中的可屏蔽中断(INT15-INT4),如下所示:

(TMS320C674x DSP CPU and InstructionSet Reference Guide P44)

IER(Interrupt Enable Register,中断使能寄存器)可以使能或禁止单个中断,功能如下:

(TMS320C674x DSP CPU and InstructionSet Reference Guide P42)

当*LED=0xfd时,LED从高位到低位依次为:

D9 D8 D7 D6 D5 D4 D3 D2

1      1  1  1  1  1  0  1;

则D3点亮,其它所有灯灭。

当*LED=0xfe时,LED从高位到低位依次为:

D9 D8 D7 D6 D5 D4 D3 D2

1      1  1  1  1  1  1  0;

则D2点亮,其它所有灯灭。

按下按键S6,则GP4_11发生中断,执行Ex4INT中断服务程序。

按下按键S3,则GP2_0发生中断,执行Ex2INT中断服务程序。

按下按键S4,则GP2_4发生中断,执行Ex2INT中断服务程序。

按下按键S5,则GP3_11发生中断,执行Ex3INT中断服务程序。

电路如图:

(研旭YXDSP-C6747开发板官方用户手册V4 P86)

使能GPIO中断事件

用户手册P832

代码如下:

/*
DSP6747 & FPGA
 */

#include "stdio.h"
#include "C6747.h"

Uint16  *LED   = (Uint16 *)0x64000012;            ///led add

Uint16 led0[8]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};
Uint16 led1[8]={0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe};
Uint16 led2[8]={0x7f,0x3f,0x1f,0x0f,0x07,0x03,0x01,0x00};
Uint16 led3[8]={0x00,0x01,0x03,0x07,0x0f,0x1f,0x3f,0x7f};
Uint16 myled[4]={0xfe,0xfd,0xfb,0xf7};

Uint8   flag;
 
void  delay(unsigned int  t)

{
  Uint32 i,j;
  for(i=0;i<t;i++)
  {
   for(j=0;j<4000;j++);
  
  }

}
/* ------------------------------------------------------------------------ *
 *                                                                          *
 *  Testing Function                                                        *
 *                                                                          *
 * ------------------------------------------------------------------------ */


void interrupt Ex2INT()	//AD采集完后的中断响应函数
{   
    asm("  DINT  ");//CSR&=0xfffe;  //关中断
	asm(" NOP 2 ");
	                      //打开读数标志
   if(GPIO_INSTAT23 & 0x00000001  )    // 清除中断标志GPIOSTAT
   { flag=1;*LED=~(*LED^0xfd);}
	else// if(GPIO_INSTAT23 & 0x00004000 )
	{flag=2;*LED=~(*LED^0xfb);}
    GPIO_INSTAT23=0xffffffff;
	asm(" NOP 2 ");
    asm("  RINT  "); //	CSR=CSR|0x1; 	// 开中断
}
void interrupt Ex3INT()	//AD采集完后的中断响应函数
{   
    asm("  DINT  ");//CSR&=0xfffe;  //关中断
	asm(" NOP 2 ");

	flag=3;*LED=~(*LED^0xf7);                      //打开读数标志
	GPIO_INSTAT23=0xffffffff;     // 清除中断标志GPIOSTAT
	asm(" NOP 2 ");
    asm("  RINT  "); //	CSR=CSR|0x1; 	// 开中断
}
void interrupt Ex4INT()	//AD采集完后的中断响应函数
{   
    asm("  DINT  ");//CSR&=0xfffe;  //关中断
	asm(" NOP 2 ");
	flag=4;                     //打开读数标志
  *LED=~(*LED^0xfe);
	GPIO_INSTAT45=0xffffffff;     // 清除中断标志GPIOSTAT
	asm(" NOP 2 ");
    asm("  RINT  "); //	CSR=CSR|0x1; 	// 开中断
}
void initExint(void)
{  
    CSR&=0xfffe;  //关中断

	asm(" NOP 2 ");
//	IENSET=0x3;                            // 使能中断源
	GPIO_INSTAT23=0xFFFFFFFF;              //清除第2 3 BANK的中断标志位
	GPIO_INSTAT45=0xFFFFFFFF;              //清除第4 BANK的中断标志位
	GPIO_BINTEN=0x1c;                       //使能GPIO BANK 2 3 4外部中断功能 
	
	GPIO_CLR_RIS_TRIG23=0x08000011;        //关闭上升沿中断 
	GPIO_SET_FAL_TRIG23=0x08000011;        //设置下降沿中断
	GPIO_CLR_RIS_TRIG45=0x00000800;        //关闭上升沿中断 
	GPIO_SET_FAL_TRIG45=0x00000800;        //设置下降沿中断

    INTmux1=0x363431;                              // 指定exINT到外部中断4
	asm(" NOP 2 ");                        // 关中断 GIE=0
	ISTP=0x80000000;	               // 重置中断向量表到0C00h
	asm(" NOP 2 ");
	ICR=0xFFFF;	
	asm(" NOP 2 ");
	ISR=0x0;	                           // 清除等待的中断
	asm(" NOP 2 ");
	IER=0xffff;			    

}
void main( void )
{  Uint8 i=0;                   
  	/* Initialize OMAPL137*/
  C6747_init(); //初始化6747核
  
  initExint(); //中断配置
   CSR=CSR|1;               //开中断
  flag=0;
  *LED=0x00;
  *LED=~*LED;//取反LED
 while(1)
   {
/*   if(flag==0)
   {
   for(i=0;i<8;i++)
    {*LED=led0[i];
    delay(400);}
	   *LED=0xfe;
   }
   if(flag==1)
   {
    for(i=0;i<8;i++)
   { *LED=led1[i];
    delay(400);}
    }
   if(flag==2)
   {  for(i=0;i<8;i++)
   { *LED=led2[i];
    delay(400);}
    }
   if(flag==3)
   {  for(i=0;i<8;i++)
   { *LED=led3[i];
    delay(400);}
     }
	if(flag==4)
	flag=0;*/
   }

}

  • 5
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值