Embedded PIC32MX dma未由adc触发

Embedded PIC32MX dma未由adc触发,embedded,microchip,dma,adc,pic32,Embedded,Microchip,Dma,Adc,Pic32,我正在尝试在pic32mx795f512l上制作一个小应用程序,但我无法让它工作。 我想实现的是,adc以尽可能高的速率从通道0连续获取当前模拟值。如果16字缓冲区已满,则应触发dma将该缓冲区保存在ram中。如果ram缓冲区已满,dma应触发中断。所以我可以在主循环中开始计算。 我现在的问题是dma根本没有被触发。当我在adc上启用中断时,主环路没有运行。 有人知道我做错了什么吗? 以下是我的源代码: /*** DEVCFG0 ***/ #pragma config DEBUG = OFF

我正在尝试在pic32mx795f512l上制作一个小应用程序,但我无法让它工作。 我想实现的是,adc以尽可能高的速率从通道0连续获取当前模拟值。如果16字缓冲区已满,则应触发dma将该缓冲区保存在ram中。如果ram缓冲区已满,dma应触发中断。所以我可以在主循环中开始计算。 我现在的问题是dma根本没有被触发。当我在adc上启用中断时,主环路没有运行。 有人知道我做错了什么吗? 以下是我的源代码:

/*** DEVCFG0 ***/

#pragma config DEBUG = OFF
#pragma config ICESEL = ICS_PGx2
#pragma config PWP = 0xff
#pragma config BWP = OFF
#pragma config CP = OFF

/*** DEVCFG1 ***/

#pragma config FNOSC = PRIPLL
#pragma config FSOSCEN = ON
#pragma config IESO = ON
#pragma config POSCMOD = XT
#pragma config OSCIOFNC = OFF
#pragma config FPBDIV = DIV_8
#pragma config FCKSM = CSDCMD
#pragma config WDTPS = PS1048576
#pragma config FWDTEN = ON

/*** DEVCFG2 ***/

#pragma config FPLLIDIV = DIV_2
#pragma config FPLLMUL = MUL_20
#pragma config FPLLODIV = DIV_1
#pragma config UPLLIDIV = DIV_2
#pragma config UPLLEN = ON

/*** DEVCFG3 ***/

#pragma config USERID = 0xffff
#pragma config FSRSSEL = PRIORITY_7
#pragma config FMIIEN = ON
#pragma config FETHIO = ON
#pragma config FCANIO = ON
#pragma config FUSBIDIO = ON
#pragma config FVBUSONIO = ON

int adcValues[128];

void __ISR(_ADC_VECTOR, IPL7SRS) ADCHandler(void) // interrupt every 8  samples
{

    IFS1bits.AD1IF = 0; // clear interrupt flag
}



void __ISR(_DMA0_VECTOR, ipl5) _IntHandlerSysDmaCh0(void)
{

    int dmaFlags=DCH0INT&0xff; // read the interrupt flags

    /*
    perform application specific operations in response to any interrupt flag set
    */
    DCH0INTCLR=0x000000ff; // clear the DMA channel interrupt flags
    IFS1CLR = 0x00010000; // Be sure to clear the DMA0 interrupt flags

}

unsigned int __attribute__((always_inline)) _VirtToPhys(const void* p) {
    return (int) p < 0 ? ((int) p & 0x1fffffffL) : (unsigned int) ((unsigned char*) p + 0x40000000L);
}

void initADC(void) {


    AD1PCFG = 0xFFFB; // PORTB = Digital; RB2 = analog
    AD1CON1 = 0x0000; // SAMP bit = 0 ends sampling
    // and starts converting

    // turn ADC on | unsigned 32-bit int output | auto-convert after sample finished |
    // don?t stop conversions at interrupt | auto-sample after conversion finished
    AD1CON1 = (1 << 15) | (4 << 8) | (7 << 5) | (0 << 4) | (1 << 2);


    IPC6bits.AD1IP = 7; // INT priority level 7, for shadow register set
    IFS1bits.AD1IF = 0; // clear interrupt flag
    IEC1bits.AD1IE = 1; // enable interrupts

    AD1CHS = 0x00020000; // Connect RB2/AN2 as CH0 input

    AD1CON1SET = 0x8000; // turn on the ADC
}

void initDMA(void) {


    IEC1CLR=0x00010000; // disable DMA channel 0 interrupts
    IFS1CLR=0x00010000; // clear any existing DMA channel 0 interrupt flag
    DMACONSET=0x00008000; // enable the DMA controller
    DCH0CON=0x03; // channel off, priority 3, no chaining
    DCH0ECON=0;
    DCH0ECONbits.CHSIRQ=_ADC_IRQ; // This should map the AD1 ? ADC1 Convert Done Interrupt to start the dma IRQ no. 33 Vector no. 27
    // program the transfer
    DCH0SSA=_VirtToPhys(&ADC1BUF0); // transfer source physical address
   DCH0DSA=_VirtToPhys(adcValues); // transfer destination physical address
    DCH0SSIZ=16; // source size 16 bytes
    DCH0DSIZ=128; // destination size NUM_SAMPS bytes
    DCH0CSIZ=16; // 16 bytes transferred per event
    DCH0INTCLR=0x00ff00ff; // clear existing events, disable all interrupts
    //DCH0INTSET=0x00090000; // enable Block Complete and error interrupts

    DCH0INTbits.CHDDIF=1; //1 = Channel Destination Pointer has reached end of destination (CHDPTR = CHDSIZ)

    IPC9CLR=0x0000001f; // clear the DMA channel 0 priority and sub-priority
    IPC9SET=0x00000016; // set IPL 5, sub-priority 2
    IEC1SET=0x00010000; // enable DMA channel 0 interrupt
    DCH0CONSET=0x80; // turn channel on

}

void main(){
    INTDisableInterrupts(); // disable interrupts before configuring ADC
    initADC();
    initDMA();
    INTEnableSystemMultiVectoredInt(); // enable interrupts at CPU

    while(1);

}

在我看来,问题在于您有两个不同的源试图使用来自ADC的中断向量,DMA通道和ISR

根据我的经验,这意味着这两种方法中只有一种会得到中断向量,它往往是ISR


我建议您删除ADC的ISR。特别是因为您似乎只是重置中断标志,但应该可以配置ADC自动重置标志并中断每个采样数,我已经能够在PIC32mx256f128B上执行此操作了

您的问题非常详细,这很好,但您可能可以提供一个简化的示例?您能否从示例中删除不必要的代码,以便我们只需处理最小的情况?谢谢你的反馈。我已经尽可能地编辑了源代码。现在应该可以编译了。