DSP篇_28335中断的设置及进入(以AD为例)

28335中断的设置步骤及进入

  • 1.问题背景
  • 2.配置中断的步骤
  • 3.最后

1.问题背景

dsp断断续续用了也快一年了,以前就用用CAN,最近初次尝试用ad模块,想用来采采信号。但是无奈手生,以及ADC配置过程中出现了一些问题,中断服务程序进不去,后来看了TI官方的例程,终于又想明白,这次一定得记下来,搞工科做实验的,哪有什么都记得住,尤其是不常用的。

2.配置中断的步骤

严格按照TI或者成熟的例程来就不会错,其实这些例程人家模板都给做好了,按照段落填写就是。

下面贴上TI的"Example_2833xAdcSoc"例程。

// Included Files
//
#include "DSP28x_Project.h"     // Device Headerfile and Examples Include File

//
// Function Prototypes
//
__interrupt void adc_isr(void);
//**中断函数声明,如果不想用库里自带的函数名字,那就在这里声明一个,这样就可以根据自己需要设置中断函数的名字**

//
// Globals
//
Uint16 LoopCount;
Uint16 ConversionCount;
Uint16 Voltage1[10];
Uint16 Voltage2[10];

//
// Main
//
void main(void)
{
    //
    // Step 1. Initialize System Control:
    // PLL, WatchDog, enable Peripheral Clocks
    // This example function is found in the DSP2833x_SysCtrl.c file.
    //
    InitSysCtrl();

    EALLOW;
    #if (CPU_FRQ_150MHZ)     // Default - 150 MHz SYSCLKOUT
        //
        // HSPCLK = SYSCLKOUT/2*ADC_MODCLK2 = 150/(2*3)   = 25.0 MHz
        //
        #define ADC_MODCLK 0x3
    #endif
    #if (CPU_FRQ_100MHZ)
        //
        // HSPCLK = SYSCLKOUT/2*ADC_MODCLK2 = 100/(2*2)   = 25.0 MHz
        //
        #define ADC_MODCLK 0x2
    #endif
    EDIS;

    //
    // Define ADCCLK clock frequency ( less than or equal to 25 MHz )
    // Assuming InitSysCtrl() has set SYSCLKOUT to 150 MHz
    //
    EALLOW;
    SysCtrlRegs.HISPCP.all = ADC_MODCLK;//由于是ADC,所以需要设置时钟分频
    EDIS;

    //
    // Step 2. Initialize GPIO:
    // This example function is found in the DSP2833x_Gpio.c file and
    // illustrates how to set the GPIO to it's default state.
    //
    // InitGpio();  // Skipped for this example

    //
    // 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_PieCtrl.c 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_DefaultIsr.c.
    // This function is found in DSP2833x_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 register
    PieVectTable.ADCINT = &adc_isr;//将中断服务程序的函数名放在这,作为中断的入口
    EDIS;    // This is needed to disable write to EALLOW protected registers

    //
    // Step 4. Initialize all the Device Peripherals:
    // This function is found in DSP2833x_InitPeripherals.c
    //
    // InitPeripherals(); // Not required for this example
    InitAdc();  // For this example, init the ADC

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

    //
    // Enable ADCINT in PIE
    //
    PieCtrlRegs.PIEIER1.bit.INTx6 = 1;//PIE级:还要设置开启相应PIE向量对应组,对应位的中断使能,AD中断是第1组第6个
    IER |= M_INT1;      // Enable CPU Interrupt 1	CPU级: CPU级也要开启相应中断线的使能位
    EINT;               // Enable Global interrupt INTM
    ERTM;               // Enable Global realtime interrupt DBGM

    LoopCount = 0;
    ConversionCount = 0;

    //
    // Configure ADC
    //
    AdcRegs.ADCMAXCONV.all = 0x0001;       // Setup 2 conv's on SEQ1
    AdcRegs.ADCCHSELSEQ1.bit.CONV00 = 0x3; // Setup ADCINA3 as 1st SEQ1 conv.
    AdcRegs.ADCCHSELSEQ1.bit.CONV01 = 0x2; // Setup ADCINA2 as 2nd SEQ1 conv.
    
    //
    // Enable SOCA from ePWM to start SEQ1
    //
    

    AdcRegs.ADCTRL2.bit.INT_ENA_SEQ1 = 1;  // Enable SEQ1 interrupt (every EOS)

    //
    // Assumes ePWM1 clock is already enabled in InitSysCtrl();
    //


    //
    // Wait for ADC interrupt
    //
    for(;;)
    {
    	AdcRegs.ADCTRL2.bit.SOC_SEQ1 = 1;
        LoopCount++;
    }
}

//
// adc_isr - 
//
__interrupt void  
adc_isr(void)
{
    Voltage1[ConversionCount] = AdcRegs.ADCRESULT0 >>4;
    Voltage2[ConversionCount] = AdcRegs.ADCRESULT1 >>4;

    //
    // If 40 conversions have been logged, start over
    //
    if(ConversionCount == 9)
    {
        ConversionCount = 0;
    }
    else
    {
        ConversionCount++;
    }

    //
    // Reinitialize for next ADC sequence
    //
    AdcRegs.ADCTRL2.bit.RST_SEQ1 = 1;         // Reset SEQ1 
    AdcRegs.ADCST.bit.INT_SEQ1_CLR = 1;       // Clear INT SEQ1 bit
    PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;   // Acknowledge interrupt to PIE

    return;
}

//
// End of File
//

结论:静下心来,按照步骤走,总不会错的

3.最后

看起来TI的例程很简单、简洁,但是当加入很多模块,逻辑复杂后,这么简单的程序还是会出错。

一生二,二生三,三生万物。

你可能感兴趣的:(DSP篇_28335中断的设置及进入(以AD为例))