DSP5-TMS32F28377D外设中断学习记录篇

中断架构
C28x CPU 14 个外设中断线。 其中两个(INT13 和 INT14 )分别直接连接到 CPU 定时器 1 2 。 其 余12 个通过增强型外设中断扩展模块(ePIE 或缩写版 PIE )连接到外设中断信号。 PIE 将多达十六个外设中断复用到每个 CPU 中断线中。 它还扩展向量表,以允许每个中断具有自己的 ISR 。 这允许 CPU 支 持大量的外设。
TMS320F2837X 系列 DSP 的中断由 3 级组成,外设级, PIE 级, CPU 级(
PIE ),它们的构成如图:

中断路径分为三个阶段-外设级中断,PIE 级中断和 CPU 级中断。每级中断有自己的使能和标志寄存器。该系统允许 CPU 处理一个中断,而其他中断处于待处理状态,在软件中实现和优先化嵌套中断,并在某些关键任务期间禁用中断。最内核的部分为 CPU 级中断,也就是 CPU只能响应从 CPU 中断线上过来的中断请求,但 28377 中断源众多,CPU 没有那么多中断线在有限中断线的情况下,只能安排中断线进行复用。每级中断有自己的使能和标志寄存器。 该系统允许 CPU 处理一个中断,而其他中断处于待处理状态,在软件中实现和优先化嵌套中 断,并在某些关键任务期间禁用中断。图 2.6.4 显示了 28377 中断的传递路径架构。

当外设产生中断(在 PIE x,通道 y 上)时,它会触发以下事件序列:
1. 中断被锁存在 PIEIFRx.y 中。
2. 如果设置了 PIEIERx.y ,中断将传递。
3. 如果 PIEACK.x 清零,则中断传递, PIEACK.x 被置位。
4. 中断在 IFR.x 中被锁存。
5. 如果设置了 IER.x ,则中断传播。
6. 如果 INTM 清零, CPU 接收中断。
7. 在通道的 D2 或更后阶段的任何指令都要完成。早期阶段的指令被刷新。
8. CPU 将其上下文保存在堆栈中。
9. 清除 IFR.x IER.x INTM 设置。 EALLOW 被清除。
10. CPU PIE 中获取 ISR 向量。 PIEIFRx.y 被清除。
11. CPU 分支到 ISR
中断延迟是 PIEIFRx.y 锁存中断和第一条 ISR 指令进入 CPU 流水线执行阶段之间的时间。最小中断延迟为 14 个 SYSCLK 周期。 ISR 或堆栈存储器上的等待状态将增加延迟。外部中断至少为 GPIO 同步增加两个 SYSCLK 周期,以及额外的输入验证时间(如果使用)。使用 C28x RPT 指令创建的循环不能中断。

 使用与配置

上电时,默认情况下不会启用中断。 PIEIER IER 寄存器被清零, INTM 1 。 应用代码负责配置和使能 所有外设中断。
要启用外设中断,请执行以下步骤:
1. 全局禁止中断( DINT SETC INTM )。
2. 通过设置 PIECTRL 寄存器的 ENPIE 位来使能 PIE
3. 将每个中断的 ISR 向量写入 PIE 向量表中的相应位置,可在 Table 2-2 中找到。
4. 为每个中断设置相应的 PIEIERx 位。 PIE 组和通道分配可以在 Table 2-2 中找到。
5. 为包含已启用中断的任何 PIE 组设置 CPU IER 位。
6. 在外设中使能中断。
7. 全局使能中断( EINT CLRC INTM )。
步骤 4 不适用于直接连接到 CPU。

 

//按键按下,对应数码显示数字+1
#include "F28x_Project.h"     // Device Headerfile and Examples Include File
#include "F2837xD_Ipc_drivers.h"

void GPIO_Setup(void);
void SEG_DATA(unsigned char d);
interrupt void xint1_isr(void);
interrupt void xint2_isr(void);
interrupt void xint3_isr(void);
interrupt void xint4_isr(void);
void ExintInit();

#define   SBIT3     GpioDataRegs.GPBDAT.bit.GPIO58
#define   SBIT2     GpioDataRegs.GPBDAT.bit.GPIO59
#define   SBIT1     GpioDataRegs.GPBDAT.bit.GPIO60
#define   SBIT0     GpioDataRegs.GPBDAT.bit.GPIO61

unsigned char const table[]={//共阴极0~f数码管编码
0xfc,0x60,0xda,0xf2,     //0~3
0x66,0xb6,0xbe,0xe0,    //4~7
0xfe,0xf6               //8~9
};

Uint16 InterruptCount1 = 0,InterruptCount2 = 0,InterruptCount3 = 0,InterruptCount4 = 0;

void main(void)
{
// Step 1. 初始化系统,锁相环,看门狗,外设时钟
   InitSysCtrl();

#ifdef _STANDALONE
#ifdef _FLASH
// 发送引导命令以允许CPU2应用程序开始执行烧写
IPCBootCPU2(C1C2_BROM_BOOTMODE_BOOT_FROM_FLASH);
#else
// 发送引导命令以允许CPU2应用程序开始仿真
IPCBootCPU2(C1C2_BROM_BOOTMODE_BOOT_FROM_RAM);
#endif
#endif


#ifdef _FLASH
   InitFlash();
#endif

// Step 2. 初始化GPIO:
    InitGpio();
    GPIO_Setup();
    ExintInit();
// Step 3. 清除所有中断;初始化中断向量表;禁止CPU中断
    DINT;

// 初始化PIE控制寄存器至默认状态,默认状态所有PIE中断被禁止;所有标志位被清除。
    InitPieCtrl();

//禁止所有CPU中断,清除CPU中断相关标志位。
    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 F2837xD_DefaultIsr.c.
// This function is found in F2837xD_PieVect.c.
    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
    PieVectTable.XINT1_INT = &xint1_isr;//地址赋给PIE通道的这几个中断
    PieVectTable.XINT2_INT = &xint2_isr;
    PieVectTable.XINT3_INT = &xint3_isr;
    PieVectTable.XINT4_INT = &xint4_isr;
    EDIS;   // This is needed to disable write to EALLOW protected registers

    // Step 4. User specific code, enable interrupts:

    // Enable XINT1 and XINT2 in the PIE: Group 1 interrupt 4 & 5
    // Enable INT1 which is connected to WAKEINT:
    PieCtrlRegs.PIECTRL.bit.ENPIE = 1;          // Enable the PIE block
    /*使能PIE通道*/
    PieCtrlRegs.PIEIER1.bit.INTx4 = 1;          // Enable PIE Group 1 INT4
    PieCtrlRegs.PIEIER1.bit.INTx5 = 1;          // Enable PIE Group 1 INT5
    PieCtrlRegs.PIEIER12.bit.INTx1 = 1;          // Enable PIE Group 12 INT1
    PieCtrlRegs.PIEIER12.bit.INTx2 = 1;          // Enable PIE Group 12 INT2
    /*使能PIE组*/
    IER |= M_INT1;//根据CPU向量中断表使能PIE1组和12组
    IER |= M_INT12;

// Enable global Interrupts and higher priority real-time debug events:
    EINT;  // Enable Global interrupt INTM
    ERTM;  // Enable Global realtime interrupt DBGM

    SBIT0=1;DELAY_US(1);
    SBIT1=1;DELAY_US(1);
    SBIT2=1;DELAY_US(1);
    SBIT3=1;DELAY_US(1);

    SEG_DATA(table[0]);
    while(1)
    {
        SEG_DATA(table[InterruptCount2]);
        SBIT0=0;DELAY_US(1);
        SBIT2=1;DELAY_US(1);
        SBIT1=1;DELAY_US(1);
        SBIT3=1;
        DELAY_US(100);
        SBIT0=1;
        SEG_DATA(0);

        SEG_DATA(table[InterruptCount1]);
        SBIT1=0;DELAY_US(1);
        SBIT2=1;DELAY_US(1);
        SBIT3=1;DELAY_US(1);
        SBIT0=1;
        DELAY_US(100);
        SBIT1=1;
        SEG_DATA(0);

        SEG_DATA(table[InterruptCount4]);
        SBIT2=0;DELAY_US(1);
        SBIT1=1; DELAY_US(1);
        SBIT3=1;DELAY_US(1);
        SBIT0=1;
        DELAY_US(100);
        SBIT2=1;
        SEG_DATA(0);

        SEG_DATA(table[InterruptCount3]);
        SBIT3=0;DELAY_US(1);
        SBIT1=1;DELAY_US(1);
        SBIT2=1;DELAY_US(1);
        SBIT0=1;
        DELAY_US(100);
        SBIT3=1;
        SEG_DATA(0);
    }
}

void GPIO_Setup()
{
    GPIO_SetupPinMux(58, GPIO_MUX_CPU1, 0);//BIT3
    GPIO_SetupPinOptions(58, GPIO_OUTPUT, GPIO_PUSHPULL);
    GPIO_SetupPinMux(59, GPIO_MUX_CPU1, 0);
    GPIO_SetupPinOptions(59, GPIO_OUTPUT, GPIO_PUSHPULL);
    GPIO_SetupPinMux(60, GPIO_MUX_CPU1, 0);
    GPIO_SetupPinOptions(60, GPIO_OUTPUT, GPIO_PUSHPULL);
    GPIO_SetupPinMux(61, GPIO_MUX_CPU1, 0);//BIT0
    GPIO_SetupPinOptions(61, GPIO_OUTPUT, GPIO_PUSHPULL);
    GPIO_SetupPinMux(77, GPIO_MUX_CPU1, 0);//dp
    GPIO_SetupPinOptions(77, GPIO_OUTPUT, GPIO_PUSHPULL);
    GPIO_SetupPinMux(78, GPIO_MUX_CPU1, 0);//g
    GPIO_SetupPinOptions(78, GPIO_OUTPUT, GPIO_PUSHPULL);
    GPIO_SetupPinMux(79, GPIO_MUX_CPU1, 0);//f
    GPIO_SetupPinOptions(79, GPIO_OUTPUT, GPIO_PUSHPULL);
    GPIO_SetupPinMux(80, GPIO_MUX_CPU1, 0);//e
    GPIO_SetupPinOptions(80, GPIO_OUTPUT, GPIO_PUSHPULL);
    GPIO_SetupPinMux(81, GPIO_MUX_CPU1, 0);//d
    GPIO_SetupPinOptions(81, GPIO_OUTPUT, GPIO_PUSHPULL);
    GPIO_SetupPinMux(82, GPIO_MUX_CPU1, 0);//c
    GPIO_SetupPinOptions(82, GPIO_OUTPUT, GPIO_PUSHPULL);
    GPIO_SetupPinMux(83, GPIO_MUX_CPU1, 0);//b
    GPIO_SetupPinOptions(83, GPIO_OUTPUT, GPIO_PUSHPULL);
    GPIO_SetupPinMux(85, GPIO_MUX_CPU1, 0);//a
    GPIO_SetupPinOptions(85, GPIO_OUTPUT, GPIO_PUSHPULL);
}

void ExintInit()
{
    EALLOW;
    GpioCtrlRegs.GPAMUX1.bit.GPIO12 = 0;         // GPIO
    GpioCtrlRegs.GPADIR.bit.GPIO12 = 0;          // input
    GpioCtrlRegs.GPAQSEL1.bit.GPIO12 = 1;        // XINT1 Synch to SYSCLKOUT only
    GpioCtrlRegs.GPAMUX1.bit.GPIO13 = 0;         // GPIO
    GpioCtrlRegs.GPADIR.bit.GPIO13 = 0;          // input
    GpioCtrlRegs.GPAQSEL1.bit.GPIO13 = 1;        // XINT2 Synch to SYSCLKOUT only
    GpioCtrlRegs.GPAMUX1.bit.GPIO14 = 0;         // GPIO
    GpioCtrlRegs.GPADIR.bit.GPIO14 = 0;          // input
    GpioCtrlRegs.GPAQSEL1.bit.GPIO14 = 1;        // XINT4 Synch to SYSCLKOUT only
    GpioCtrlRegs.GPAMUX1.bit.GPIO15 = 0;         // GPIO
    GpioCtrlRegs.GPADIR.bit.GPIO15 = 0;          // input
    GpioCtrlRegs.GPAQSEL1.bit.GPIO15 = 1;        // XINT5 Synch to SYSCLKOUT only
    EDIS;
    GPIO_SetupXINT1Gpio(12);    // GPIO12 is XINT1
    XintRegs.XINT1CR.bit.POLARITY = 0;      // Falling edge interrupt
    XintRegs.XINT1CR.bit.ENABLE = 1;        // Enable XINT1
    GPIO_SetupXINT2Gpio(13);    // GPIO13 is XINT2
    XintRegs.XINT2CR.bit.POLARITY = 0;      // Falling edge interrupt
    XintRegs.XINT2CR.bit.ENABLE = 1;        // Enable XINT1
    GPIO_SetupXINT3Gpio(14);    // GPIO14 is XINT4
    XintRegs.XINT3CR.bit.POLARITY = 0;      // Falling edge interrupt
    XintRegs.XINT3CR.bit.ENABLE = 1;        // Enable XINT12
    GPIO_SetupXINT4Gpio(15);    // GPIO15 is XINT5
    XintRegs.XINT4CR.bit.POLARITY = 0;      // Falling edge interrupt
    XintRegs.XINT4CR.bit.ENABLE = 1;        // Enable XINT12
}

void SEG_DATA(unsigned char d)
{
    Uint32 dat1 = 0,dat2 = 0;
     dat1 = d;//假设0,则0xfc=0x1111 1010
     dat1 <<= 13; //左移13位, C组GPIO是从GPIO64开始的(77-64=13)     0x1111 1010 13个0
     dat2 = d;//假设0,则0xfc=0x1111 1010
     dat2 <<= 13;//0x1111 1010 13个0 映射到 95~85-84-83-82-81-80-79-78-77~64
     dat2 &= 0x100000;//0x1111 1010 13个0
     dat2 <<= 1;//1111 0100 12个0 1   映射到 95~85-84-83-82-81-80-79-78-77~64
     dat1 |= dat2;//0x1111 1010 13个0  | 1111 0100 12个0 1 = 0x1111 1110 12个0 1
     GpioDataRegs.GPCDAT.all = dat1;//C组GPIO95-64
}

interrupt void xint1_isr(void)
{
    PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;//PIE组应答
    DELAY_US(1000);
    if(GpioDataRegs.GPADAT.bit.GPIO12 == 0) InterruptCount1++;
    if(InterruptCount1 > 9) InterruptCount1 = 0;

}


interrupt void xint2_isr(void)
{
    PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;
    DELAY_US(1000);
    if(GpioDataRegs.GPADAT.bit.GPIO13 == 0) InterruptCount2++;
    if(InterruptCount2 > 9) InterruptCount2 = 0;

}

interrupt void xint3_isr(void)
{
    PieCtrlRegs.PIEACK.all = PIEACK_GROUP12;
    DELAY_US(1000);
    if(GpioDataRegs.GPADAT.bit.GPIO14 == 0) InterruptCount3++;
    if(InterruptCount3 > 9) InterruptCount3 = 0;

}

interrupt void xint4_isr(void)
{
    PieCtrlRegs.PIEACK.all = PIEACK_GROUP12;
    DELAY_US(1000);
    if(GpioDataRegs.GPADAT.bit.GPIO15 == 0) InterruptCount4++;
    if(InterruptCount4 > 9) InterruptCount4 = 0;

}

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值