View previous topic :: View next topic |
Author |
Message |
hayee
Joined: 05 Sep 2007 Posts: 252
|
How to use simultaneous sampling option. |
Posted: Mon Feb 13, 2012 12:46 am |
|
|
Hi,
I am using PIC24HJ128GP306 and CCS compiler version 4.124.
In PIC24HJ128GP306 there is an option for simultaneous sampling.
What I want to do is to hold and sample two ADC channels (one is for voltage and one is for current) and then calculate power at that instant.
Can anyone show me a sample program how to use this simultaneous sampling option and read the analog inputs ?
Thanks |
|
|
hayee
Joined: 05 Sep 2007 Posts: 252
|
|
Posted: Wed Feb 15, 2012 11:18 pm |
|
|
Is there anyone to guide me? |
|
|
SherpaDoug
Joined: 07 Sep 2003 Posts: 1640 Location: Cape Cod Mass USA
|
|
Posted: Thu Feb 16, 2012 7:27 am |
|
|
Not too many people use the PIC24 series and your question is pretty specific. You probably won't get many answers. You likely will have to study the datasheet and figure it out yourself. _________________ The search for better is endless. Instead simply find very good and get the job done. |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9221 Location: Greensville,Ontario
|
|
Posted: Thu Feb 16, 2012 5:31 pm |
|
|
You don't say how often you have to read the data or where the voltage and current measurements are from.
Even 'realtime' so called 'smart meters' update only several times per second NOT every microsecond.
You should read the datasheets for smartmeter 'front ends'. |
|
|
hayee
Joined: 05 Sep 2007 Posts: 252
|
|
Posted: Thu Feb 16, 2012 11:36 pm |
|
|
Thanks for your replies
Voltage and current measurments are coming from generator. I have to read the values manually so there is no timing issue, maybe read 2-3 times in a second.
Will I require asm patch or I can make a function in C using CCS compiler? |
|
|
bkamen
Joined: 07 Jan 2004 Posts: 1615 Location: Central Illinois, USA
|
|
Posted: Fri Feb 17, 2012 2:30 am |
|
|
hayee wrote: | Thanks for your replies
Voltage and current measurments are coming from generator. I have to read the values manually so there is no timing issue, maybe read 2-3 times in a second.
Will I require asm patch or I can make a function in C using CCS compiler? |
You never need an asm patch...
I like to do this:
define a structure that contains the bits of a given PIC register... then use #byte or #word to overlay it on the register I want to fiddle with.
Now you can easily use standard C for all your fun -- PROVIDED the CCS functions are failing you. (or, sometimes you just need more control)
In the case of the dual sample/hold (I used this feature on the PIC18F4431), there's bits you have to set to make it do this feature.. and sample groups...
and then, when you execute a sample run.. it will do all the work for you.. and then put the samples in the ADC FIFO. Then you just read them out until buffer is empty (there's a bit to check for that too).
The things you need to keep in mind is that the buffer should always be emptied -- and don't lose track that it was empty to start with. and so on.
Otherwise, it's pretty straight forward. _________________ Dazed and confused? I don't think so. Just "plain lost" will do. :D |
|
|
hayee
Joined: 05 Sep 2007 Posts: 252
|
|
Posted: Mon Feb 20, 2012 4:06 am |
|
|
bkamen can you give me program which you have written for PIC18F4431 as an example? |
|
|
bkamen
Joined: 07 Jan 2004 Posts: 1615 Location: Central Illinois, USA
|
|
Posted: Mon Feb 20, 2012 3:05 pm |
|
|
Unfortunately, no. It was code I wrote for a client.
However, I could help you get your code working once you post a small compilable example that gets the A/D up and running in the mode of operation you need.
-Ben _________________ Dazed and confused? I don't think so. Just "plain lost" will do. :D |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Feb 20, 2012 3:36 pm |
|
|
See the following link for dual-channel simultaneous ADC sampling
for the 18F4431:
http://www.ccsinfo.com/forum/viewtopic.php?t=42256
Don't post questions about your PIC24 ADC in that thread. That thread
is about the 18F4431. |
|
|
hayee
Joined: 05 Sep 2007 Posts: 252
|
|
Posted: Tue Feb 21, 2012 5:19 am |
|
|
I want to read two analog channels simultaneously.
For this i set ADC registers as follow
Quote: |
adcon1=0xe8;
initially ADC will be off "bit 15 ADON=0"
bit 13 ADSIDL=0,
bit 12 ADDMABM=0,
ADC in 10-bit mode "bit 10 AD12B=0"
Form integer "bit9-8 00"
SSRC "bit7-5 SSRC=111" don't wanna use any interrupt or timer
SIMSAM "bit 3 SIMSAM=1" sample CH0 and CH1 simultenously
ASAM "bit 2 ASAM=0" sampling begins when SAMP bit is set
SAMP "bit 1 SAMP=0" can be change when sampling is required
DONE "bit 0 DONE" looking if conversion is done or not
ad1con2=0x100;
VCFG "bit 15-13 VCFG=000" Vrefh=AVdd, Vfrel=AVss
CSCNA "bit 10 CSCNA=0" Do not scan input
CHPS "bit 9-8 CHPS=01" convert CH0 and CH1
BUFS "bit 7 BUFS=0"
SMPI "bit 5-2 SMPI=0000"
BUFM "bit 1 BUFM=0"
ALTS "bit 0 ALTS=0"
ad1con3=0x9f05;
ADRC "bit 15 ADRC=1" ADC internal clock
SAMC "bit 12-8 SAMC=11111" Auto sample Time bit
ADCS "bit 7-0 ADCS=00000101" ADC Conversion clock
ad1con4= this is for DMA, Have i use it for simultaneous sampling to store data in array?
ad1chs123=0x0000 their default values
ad1chs0=0x0000 their default values
ad1pcfgl=0xfffc for selecting analog AN0 and AN1
|
Are they correct or not?
Is it nessasary to use DMA for storing data coming from both channels or i can use simply variables to store data?
In my program window i initialize all the parameters like tht
Code: |
#include <adc_simultenous.h>
#byte ad1con1 =0x0320
#byte ad1con2 =0x0332
#byte ad1con3 =0x0324
#byte ad1con4 =0x0332
#byte ad1chs123=0x0326
#byte ad1chs0 =0x0328
#byte ad1cssh =0x032e
#byte ad1cssl =0x0330
#byte ad1pcfgh =0x032a
#byte ad1pcfgl =0x032c
#bit adon=ad1con1.15
#bit samp=ad1con1.1
#bit done=ad1con1.0
void main()
{
ad1con1=0xe8;
ad1con2=0x100;
ad1con3=0x9f05;
ad1chs123=0x0000;
ad1chs0=0x0000;
ad1pcfgl=0xfffc;
while(1)
{
}
}
|
Is it correct?
what should be the next step to read the channels? |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Feb 21, 2012 12:36 pm |
|
|
I don't have the PCD compiler so I can't help that much. Very few people
who like to answer questions have the PCD compiler. Probably hardly
anyone wants to read the PIC24HJ128GP306 data sheet and analyze the
correct register settings for an obscure topic such as simultaneous ADC
readings. For those reasons, the chances of getting a reply are low.
Basically, you probably need to solve the problem by yourself. |
|
|
bkamen
Joined: 07 Jan 2004 Posts: 1615 Location: Central Illinois, USA
|
|
Posted: Tue Feb 21, 2012 10:41 pm |
|
|
hayee wrote: |
Code: | void main()
{
ad1con1=0xe8;
ad1con2=0x100;
ad1con3=0x9f05;
ad1chs123=0x0000;
ad1chs0=0x0000;
ad1pcfgl=0xfffc;
while(1)
{
}
}
|
Is it correct?
what should be the next step to read the channels? |
Well, at some point, you need to turn on the converter (ad1con1.15).
You don't need to worry about DMA at the moment. Start simple -- then once you know it works, add fancy.
Read AD1CON1 bits 3,2,1 carefully. If you use an ISR to collect samples, bit 2 will be 1. If you want to do it manually (even with an ISR) you'll want 1=1 to start.
AD1CON2 =0x100, so you only want to AD CH0 and 1? I assume so.
AD1CON3 = 0x9F05 -- I'll assume this is what you want.
AD1CON4 = You don't set. You might need to look at this.
AD1CHS123 = here you set to 0. I'm assuming this is what you want.
AD1CHS0 = here you set to 0. I'm assuming this is also what you want.
AD1CSSH = you don't set at all.
AD1PCFGH = you don't set.
AD1PCFGL = you set for AN0-AN1 == Analog mode.
From here, you read ch:16.9 "Simultaneous Sampling Enable"
From there, you read ch:16.16 on how to pick up your samples.
You can look at the functions in the pcd.chm but honestly, because of the simultaneous S/H stuff you're doing, you may want to try doing it the way you're doing it now.
-ben _________________ Dazed and confused? I don't think so. Just "plain lost" will do. :D |
|
|
hayee
Joined: 05 Sep 2007 Posts: 252
|
|
Posted: Thu Mar 01, 2012 5:19 am |
|
|
I tried to sample one channel (CH0) and it seems ok. The code is like that
Code: |
#byte adc1buf0 =0x0300
#byte ad1con1 =0x0320
#byte ad1con2 =0x0332
#byte ad1con3 =0x0324
#byte ad1con4 =0x0332
#byte ad1chs123=0x0326
#byte ad1chs0 =0x0328
#byte ad1cssh =0x032e
#byte ad1cssl =0x0330
#byte ad1pcfgh =0x032a
#byte ad1pcfgl =0x032c
#bit adon=ad1con1.15
#bit samp=ad1con1.1
#bit done=ad1con1.0
void main()
{
int16 adcval;
ad1con1=0x0000;
ad1con2=0x0000;
ad1con3=0x0002;
ad1pcfgl=0xfffb;
ad1chs0=0x0002;
ad1cssl=0x0000;
adon=1;//ADC ON
while(1)
{
samp=1;//start sampling
delay_ms(100);//some delay
samp=0;//stop sampling and start conversion
while(!done);//while conversion not done stay here
adcval=adc1buf0;//when conversion done save value form buffer to variable.
printf(" %lu ",adcval);//print that value.
}
} |
For two channels scanning I use the registers as
Code: |
ad1con1=0x0008;
ad1con2=0x0200;
ad1con3=0x0002;
ad1con4=0x0000;
ad1chs123=0x0000;
ad1chs0=0x0000;
ad1pcfgl=0xfffc;
ad1cssl=0x0000;
|
Now my question is when I had only one channel I was scanning and storing result like that
Code: |
samp=1;//start sampling
delay_ms(100);//some delay
samp=0;//stop sampling and start conversion
while(!done);//while conversion not done stay here
adcval=adc1buf0;//when conversion done save value from buffer to variable.
|
How should I do to scan and save both channels result in different variables? |
|
|
hayee
Joined: 05 Sep 2007 Posts: 252
|
|
Posted: Sat Mar 03, 2012 1:42 am |
|
|
If one channel can be sampled easily by monitoring the DONE bit.if DONE bit goes high, it means conversion is done and we can read the value from buffer. As shown in the figure
http://www.mediafire.com/i/?ix8k2cimq6kc4oc
But how to read the values when i have to scan more than one channel ?As in the following image if i am sampling 4 channels then after 4 conversions DONE bit will be high and if i read the buffer it will show me last conversion values, other 3 values will be lost.
My question is that how I can read those 3 values without losing them?
What should be the technique I have to use to read all the 4 conversions?
http://www.mediafire.com/i/?cz1dbxgcc3n9gae |
|
|
hayee
Joined: 05 Sep 2007 Posts: 252
|
|
Posted: Wed Mar 14, 2012 1:35 am |
|
|
I have tried to write a code for simultaneous sample for two analog inputs using timer3 trigger option but is it not working.it is taking only one analog input AN0 and shows the result on hyperterminal
Here is my code..some one point me out where i am wrong
Code: |
#include <24HJ128GP306.h>
#FUSES HS,NOWDT,PR//High speed Osc (> 4mhz for PCM/PCH) (>10mhz for PCD)
#use delay(clock=20000000)
#use rs232(baud=19200, UART1, stream=port1)
//***adc1 registers***
#word adc1buf0 =0x0300
#word ad1con1 =0x0320
#word ad1con2 =0x0332
#word ad1con3 =0x0324
#word ad1con4 =0x0332
#word ad1chs123=0x0326
#word ad1chs0 =0x0328
#word ad1cssh =0x032e
#word ad1cssl =0x0330
#word ad1pcfgh =0x032a
#word ad1pcfgl =0x032c
#bit adon=ad1con1.15
#bit samp=ad1con1.1
#bit done=ad1con1.0
#bit bufs=ad1con2.7
//***timer3 registers***
#word pr3=0x010e
#word t3con=0x0112
#bit ton=t3con.15
//***interrupts register***
#word ifs0=0x0084
#word iec0=0x0094
#word ipc3=0x00aa
#word sr=0x0042
#bit ad1if=ifs0.13
#bit ad1ie=iec0.13
int16 b[3];
int i,c;
void main()
{
printf(" start ");
ad1con1=0x004c;//ADC off, 10-bit, integer format, Timer3 for sample clock,
//SIMSAM=1, auto sampling=1
ad1con2=0x0100;//Vrefl=AVss Vrefh=AVdd, Do not scan input, convert CH0 & CH1,
//input select for sample A
ad1con3=0x0003;//system clock, auto sample=0, adc conversion=adcs=19
ad1con4=0x0000;//
ad1chs123=0x0101;//CH1- CH2- CH3- input is Vrefl
//CH1+ AN3, CH2+ AN4, CH3+ AN5
ad1chs0=0x0000;//CH0- input is Vrefl, CH0+ input is AN0
ad1cssh=0x0000;//skip ANx for input scan
ad1cssl=0x0000;//skip ANx for input scan
ad1pcfgl=0xfff6;//selecting AN0 and AN3
ad1pcfgh=0xffff;//
done=0;
ipc3=0x0070;//interrupt priority for ADC1 is 7
ad1if=0;
ad1ie=1;
adon=1; //ADC ON
t3con=0x0000;//
pr3=1250;
ton=1;
i=0;
while(1)
{
if(c==1)
{
printf(" 1=%lu ",b[1]);
printf(" 2=%lu ",b[2]);
c=0;
}
}
}
#int_ADC1
void AD_isr(void)
{
if(i>0)
{
b[i]=adc1buf0;
i++;
adc1buf0=0;
}
else
{
i=1;
}
if(i==3)
{
i=0;c=1;
}
} |
|
|
|
|