dsPIC33fj - using ADC with DMA

Status
Not open for further replies.

maryele

Newbie level 2
Joined
Feb 27, 2014
Messages
2
Helped
0
Reputation
0
Reaction score
0
Trophy points
1
Visit site
Activity points
46
Hello,

am using dsPIC33fj, am trying to read(sample) a signal using the ADC and DMA. I've initialized both functions, am getting an error " due to software break point in user code" but i dont know why or where.. also i want to ask how can i read the stored samples in the DMA memory ?

the problem is that I was using the ADC only to get the samples but once i added an arithmetic equation to the code after sampling, the sample rate decreases.. I thought that the DMA would help to fix this issue since it won't use the CPU..

note: its my first time to use the DMA

the following is the code i've written:


Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
"#include "xc.h"
#include "lcd.h"
#include "delay.h"
#include <stdio.h>
 
#define MAX_CHNUM 1 // Highest Analog input number (AN4,AN5,AN10,AN13)
#define SAMP_BUFF_SIZE 16 //size of input buffer/channel
#define NUM_CHS2SCAN 1 //Number of channels
 
  // Select internal FRC at POR
_FOSCSEL(FNOSC_FRC);
// Enable clock switching and configure POSC in XT mode
_FOSC(FCKSM_CSECMD & OSCIOFNC_OFF & POSCMD_XT);
 
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)));
 
void initDMA(void)
{
DMA0CONbits.AMODE = 0b10; // Peripheral indirect addressing mode
DMA0CONbits.MODE = 0b10; //Continuous Ping-Pong mode
DMA0PAD=(int)&ADC1BUF0; //contains the static address of the peripheral data register
DMA0CNT = 31; //8*4-1, the block transfer complete
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
}
 
#define MAX_CHNUM 1 // Highest Analog input number (AN4,AN5,AN10,AN13)
#define SAMP_BUFF_SIZE 8 //size of input buffer/channel
#define NUM_CHS2SCAN 1 //Number of channels
// Number of locations for ADC buffer = 14 x 8 = 112 words
//The buffer should be aligned to 128 words or 256 bytes
 
void initADC(void)
{
AD1CON1bits.FORM = 2; // fractional
AD1CON1bits.SSRC = 2; // Timer3 as sample clock source
AD1CON1bits.ASAM = 1; //auto sampling
AD1CON1bits.AD12B = 0; // 12-bit ADC operation
//AD1CON1bits.SIMSAM = 1; //Simultaneous sampling
//AD1CON2bits.CSCNA = 1; // Scan Inputs
AD1CON2bits.CHPS = 0;
AD1CON3bits.ADRC = 0; // ADC Clock is derived from Systems Clock
AD1CON3bits.ADCS = 63; // Tad=Tcy*(ADCS+1)= (1/40M)*64 = 1.6us (625Khz)
// ADC Conversion Time for 10-bit Tc=12*Tab = 19.2us AD1CON1bits.ADDMABM = 0; //scatter/gather mode
AD1CON2bits.SMPI = 0; // 4 ADC Channel is scanned
AD1CON4bits.DMABL = 0b011; // Each buffer contains 8 words
AD1CSSH = 0x0000; //no scan for AN16-31
 
//AD1PCFGH/AD1PCFGL: Port Configuration Register
AD1PCFGL=0xFFFF;
AD1PCFGH=0xFFFF;
 
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
TMR3 = 0x0000;
PR3 = 1600;
T3CON = 0x8000;
}
 
int main(void)
{
 
     // Configure PLL prescaler, PLL postscaler, and PLL divisor
PLLFBD=30; // M = 32
CLKDIVbits.PLLPRE=0; // N1 = 2
CLKDIVbits.PLLPOST=0; // N2 = 2
// Initiate clock switch to primary oscillator with PLL (NOSC = 0b011)
__builtin_write_OSCCONH(0x03);
__builtin_write_OSCCONL(0x01);
// Wait for clock switch to occur
while (OSCCONbits.COSC != 0b011);
// Wait for PLL to lock
while(OSCCONbits.LOCK!=1) {};
 
int i=0;
float store[1000];
 initDMA();
 initADC();
 
 TRISA = 0x0000;         //bit 7 input on PORTA- S5, Data direction register -input=1
 int ADCValueT;
 double temp;//,temperature;
    int u=0;
           while (u<1000)
           {
     while(!IFS0bits.AD1IF);
    ADCValueT = ADC1BUF0;
    IFS0bits.AD1IF = 0 ;
    temp =(ADCValueT*3.3)/1024.0;
                //temperature=(temp-0.5)/0.01;
             store[i]=temp;
                u=u+1;
           }
    PORTA=0x00FF;
    return 0;
}
 
void ProcessADCSamples(int * AdcBuffer)
{
 int i=0;
 int s[20];
 while(i<16)
 {
     s[i]= ((*AdcBuffer)*3.3)/1024.0 ;
     *AdcBuffer++;
 }
}
 
int DmaBuffer=0;
void __attribute__((interrupt, no_auto_psv)) _DMA0Interrupt(void)
{
 if(DmaBuffer == 0)
 {
 ProcessADCSamples(&BufferA[1][0]);
 }
 else
 {
 ProcessADCSamples(&BufferB[1][0]);
 }
 DmaBuffer ^= 1;
 IFS0bits.DMA0IF = 0; // Clear the DMA0 Interrupt Flag
}

 
Last edited by a moderator:

Status
Not open for further replies.

Similar threads

Cookies are required to use this site. You must accept them to continue using the site. Learn more…