【转】[原创] CCSV5之外部中断学习
dsp吧
全部回复
仅看楼主
level 2
文章来源于:http://bbs.ickey.cn/group-topic-id-40270.html
作者:barrettzxn
继学会在CCSV5.2中建工程和点亮灯之后,接下来我就学了dsp的中断处理过程。下面,我也来分享一下我的学习过程!
首先放出下图!(来自数据手册)
然后下面有一大段英文。。。。。
翻译一下,大致意思是这样的:
外设级:
当一个外设发生了一个中断,特定的外设寄存器中相应的中断标志位(IF)就会置位。如果相应的中断使能位被设置,外设就会向PIE控制器产生一个中断请求。如果中断在外设级没有被使能,IF位仍然保持置1状态直到被软件清除。如果中断之后使能,IF位仍然是1,中断请求将会被PIE响应。外设寄存器的中断标志应该被手动清除。
PIE级:
PIE把 8个外设和外中断多路复用为一个CPU中断。这些中断被分为12组。同一组的中断复用一个CPU中断。例如:PIE组1复用CPU中断1(INT1),PIE组12复用CPU中断12(INT12)。连接到CPU其余的中断的中断源是没有被复用的,PIE直接将请求传递到CPU。
对于复用的中断源,每个中断组的PIE块中有相应的标志寄存器(PIEIFRx)和使能寄存器(PIEIERx)(X = PIE组1 - PIE组12)。组内的每个位,称为y,对应于一个8路复用的中断,因此PIEIFRx.y 和PIEIERx.y (y =1-8)对应于中断PIE组X(X= 1〜12)。另外,每个PIE中断组都有一个中断答应位。
当有向PIE控制器的请求时,相应的PIE中断标志(PIEIFRx.y)就会置1,如果PIE中断使能位(PIEIERx.y)被设置,PIE控制器就会检查相应的PIEACKx位,确认CPU是否为中断做好准备。如果PIEACKx位已被清除,PIE就会向CPU发送一个中断请求。如果PIEACKx位被置位,PIE等到它别清除,再发送INTx的请求。
CPU级:
当请求被发送到CPU,CPU级相应的与INTx的中断标志位(IFR)被置位,一旦在IFR的标志被设定后,相应的中断不会被服务,直到是但设置了CPU的中断使能寄存器(IER)或调试中断使能寄存器(DBGIER)和全局中断屏蔽位(INTM)。
下面为整个中断响应的过程图
知道了上述过程后,我们还需要了解PIE外设中断向量表,如下图所示,
在该例程中,我们复用CPU的第一组中断INT1,并且使用该组的第4路中断INT1.4(可能描述的不当)。
下面就给出外部中断的例程。
首先先看C2000 Lanuch Pad的按键部分原理图
从这可是看出我们按键一按下,需要检测的是上升沿!当然还需要把内部的上拉电阻去掉(IO默认是上拉的);
下面附上代码!
#include"DSP28x_Project.h" // Device Headerfile and Examples Include File
extern Uint16 RamfuncsLoadStart;
extern Uint16 RamfuncsLoadSize;
extern Uint16 RamfuncsRunStart;
void main(void)
{
memcpy((uint16_t *)&RamfuncsRunStart,(uint16_t *)&RamfuncsLoadStart, (unsigned long)&RamfuncsLoadSize);
InitSysCtrl();//Initialize System Control:
DINT;//失能CPU中断
InitPieCtrl();// 初始化PIE寄存器
IER = 0x0000;
IFR = 0x0000;
InitPieVectTable();//初始化PIE中断表
//允许访问受保护的空间
EALLOW;
GpioCtrlRegs.GPAPUD.bit.GPIO12 = 1; //除能上拉电阻
GpioCtrlRegs.GPAMUX1.bit.GPIO12 = 0; //GPIO12作普通IO使用
GpioCtrlRegs.GPADIR.bit.GPIO12 = 0; //配置为输入
GpioCtrlRegs.GPAQSEL1.bit.GPIO12 = 2; // 6 samples
GpioCtrlRegs.GPACTRL.bit.QUALPRD1 = 0xFF; //采样周期为510*Tsysclk,窗口宽度为5*510*Tsysclk=2550/60M=42.5us
GpioIntRegs.GPIOXINT1SEL.bit.GPIOSEL = 12; //GPIO12作为XINT1的中断源
XIntruptRegs.XINT1CR.bit.POLARITY = 1; //上升沿触发中断
XIntruptRegs.XINT1CR.bit.ENABLE = 1; //外中断1使能
PieCtrlRegs.PIECTRL.bit.ENPIE = 1; //使能PIE
PieCtrlRegs.PIEIER1.bit.INTx4 = 1; //使能INT1.4
// IER |= 0x0001; //使能INT1
IER |= M_INT1; // Enable CPU INT1
//禁止访问受保护的空间
EDIS;
EINT;//使能中断
EALLOW;// 允许访问受保护的空间
// 配置I/O口为输出
GpioCtrlRegs.GPADIR.all=0x000f;
GpioDataRegs.GPACLEAR.bit.GPIO0=1;//LED0亮
GpioDataRegs.GPASET.bit.GPIO1=1;
GpioDataRegs.GPASET.bit.GPIO2=1;
GpioDataRegs.GPASET.bit.GPIO3=1;
// 禁止访问受保护的空间
EDIS;
while(1){}
}
//中断服务程序
interrupt void XINT1_ISR(void)
{
GpioDataRegs.GPATOGGLE.bit.GPIO0=1;
PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;
}
针对中断服务函数,我们可以在F2802x_DefaultIsr.c文件里面找到!
// INT1.4
interrupt void XINT1_ISR(void)
{
// Insert ISR Code here
// To receive more interrupts from this PIE group, acknowledge this interrupt
// PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;
// Next two lines for debug only to halt the processor here
// Remove after inserting ISR Code
asm (" ESTOP0");
for(;;);
}
所以我们在该文件中把它屏蔽,然后放到main函数里
并且添加下面两句语句:
GpioDataRegs.GPATOGGLE.bit.GPIO0=1;//翻转IO电平
PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;//清除该组中断标志
在中断函数中,我把GPIO0的电平翻转,所以烧录程序后上电,一开始是亮的,然后我们按一下GPIO12对应的按键,灯就灭了,再按一下,又亮了。!
上电后,按键前!
按键后!
在这里我也有一个问题!
我看到网上很多的程序是先编写一个中断服务程序,然后把它的地址加到中断向量表中!
例如:
interrupt void Key_On_isr(void)
{
GpioDataRegs.GPATOGGLE.bit.GPIO0=1;
PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;
}
然后在main函数里添加如下语句:PieVectTable.XINT1 = &Key_On_isr;,但是我试过好像不行,不知有哪位高人知道原因
2014年11月26日 07点11分 1
1