这是 DSP28335的例程,程序目的是通过按不同的按键,通过中断改变LED的闪动方式
,你可以对比一下。 (DSP2812和 DSP28335是差不多的)
#include "DSP2833x_Deviceh" // DSP2833x Headerfile Include File#include "DSP2833x_Examplesh" // DSP2833x Examples Include File
#define LED1_ON GpioDataRegsGPASETbitGPIO0=1
#define LED1_OFF GpioDataRegsGPACLEARbitGPIO0=1
#define LED2_ON GpioDataRegsGPASETbitGPIO1=1
#define LED2_OFF GpioDataRegsGPACLEARbitGPIO1=1
#define LED3_ON GpioDataRegsGPASETbitGPIO2=1
#define LED3_OFF GpioDataRegsGPACLEARbitGPIO2=1
#define LED4_ON GpioDataRegsGPASETbitGPIO3=1
#define LED4_OFF GpioDataRegsGPACLEARbitGPIO3=1
#define LED5_ON GpioDataRegsGPASETbitGPIO4=1
#define LED5_OFF GpioDataRegsGPACLEARbitGPIO4=1
#define LED6_ON GpioDataRegsGPASETbitGPIO5=1
#define LED6_OFF GpioDataRegsGPACLEARbitGPIO5=1
#define LED7_ON GpioDataRegsGPBSETbitGPIO51=1
#define LED7_OFF GpioDataRegsGPBCLEARbitGPIO51=1
#define LED8_ON GpioDataRegsGPBSETbitGPIO50=1
#define LED8_OFF GpioDataRegsGPBCLEARbitGPIO50=1
interrupt void ISRExint3(void);
interrupt void ISRExint4(void);
interrupt void ISRExint5(void);
interrupt void ISRExint6(void);
void configtestled(void);
Uint16 sign ;
void main(void)
{
// Step 1 Initialize System Control:
// PLL, WatchDog, enable Peripheral Clocks
// This example function is found in the DSP2833x_SysCtrlc file
InitSysCtrl();
// Step 2 Initalize GPIO:
// This example function is found in the DSP2833x_Gpioc file and
// illustrates how to set the GPIO to it's default state
// InitGpio(); // Skipped for this example
InitXintf16Gpio(); //zq
// Step 3 Clear all interrupts and initialize PIE vector table:
// Disable CPU interrupts
DINT;
// Initialize the PIE control registers to their default state
// The default state is all PIE interrupts disabled and flags
// are cleared
// This function is found in the DSP2833x_PieCtrlc file
InitPieCtrl();
// Disable CPU interrupts and clear all CPU interrupt flags:
IER = 0x0000;
IFR = 0x0000;
// Initialize the PIE vector table with pointers to the shell Interrupt
// Service Routines (ISR)
// This will populate the entire table, even if the interrupt
// is not used in this example This is useful for debug purposes
// The shell ISR routines are found in DSP2833x_DefaultIsrc
// This function is found in DSP2833x_PieVectc
InitPieVectTable();
// Interrupts that are used in this example are re-mapped to// ISR functions found within this file
EALLOW; // This is needed to write to EALLOW protected registers
PieVectTableXINT3 = &ISRExint3;
PieVectTableXINT4 = &ISRExint4;
PieVectTableXINT5 = &ISRExint5;
PieVectTableXINT6 = &ISRExint6;
EDIS; // This is needed to disable write to EALLOW protected registers
PieCtrlRegsPIECTRLbitENPIE = 1; // Enable the PIE block
PieCtrlRegsPIEIER12bitINTx1= 1;
PieCtrlRegsPIEIER12bitINTx2= 1;
PieCtrlRegsPIEIER12bitINTx3= 1;
PieCtrlRegsPIEIER12bitINTx4= 1;
IER |= M_INT12; // Enable CPU int1
EINT; // Enable Global interrupt INTM
ERTM; // Enable Global realtime interrupt DBGM
configtestled();
sign = 0;
while(1)
{
if(sign==0)
{ LED1_OFF;
LED2_OFF;
LED3_OFF;
LED4_OFF;
LED5_OFF;
LED6_OFF;
LED7_OFF;
LED8_OFF;
DELAY_US(50000);
LED1_ON;
DELAY_US(50000);
LED2_ON;
DELAY_US(50000);
LED3_ON;
DELAY_US(50000);
LED4_ON;
DELAY_US(50000);
LED5_ON;
DELAY_US(50000);
LED6_ON;
DELAY_US(50000);
LED7_ON;
DELAY_US(50000);
LED8_ON;
DELAY_US(50000); //NO XINT
}
if(sign==3)
{
LED1_OFF;
LED2_OFF;
LED3_OFF;
LED4_OFF;
LED5_OFF;
LED6_OFF;
LED7_OFF;
LED8_OFF;
DELAY_US(50000);
LED1_ON;
LED2_ON;
DELAY_US(50000);
LED3_ON;
LED4_ON;
DELAY_US(50000);
LED5_ON;
LED6_ON;
DELAY_US(50000);
LED7_ON;
LED8_ON;
DELAY_US(50000); // XINT3 COME
}
if(sign==4)
{ LED1_ON;
LED2_ON;
LED3_ON;
LED4_ON;
LED5_ON;
LED6_ON;
LED7_ON;
LED8_ON;
DELAY_US(50000);
LED1_OFF;
DELAY_US(50000);
LED2_OFF;
DELAY_US(50000);
LED3_OFF;
DELAY_US(50000);
LED4_OFF;
DELAY_US(50000);
LED5_OFF;
DELAY_US(50000);
LED6_OFF;
DELAY_US(50000);
LED7_OFF;
DELAY_US(50000);
LED8_OFF;
DELAY_US(50000); // XINT4 COME
}
if(sign==5)
{LED1_ON;
LED2_ON;
LED3_ON;
LED4_ON;
LED5_ON;
LED6_ON;
LED7_ON;
LED8_ON;
DELAY_US(50000);
LED1_OFF;
LED2_OFF;
DELAY_US(50000);
LED3_OFF;
LED4_OFF;
LED1_ON;
LED2_ON;
DELAY_US(50000);
LED5_OFF;
LED6_OFF;
LED3_ON;
LED4_ON;
DELAY_US(50000);
LED7_OFF;
LED8_OFF;
LED5_ON;
LED6_ON;
DELAY_US(50000); // XINT5 COME
}
if(sign==6)
{LED1_OFF;
LED2_ON;
LED3_OFF;
LED4_ON;
LED5_OFF;
LED6_ON;
LED7_OFF;
LED8_ON;
DELAY_US(50000);
LED1_ON;
LED2_OFF;
LED3_ON;
LED4_OFF;
LED5_ON;
LED6_OFF;
LED7_ON;
LED8_OFF;
DELAY_US(50000); // XINT5 COME
}
}
}
interrupt void ISRExint3(void)
{
PieCtrlRegsPIEACKall = PIEACK_GROUP12;
sign=3;
}
interrupt void ISRExint4(void)
{
PieCtrlRegsPIEACKall = PIEACK_GROUP12;
sign=4;
}
interrupt void ISRExint5(void)
{
PieCtrlRegsPIEACKall = PIEACK_GROUP12;
sign=5;
}
interrupt void ISRExint6(void)
{
PieCtrlRegsPIEACKall = PIEACK_GROUP12;
sign=6;
}
void configtestled(void)
{
EALLOW;
GpioCtrlRegsGPAMUX1bitGPIO0 = 0; // GPIO0 = GPIO0
GpioCtrlRegsGPADIRbitGPIO0 = 1;
GpioCtrlRegsGPAMUX1bitGPIO1 = 0; // GPIO1 = GPIO1
GpioCtrlRegsGPADIRbitGPIO1 = 1;
GpioCtrlRegsGPAMUX1bitGPIO2 = 0; // GPIO2 = GPIO2
GpioCtrlRegsGPADIRbitGPIO2 = 1;
GpioCtrlRegsGPAMUX1bitGPIO3 = 0; // GPIO3 = GPIO3
GpioCtrlRegsGPADIRbitGPIO3 = 1;
GpioCtrlRegsGPAMUX1bitGPIO4 = 0; // GPIO4 = GPIO4
GpioCtrlRegsGPADIRbitGPIO4 = 1;
GpioCtrlRegsGPAMUX1bitGPIO5 = 0; // GPIO5 = GPIO5
GpioCtrlRegsGPADIRbitGPIO5 = 1;
GpioCtrlRegsGPBMUX2bitGPIO51 = 0; // GPIO51 = GPIO51
GpioCtrlRegsGPBDIRbitGPIO51 = 1;
GpioCtrlRegsGPBPUDbitGPIO51=0;
GpioCtrlRegsGPBMUX2bitGPIO50 = 0; // GPIO50 = GPIO50
GpioCtrlRegsGPBDIRbitGPIO50 = 1;
GpioCtrlRegsGPBPUDbitGPIO50=0;
EDIS;
}
//===========================================================================
// No more
//===========================================================================
最近在用2812编程,遇到一个问题,想请教各位高手,我先说一下自己的一点理解请教高手指点。 PIE一般用到的中断组是INT1-INT12。我们知道他们的优先级顺序是INT1>INT2>INT3…INT11>INT12。在开所有中断使能的前提下,如果不同组(如INT1组的TINT0和INT2组的T1CINT)的中断同时向PIE发出中断请求,
那么PIE会放中断优先级较高(INT1TINT0)的中断过去。同样的在如果是同组的中断请求同时到达的话(如INT2组的),那么也同样按照PIE中断向量表查看同组优先级,CPU响应优先级较高的中断。
我的理解是,
(1)不同组之间的中断可以实现中断嵌套。如INT1组的TINT0和INT2组的T1CINT。当CPU正在响应INT2组的T1CINT中断服务程序这时如果产生了INT1组的TINT0中断的话那么CPU便会产生中断嵌套,先停下T1CINT转而去执行TINT0,
当TINT0中断服务程序执行完之后再去执行剩余没有执行网的INT1中断服务程序。
(2)同组之间的中断不可以实现中断嵌套。如果同样是INT1组的两个中断比如ADCINT和TINT0。当CPU正在响应INT1的中断服务程序时,这时如果产生了ADCINT,尽管ADCINT在INT1组中的优先级比TINT0的优先级高,还是不会产生中断嵌套。
因为同组的中断在向CPU发出中断请求之前先要经过PIE中的应答位PIEACK验证,如果PIEACK为1说明此时正有改组的中断正在响应,PIE不会放响应该发出中断请求的中断源通过,只有等到正在响应的中断服务程序执行完才会去响应刚刚
发出中断请求的中断服务程序。这也就是为什么,我们在中断服务程序的后面都要加上一句PieCtrlPIEACKbitACKx=1;就是为了让应答位清零,可以响应同组的其他中断。
以上两点是我对2812中断嵌套的一点理解,尤其是提到的第(2)点,万望高手不吝指导。
在DSP(数字信号处理器)的编程中,为了实现某些功能,我们通常会用到中断,而中断周期的计算方法如下:
1、首先需要确定所使用的DSP芯片的时钟频率和定时器的计数精度。
2、然后根据所需的中断周期时间来计算出需要经过多少个计数周期才能产生一次中断。例如,设定一个需要50us中断一次的定时器,假设时钟频率为100MHz,定时器精度为16位,那么每秒定时器计数次数为100000000次,50us的计数次数则为5000次,即每达到5000次计数就会产生一次中断。
3、根据DSP芯片的手册和开发工具中提供的配置寄存器和相应的定时器控制寄存器设置定时器中断参数,以及初始化定时器的初始值和中断服务程序。
PIE。根据dsp软件的公告得知,DSP控制器的外设中断扩展模块,对中断进行集中化扩展,使每一级CPU中断均可以响应多个中断源。DSP是数字信号处理的缩写,是一种使用数字处理技术对信号进行处理的技术。
直接在定时中断中设置一个LoopCount,然后不停的LoopCount++,然后再在主程序里的循环里不停的查询LoopCount,达到你要的值就去执行你要的代码,否则就接着循环。你用10Mhz的时钟,想达到非常高的精度本身就不是件容易的事。真想要特别高的精度,可以看看F2812和F28335,150MHz。精度一定能满足你
VEC_ENTRY macro addr
STW B0,--B15 ;把B0内容保存到B15,然后指针变量后移,相当于压栈
MVKL addr,B0
MVKH addr,B0 ;传入参数的地址给B0
B B0 ;程序跳转到B0指向的地址
LDW B15++,B0 ;把之前保存的B0恢复;相当于pop
NOP 2
NOP
NOP
endm
从解释来看,感觉就只是完成一个简单的程序跳转功能,用别的寄存器应该也能实现,非要说有什么特殊用途的话,目前能想到也是在C64X平台下,只有A0、A1。A2、B0、B1、B2可以作为条件寄存器,但这个代码里并不存在条件执行。
以上就是关于关于 DSP 2812 外部中断 XINT1 使用问题全部的内容,包括:关于 DSP 2812 外部中断 XINT1 使用问题、dsp pie怎样控制外设中断传到cpu,cpu对外设的响应过程、dsp的中断周期怎么算等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)