View previous topic :: View next topic |
Author |
Message |
Sami
Joined: 29 Oct 2014 Posts: 4
|
reading multiple ADC channels using DMA PIC24EP64MC204 |
Posted: Fri Mar 17, 2017 4:11 am |
|
|
Hi guys,
I am trying to create a project that is required to read multiple ADC channels and then fetch them to the DMA channel. I have checked the code example and the datasheet, when i try to enable the DMA on multiple ADC channels and then read them through software (via simple i2c communication) i notice that the result is not consistent. I am expecting to read 3.3 volts on AN4 and i have two temperature sensors on AN0 and AN1, so when i enable these pins the buffer result is composed of five repeated values (i have converted the hex value to voltage value by software):
3.07107843137255
2.71691176470588
2.7046568627451
0.00122549019607843
0.00122549019607843
The first one is for the AN4 and the second two are for the temp sensor. I have made sure by disabling and enabling each pin and then observing the buffer result. I was expecting to get only these 3 values but for some reason i am getting two additional zeros. I am under the impression that if i enable only one ADC pin i should get only 1 repeated value in the buffer, and if i enabled 2 pins i will get 2 repeated values and so one, is this correct ? Or the DMA doesn't work like this ? Thanks in advance and sorry if my question is obvious, this is first time that i worked with DMA.
The pic that i am using is PIC24EP64MC204, ccs compiler revision is 5.069. Here is a sample of my code:
Code: |
#include <24EP64MC204.h>
#device ADC=16
#device ICSP=1
#use delay(clock=140000000,crystal=8000000)
#FUSES NOWDT
#FUSES NOJTAG
#FUSES CKSFSM
#FUSES NOPWMLOCK
#define BUFFER_SIZE 1024
#BANK_DMA
int16 DMA_BUFFER_A[BUFFER_SIZE];
void main()
{
enable_interrupts(INTR_GLOBAL);
setup_adc_ports( sAN0 | sAN1 | sAN4, VSS_VREF);
setup_adc(ADC_CLOCK_INTERNAL);
setup_dma(0, DMA_IN_ADC1, DMA_WORD);
dma_start(0, DMA_CONTINOUS , &DMA_BUFFER_A[0], BUFFER_SIZE);
}
|
And here when i retrieve the buffer by copy it into another array and extract them by i2c communication, (i call these code form software 8 times and on each time i read the page3 to get the results.
Code: |
int i = 0;
for( i = 0 ; i < 64; i++)
{
PAGE03[i * 2 + 1] = (int8) (DMA_BUFFER_A[I2cRetrievingCounterA + i] & 0x00ff);
PAGE03[i * 2] = (int8)((DMA_BUFFER_A[I2cRetrievingCounterA + i] & 0xff00) >> 8);
}
I2cRetrievingCounterA+= 64;
if(I2cRetrievingCounterA >=BUFFER_SIZE)
{
I2cRetrievingCounterA = 0;
}
|
|
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9221 Location: Greensville,Ontario
|
|
Posted: Fri Mar 17, 2017 6:16 am |
|
|
hmm.. I don't use that PIC but
1) you should post a complete small program that others can cut/paste/compile/test. One problem I see is you say you read 3 items but print 5. That could just be a printing loop code error.It'd be nice to see a label with the values( V33 = 3.07 Temp sens 1 = 2.7 ). Ths way you know what to expect as a value...
2) this...setup_adc(ADC_CLOCK_INTERNAL); is a big nono for 16f/18F series PICs. Hopefully others can confirm/deny it is legal to use. I suspect it's OK as your 3V reading is OK...but best to confirm
Jay |
|
|
newguy
Joined: 24 Jun 2004 Posts: 1907
|
|
Posted: Fri Mar 17, 2017 6:24 am |
|
|
Search out and read the DMA documentation and examples from Microchip. The way DMA works is that it can't "pack" readings into contiguous memory. Your 5 readings are due to the DMA assembling readings from AN0, AN1, and AN4 (which you want), and spaces in memory reserved for AN2 and AN3. |
|
|
Sami
Joined: 29 Oct 2014 Posts: 4
|
|
Posted: Fri Mar 17, 2017 6:50 am |
|
|
Thanks guys for the replies, I will check Microchip example, but for some reason when I enable all the 8 ADC I only get these 5 repeated value, but i should get 8. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19499
|
|
Posted: Fri Mar 17, 2017 8:04 am |
|
|
Have a look at this post (in the code library). May well help.
<http://www.ccsinfo.com/forum/viewtopic.php?t=47875&highlight=dma+adc> |
|
|
|