1 | #include <xc.h>
|
2 | #include "tglpin.h"
|
3 |
|
4 | // User Defines
|
5 | //#define FCY 70000000 // User must calculate and enter FCY here
|
6 | #define NUMSAMP 16 // Number of Samples to Buffer until DMA Interrupt
|
7 |
|
8 | // *****************************************************************************
|
9 | // *****************************************************************************
|
10 | // Section: File Scope or Global Constants
|
11 | // *****************************************************************************
|
12 | // *****************************************************************************
|
13 | /* This section defines the input and the output buffers having an integer data type.
|
14 | The input buffers are stored in either the extended data space or the x-memory area
|
15 | depending on whether the extended data space (EDS) is available in the given dsPIC33E device.
|
16 | */
|
17 | __eds__ int bufferA[NUMSAMP] __attribute__( (eds, space(dma)) );
|
18 | __eds__ int bufferB[NUMSAMP] __attribute__( (eds, space(dma)) );
|
19 |
|
20 | unsigned int adc_messwert = 0;
|
21 | unsigned int PWM_PERIOD=2800; //The PWM period can be computed: PWM_PERIOD = FOSC/(FPWM*PWMInputClockPrescaler)
|
22 | float DC =0.02;
|
23 | float DC1=0.02;
|
24 | float DC2=0.02;
|
25 | float DC3=0.02;
|
26 | float DC4=0.02;
|
27 | float DC5=0.02;
|
28 | unsigned int dmaBuffer = 0;
|
29 |
|
30 | /******************************************************************************
|
31 | * Function: void InitAdc1(void)
|
32 | * Overview: This function is used to configure A/D to convert channel 5 on Timer event.
|
33 | * It generates event to DMA on every sample/convert sequence. ADC clock is configured at 625Khz.
|
34 | *****************************************************************************/
|
35 | void InitAdc1( void )
|
36 | {
|
37 | AD1CON1bits.FORM = 0; // Data Format: 0=Integer, 1=Signed Integer 3=Signed Fraction
|
38 | AD1CON1bits.SSRCG= 0; //
|
39 | AD1CON1bits.SSRC = 7; // 7 Interan Counter (SAMC) ends sampling and starts convertion
|
40 | AD1CON1bits.ASAM = 1; // ADC Sample Control: Sampling begins immediately after conversion
|
41 | AD1CON1bits.AD12B= 0; // 10-bit ADC operation
|
42 | AD1CON2bits.CHPS = 1; // 0: Converts CH0 // 1 for: CH0 and CH1
|
43 | AD1CON3bits.ADRC = 0; // ADC Clock is derived from Systems Clock
|
44 | AD1CON3bits.SAMC = 0; // Auto Sample Time = 0*Tad
|
45 | AD1CON3bits.ADCS = 6; // ADC Conversion Clock Tad=Tcy*(ADCS+1)= (1/70M)*7 = 100ns (10.0Mhz)
|
46 |
|
47 | // ADC Conversion Time for 10-bit Tc=12*Tab = 900ns (1.1MHz)
|
48 | AD1CON1bits.ADDMABM = 1; // 1: DMA buffers are built in conversion order mode ([0]1, [1]=2, [3]=1.. //0 Scatter gather mode
|
49 | AD1CON2bits.SMPI = 0; // SMPI must be 0
|
50 | AD1CON4bits.ADDMAEN = 1; // Converts in ADC1BUF0
|
51 |
|
52 | // AD1CHS0/AD1CHS123: A/D Input Select Register
|
53 | AD1CHS0bits.CH0SA = 0; // MUXA +ve input selection (AIN0) for CH0
|
54 | AD1CHS0bits.CH0SA = 5; // MUXA +ve input selection (AIN5) for CH0
|
55 | AD1CHS0bits.CH0NA = 0; // MUXA -ve input selection (Vref-) for CH0
|
56 | AD1CHS123bits.CH123SA = 0; // MUXA +ve input selection (AIN0) for CH1
|
57 | AD1CHS123bits.CH123NA = 0; // MUXA -ve input selection (Vref-) for CH1
|
58 | IFS0bits.AD1IF = 0; // Clear the A/D interrupt flag bit
|
59 | IEC0bits.AD1IE = 0; // Do Not Enable A/D interrupt
|
60 | AD1CON1bits.ADON = 1; // Turn on the A/D converter
|
61 | TglPinInit();
|
62 | }
|
63 |
|
64 | /******************************************************************************
|
65 | * Function: void InitDma0(void)
|
66 | * Overview: DMA0 configuration function.
|
67 | Direction: Read from peripheral address 0-x300 (ADC1BUF0) and write to DMA RAM
|
68 | AMODE: Register indirect with post increment
|
69 | MODE: Continuous, Ping-Pong Mode
|
70 | IRQ: ADC Interrupt
|
71 | ADC stores results stored alternatively between DMA_BASE[0]/DMA_BASE[16] on every
|
72 | 16th DMA request
|
73 | *****************************************************************************/
|
74 | void InitDma0( void )
|
75 | {
|
76 | DMA0CONbits.AMODE = 0; // Configure DMA for Register indirect with post increment
|
77 | DMA0CONbits.MODE = 2; // 2 Configure DMA for Continuous Ping-Pong mode
|
78 |
|
79 | DMA0PAD = ( int ) &ADC1BUF0; // Point DMA to ADC1BUF
|
80 | DMA0CNT = ( NUMSAMP - 1 ); // Interrupt auf NUMSAMP Transfers
|
81 |
|
82 | DMA0REQ = 13; // ADC1 ? ADC1 Convert Done
|
83 |
|
84 | DMA0STAL = __builtin_dmaoffset( &bufferA );
|
85 | DMA0STAH = __builtin_dmapage( &bufferA );
|
86 |
|
87 | DMA0STBL = __builtin_dmaoffset( &bufferB );
|
88 | DMA0STBH = __builtin_dmapage( &bufferB );
|
89 |
|
90 |
|
91 | IFS0bits.DMA0IF = 0; //Clear the DMA interrupt flag bit
|
92 | IEC0bits.DMA0IE = 1; //Set the DMA interrupt enable bit
|
93 | DMA0CONbits.CHEN = 1;
|
94 | }
|
95 |
|
96 |
|
97 |
|
98 | /******************************************************************************
|
99 | * Function: void ProcessADCSamples(__eds__ int16_t * adcBuffer)
|
100 | * Overview: This function is just a prototype which can be used to perform
|
101 | * some activity on the samples taken by the ADC.
|
102 | *****************************************************************************/
|
103 | void ProcessADCSamples( __eds__ int *adcBuffer )
|
104 | {
|
105 | /* Do something with ADC Samples */
|
106 | int avg=0;
|
107 | avg=(adcBuffer[2]); //+adcBuffer[4]+adcBuffer[6])/3;
|
108 | adc_messwert= avg;
|
109 | IEC0bits.DMA0IE = 1; //Set the DMA interrupt enable bit
|
110 | }
|
111 |
|
112 | /******************************************************************************
|
113 | * Function: void __attribute__((interrupt, auto_psv)) _DMA0Interrupt(void)
|
114 | * Overview: Depending on the dmaBuffer value, the data in bufferA or bufferB is passed
|
115 | *****************************************************************************/
|
116 | void __attribute__ ( (interrupt, auto_psv) ) _DMA0Interrupt( void )
|
117 | {
|
118 | DMA0CONbits.CHEN=0; //Disable DMA
|
119 |
|
120 | if( dmaBuffer == 0 )
|
121 | {
|
122 | ProcessADCSamples( bufferA );
|
123 | }
|
124 | else
|
125 | {
|
126 | ProcessADCSamples( bufferB );
|
127 | }
|
128 |
|
129 | dmaBuffer ^= 1;
|
130 | TglPin(); // Toggle RA4 -> LED D7
|
131 | IFS0bits.DMA0IF = 0; // Clear the DMA0 Interrupt Flag
|
132 | DMA0CONbits.CHEN=1; //Enable DMA
|
133 | }
|