#if defined(__dsPIC33F__) #include "p33fxxxx.h" #elif defined(__PIC24H__) #include "p24fxxxx.h" #endif #include "adcDrv1.h" #include "math.h" // Define Message Buffer Length for ECAN1/ECAN2 #define MAX_CHNUM 5 // Highest Analog input number in Channel Scan #define SAMP_BUFF_SIZE 8 // Size of the input buffer per analog input #define NUM_CHS2SCAN 2 // Number of channels enabled for channel scan // Number of locations for ADC buffer = 6 (AN0 to 5) x 8 = 48 words // Align the buffer to 128 words or 256 bytes. This is needed for peripheral indirect mode int BufferA[MAX_CHNUM+1][SAMP_BUFF_SIZE] __attribute__((space(dma),aligned(256))); int BufferB[MAX_CHNUM+1][SAMP_BUFF_SIZE] __attribute__((space(dma),aligned(256))); char i; char j; char m = 30; int speicher[35][3]; void berechnung(void); void PWM(int zeit); void ProcessADCSamples(int * AdcBuffer); /*============================================================================= ADC Initialisation for Channel Scan =============================================================================*/ void initAdc1(void) { AD1CON1bits.FORM = 3; // Data Output Format: Signed Fraction (Q15 format) AD1CON1bits.SSRC = 2; // Sample Clock Source: GP Timer starts conversion AD1CON1bits.ASAM = 1; // ADC Sample Control: Sampling begins immediately after conversion AD1CON1bits.AD12B = 0; // 10-bit ADC operation AD1CON2bits.VCFG = 0; AD1CON1bits.SIMSAM = 1; // AD1CON2bits.CSCNA = 1; // Scan Input Selections for CH0+ during Sample A bit AD1CON2bits.CHPS = 11; // Converts CH1/3 AD1CON3bits.ADRC = 0; // ADC Clock is derived from Systems Clock AD1CON3bits.ADCS = 11; // ADC Conversion Clock Tad=Tcy*(ADCS+1)= 150ns // ADC Conversion Time for 10-bit Tc=12*Tab = 19.2us // Complete Conversion Time = Tc + Tad = 25us AD1CON3bits.SAMC = 3; AD1CON1bits.ADDMABM = 0; // DMA buffers are built in scatter/gather mode AD1CON2bits.SMPI = (NUM_CHS2SCAN-1); // 2 ADC Channel is scanned AD1CON4bits.DMABL = 3; // Each buffer contains 8 words AD1CHS123bits.CH123SA = 1; //AD1CSSH/AD1CSSL: A/D Input Scan Selection Register AD1CSSLbits.CSS3=1; // Enable AN3 for channel scan (Mikrofonverstärker1) AD1CSSLbits.CSS5=1; // Enable AN5 for channel scan (Mikrofonverstärker2) //AD1PCFGH/AD1PCFGL: Port Configuration Register AD1PCFGL=0xFFFF; // Alles Digitale Eingänge AD1PCFGLbits.PCFG3 = 0; // AN3 as Analog Input AD1PCFGLbits.PCFG5 = 0; // AN5 as Analog Input IFS0bits.AD1IF = 0; // Clear the A/D interrupt flag bit IEC0bits.AD1IE = 0; // Do Not Enable A/D interrupt AD1CON1bits.ADON = 1; // Turn on the A/D converter } /*============================================================================= Timer 3 is setup to time-out every 604,5 microseconds (50Khz Rate). As a result, the module will stop sampling and trigger a conversion on every Timer3 time-out, i.e., Ts=604,5us. Mikrophone sind im Abstand von 20,7 cm auszurichten. =============================================================================*/ void initTmr3() { TMR3 = 0x0000; PR3 = 200000; // 24180 Trigger ADC1 every 16kHz IFS0bits.T3IF = 0; // Clear Timer 3 interrupt IEC0bits.T3IE = 0; // Disable Timer 3 interrupt T3CONbits.TON = 1; // Start Timer 3 } // DMA0 configuration // Direction: Read from peripheral address 0-x300 (ADC1BUF0) and write to DMA RAM // AMODE: Peripheral Indirect Addressing Mode // MODE: Continuous, Ping-Pong Mode // IRQ: ADC Interrupt void initDma0(void) { DMA0CONbits.AMODE = 2; // Configure DMA for Peripheral indirect mode DMA0CONbits.MODE = 2; // Configure DMA for Continuous Ping-Pong mode DMA0PAD=(int)&ADC1BUF0; DMA0CNT = (SAMP_BUFF_SIZE*NUM_CHS2SCAN)-1; DMA0REQ = 13; // Select ADC1 as DMA Request source DMA0STA = __builtin_dmaoffset(BufferA); DMA0STB = __builtin_dmaoffset(BufferB); IFS0bits.DMA0IF = 0; //Clear the DMA interrupt flag bit IEC0bits.DMA0IE = 1; //Set the DMA interrupt enable bit DMA0CONbits.CHEN=1; // Enable DMA } /*============================================================================= _DMA0Interrupt(): ISR name is chosen from the device linker script. =============================================================================*/ unsigned int DmaBuffer = 0; void __attribute__((interrupt, no_auto_psv)) _DMA0Interrupt(void) { if(DmaBuffer == 0) { ProcessADCSamples(&BufferA[3][0]); ProcessADCSamples(&BufferA[5][0]); } else { ProcessADCSamples(&BufferB[3][0]); ProcessADCSamples(&BufferB[5][0]); } DmaBuffer ^= 1; IFS0bits.DMA0IF = 0; // Clear the DMA0 Interrupt Flag } void ProcessADCSamples(int * AdcBuffer) { speicher[i+2][j] = *AdcBuffer; j^=1; if(j==1) { i++; } if (i == m & j == 1) { berechnung(); } }