View previous topic :: View next topic |
Author |
Message |
starfire151
Joined: 01 Apr 2007 Posts: 195
|
long time to convert ADC value with pic24 |
Posted: Sat Jun 27, 2015 12:44 pm |
|
|
First, I'm running PCWHD V5.044 on a Windows 7 32-bit platform.
I'm having a problem in understanding the timing associated with getting an ADC conversion value from a PIC24EP256GP202 running with an internal rate of 58.96MHz. In looking at scope traces, I can see the external interrupt occurring in the expected amount of time (around 2us, all it does is increments a count and sets a flag for the background to start the conversion). I put a scope marker around the start and end of the ADC conversion routine. The following snippet is from the background routine where the marker is set and cleared:
Code: |
.................... output_high(TEST_PIN);
01548: BSET.B E15.3
.................... set_adc_channel(CH_PK_IN); // start conversion on peak input channel
0154A: CLR AD1CHS0
.................... delay_us(delayADC);
0154C: MOV.B 1037,W0L
0154E: CLR.B W0H
01550: CALL 104C
.................... peakVal = (read_adc() & 0xfff); // 12-bit ADC value
01554: BCLR.B AD1CON1.DONE
01556: BSET.B AD1CON1.SAMP
01558: BTSS.B AD1CON1.DONE
0155A: BRA 1558
0155C: MOV ADC1BUF0,W5
0155E: MOV #FFF,W0
01560: AND W0,W5,W0
01562: MOV W0,103E
.................... output_low(TEST_PIN);
|
The delayADC value is 3.
It takes about 15us to do this conversion, including the 3us delay after starting the conversion. According to the datasheet, the parts is supposed to be able to do 500kbps conversions.
Am I missing something? |
|
|
jeremiah
Joined: 20 Jul 2010 Posts: 1345
|
|
Posted: Sat Jun 27, 2015 12:59 pm |
|
|
where is your setup_adc() call? |
|
|
starfire151
Joined: 01 Apr 2007 Posts: 195
|
|
Posted: Sat Jun 27, 2015 2:04 pm |
|
|
I'm sorry, I should have included that.
I'm setting up the ADC before the main background loop with the following:
Code: |
setup_adc_ports(sAN0);
setup_adc(ADC_CLOCK_INTERNAL);
|
I'm using the internal clock. I'm only using the AN0 input pin.
In addition, I'm setting up the ADC to do 12-bit conversions:
|
|
|
jeremiah
Joined: 20 Jul 2010 Posts: 1345
|
|
Posted: Sat Jun 27, 2015 2:51 pm |
|
|
For most chips (I don't know about this one), the internal clock is only for when doing the conversions during sleep.
Have you tried using the system clock (divided down to Fadc <= 8.5MHz)? |
|
|
starfire151
Joined: 01 Apr 2007 Posts: 195
|
|
Posted: Sat Jun 27, 2015 3:26 pm |
|
|
That's interesting that you say ADC_CLOCK_INTERNAL is usually used for sleep mode. I'd never heard that. I've probably misinterpreted the meaning of that clock for a lot of years. I just thought it was the internal clock for use with the ADC. Thanks for that information.
Forgive my ignorance but why do you say <= 8.5MHz? If I'm running with the internal oscillator at 58.96MHz, what would be a suitable ADC_CLOCK_DIV_ number? Since 58.96MHz / 8.5MHz is roughly 6.9, would a suitable clock value be ADC_CLOCK_DIV_16?
Thanks for responding.
|
|
|
starfire151
Joined: 01 Apr 2007 Posts: 195
|
|
Posted: Sat Jun 27, 2015 4:36 pm |
|
|
Thanks, very much, for your help in pointing me in the right direction. I experimented with the ADC_CLOCK values and got the system to operate MUCH faster!
Thanks, again, for your help. |
|
|
jeremiah
Joined: 20 Jul 2010 Posts: 1345
|
|
Posted: Sat Jun 27, 2015 5:19 pm |
|
|
starfire151 wrote: | That's interesting that you say ADC_CLOCK_INTERNAL is usually used for sleep mode. I'd never heard that. I've probably misinterpreted the meaning of that clock for a lot of years. I just thought it was the internal clock for use with the ADC. Thanks for that information.
Forgive my ignorance but why do you say <= 8.5MHz? If I'm running with the internal oscillator at 58.96MHz, what would be a suitable ADC_CLOCK_DIV_ number? Since 58.96MHz / 8.5MHz is roughly 6.9, would a suitable clock value be ADC_CLOCK_DIV_16?
Thanks for responding.
|
Sorry for the late reply, but to answer your question, the data sheet specified something like a minimum Tad of 117ns for 12bit ADC, which gives just over 8.5MHz, so you want your ADC clock to be some value less than or equal to that so you don't violate the minimum Tad value. Since you said it was roughly 6.9, a divider of 7 or more will work (Note that CCS only defines the powers of 2, but you can look at their pattern and define your own for dividers you need).
Also, something to consider:
It is really really difficult to actually get 12 bits of precision on ADC unless your circuit is perfectly designed. Most people choose 12bits but the actual data they capture has much less resolution. You might consider dropping to 10 bits and you can get an even faster ADC clock (up to 1Msps). You can use a lower divisor (probably 5 or 6, but haven't done the math). |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19496
|
|
Posted: Sun Jun 28, 2015 12:38 am |
|
|
The comment about 'sleep', only applies to the PIC16/18 (the PIC24, is quite happy to use the internal clock), _but_ the internal clock gives (as you have found), a very slow conversion. ADC_CLOCK_INTERNAL, uses an internal RC clock, which is not recommended on the PIC16/18 for use above 1Mhz!. It is a terrifyingly common error to use it 'generically', and even some of the CCS samples do.... :(
Unfortunately, the CCS setup values don't really work logically for these later chips. They stick with 'ADC_CLOCK_DIV' settings, while the processors actually support integer dividers, and this is not made clear.
You can actually just put the divider (-1) into the setup line. So:
Code: |
setup_adc(19|ADC_TAD_MUL_2);
|
gives /20, and 2 Tad acquisition.
So for '6.9', the fastest setting would be:
which gives /7. Add (OR in) a suitable Tad, if needed.
I Haven't checked the calculations to see if /7 is acceptable. |
|
|
|