1

我正在尝试在 pic32mx795f512l 上做一个小应用程序,但我无法让它工作。我想要实现的是,adc 以尽可能高的速率不断地从通道 0 获取当前模拟值。如果 16 Word 缓冲区被填满,它应该触发 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);

}
4

1 回答 1

0

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

根据我的经验,这意味着两者中只有一个会获得中断向量,而且它往往是 ISR。

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

于 2017-03-16T01:26:13.733 回答