Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

dsPIC33fj - using ADC with DMA

Status
Not open for further replies.

maryele

Newbie level 2
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

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top