Documentos de Académico
Documentos de Profesional
Documentos de Cultura
Author Message
Joined: 11 Feb 2007 I've been attempting to write a program for the 16f877 that reads a variable dc voltage and
Posts: 8
Location: Cedar Rapids adjusts the duty cycle on the output (via the PWM). I started out using a modified example from
PIC-C with limited sucess. The output on the scope had a continuously changing duty cycle for a
constant input voltage. I'm fairly certain that there is a problem with the analog to digital
conversion, but am uncertain of what is causing this issue. Any advice would be appreciated.
Code:
#include <16F877.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=10000000)
void main() {
char selection;
byte value;
selection = '2';
switch(selection) {
case '1' : setup_timer_2(T2_DIV_BY_1, 127, 1);
break;
case '2' : setup_timer_2(T2_DIV_BY_4, 127, 1);
break;
case '3' : setup_timer_2(T2_DIV_BY_16, 127, 1);
break;
}
setup_port_a(ALL_ANALOG);
setup_adc(adc_clock_internal);
set_adc_channel( 0 );
while( TRUE ) {
value=read_adc();
1 от 6 26.2.2007 г. 09:43
CCS :: View topic - Stability issues with ADC? http://ccsinfo.com/forum/viewtopic.php?t=29875&highlight=rea...
Joined: 08 Sep 2003 Change the value you read to a 16 bit number. Both the ADC and PWM support 10 bits of
Posts: 1104
Location: Houston resolution.
Code:
INT16 value;
Look at the recommended ADC clock sources, and as a second comment, think 'time'. At 10MHz,
the internal RC clock, is _not_ recommended for the ADC (not above 1MHz).
There is a minimum time specified between ADC reads, of 2Tad. You are only updating the PWM
registers, which does not wait for the PWM.
Consider synchronising the loop to the PWM frequency.
Best Wishes
I may be seeing some noise on lower input voltages. I will try a low pass filter first, and then try
Joined: 11 Feb 2007
Posts: 8 your suggestions. They are all very helpful; thank you.
Location: Cedar Rapids
Did I hear that the ADC should not use the internal clock for > 1MHz ?
Joined: 13 Jan 2007
Posts: 30
I am using 10bit ADC on the 877a with internal clock and ref and facing unstable values (what
could the reson be besides noise ?)
2 от 6 26.2.2007 г. 09:43
CCS :: View topic - Stability issues with ADC? http://ccsinfo.com/forum/viewtopic.php?t=29875&highlight=rea...
Quote:
Joined: 06 Sep 2003
Posts: 6756 Did I hear that the ADC should not use the internal clock for > 1MHz ?
I think every PIC data sheet has that warning in the A/D section.
You have to read the data sheet when you use a peripheral module.
There are always "gotchas" that must be kept in mind. You can't
just choose setup parameters based on what "looks good".
When I made the comment that his code works, I wasn't trying to
undercut Ttelmah's statement. I myself have made the same
statement and referenced the data sheet as shown above.
His problem with unstable values could be due to using the Internal
clock for the A/D. It could also be that his circuit that drives the
A/D pin on the PIC has too high of an output impedance.
The PIC data sheet specifies the upper limit on the impedance.
For some PICs, it can be as high as 10K. For the more modern
PICs, it is often only 2.5K maximum. You have to read the data sheet.
I'm using a 10 MHz oscillator to drive the pic. Would this be a more advisable clock to use for
Joined: 11 Feb 2007
Posts: 8 the ADC? If so, could you give me a code snippet of how to implement such a feature?
Location: Cedar Rapids
The 'second' point I was making in my original post, related to sample intervals. The
'set_pwm_duty' code, when dealing with an 'int' value, is very fast. It only has to write one byte
to the PWM register. Now on the PIC, the actual interval, does not update till the end of the PWM
period. So the interval, may well be changed about 40 times, before the physical update occurs.
The ADC, requires the input capacitor to recharge between readings, and as posted, this is not
allowed to happen, which will make the behaviour noisier. I'd suggest trying this:
Code:
#bit CCPIF=0XC.2
void main() {
char selection;
byte value;
selection = '2';
3 от 6 26.2.2007 г. 09:43
CCS :: View topic - Stability issues with ADC? http://ccsinfo.com/forum/viewtopic.php?t=29875&highlight=rea...
switch(selection) {
case '1' : setup_timer_2(T2_DIV_BY_1, 127, 1);
break;
case '2' : setup_timer_2(T2_DIV_BY_4, 127, 1);
break;
case '3' : setup_timer_2(T2_DIV_BY_16, 127, 1);
break;
}
setup_port_a(ALL_ANALOG);
setup_adc(adc_clock_div_32);
set_adc_channel( 0 );
CCPIF=0;
while( TRUE ) {
//Wait for the output pulse to update
while (CCPIF==0) ;
value=read_adc();
CCPIF=0;
}
This makes two tiny changes to the original code. The first is to change the ADC clock source,
and the second, is to synchronise the read to the PWM.
I'll be interested to hear if this is better.
Best Wishes
I can tell you how to find the information. That's a better way.
Joined: 06 Sep 2003
Posts: 6756
Download the 16F877 data sheet:
http://ww1.microchip.com/downloads/en/DeviceDoc/30292c.pdf
You'll see a chart that show the Maximum Device Frequency on the
right side, and on the left side it shows the divisor. Find the lowest
frequency in the table that is greater than or equal to your PIC's
frequency. Then go over to the left column and find the divisor value.
Then look in the 16F877.H file, in the A/D section, and find the CCS
constant for that clock frequency. Example:
Let's say your crystal frequency is 4 MHz. Look in the table on the
right side. The lowest frequency that is greater than or equal to 4 MHz
is 5 MHz. Then go over to the left and you see the divisor is 8Tosc.
Then look in 16F877.H, and you see the CCS constant for this divisor is:
ADC_CLOCK_DIV_8
4 от 6 26.2.2007 г. 09:43
CCS :: View topic - Stability issues with ADC? http://ccsinfo.com/forum/viewtopic.php?t=29875&highlight=rea...
--------------------
Regarding 18F PICs with a PLL:
Note that the table corresponds to the PIC's operating frequency.
If your PIC has a 10 MHz crystal running in 4x PLL, the PIC will be
running at 40 MHz. PICs that have a PLL will have additional entries
in the table to show you the divisor for use at 40 MHz.
Why does not CCS categorize the forum into section.. like ADC/PWM/I2C etc ???
Joined: 13 Jan 2007
Posts: 30
All this information bundled in one big forum head is so messy...
The problem with 'categorising', is that few problems would then be in the right place. If you
look at posted questions, you will find that it is rare for the final solution, to match what the
poster 'thought' the problem was, and most quations relate to multiple things (this thread for
example, relates to the ADC, the PWM, and also clocking, and timing issues). You can categorise
for yourself, to a large extent with the search function. Also, remember that CCS, really have
almost nothing to 'do' with this forum. It is a _user_ forum, with CCS providing the space, and
one CCS person (Daren Rook), acting to administer it, but with only a very small amount of time
involved. At the end of the day, it'd be 'nice' to have posters make sure that the thread title, has
some good relationship to the question involved, since this would make searching a lot easier,
but beyond this, it would require a significant input of time from somewhere...
Best Wishes
I'm still not sure what was causing the instability, but now I have it working. Rather than using
Joined: 11 Feb 2007
Posts: 8 a variable dc power supply for the input voltage, I am now using a 5KOhm potentiometer. There
Location: Cedar Rapids is no longer any instability with my PWM. Thanks.
My 'suggestion' would be that it'd be worth looking with a scope at what the output voltage of
the 'variable DC supply', was actually 'doing', into the low load represented by the ADC. You may
well find there is a minimum load required for it to become stable.
Best Wishes
Okay, here's a new problem. I've been informed that I need to output a 500KHz PWM signal,
Joined: 11 Feb 2007
Posts: 8 instead of a 20KHz signal. I manipulated the code a little bit and was able to get an output of
Location: Cedar Rapids 500KHz, but now the output is unstable again and very sensitive to the analog input. In other
words, if I input as little as .5V, the duty cycle is now 100% (where as for the 20KHz, 5V would
max out at 50%). I also tried introducing a 500uS delay into the loop, with little added benefit.
Here's the code:
Code:
5 от 6 26.2.2007 г. 09:43
CCS :: View topic - Stability issues with ADC? http://ccsinfo.com/forum/viewtopic.php?t=29875&highlight=rea...
#if defined(__PCM__)
#include <16F877.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=10000000)
//#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, BRGH1OK)
#elif defined(__PCH__)
#include <18F452.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=10000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, BRGH1OK)
#endif
void main() {
INT16 value;
setup_port_a(ALL_ANALOG);
setup_adc(adc_clock_internal);
set_adc_channel( 0 );
while( TRUE ) {
value=read_adc();
6 от 6 26.2.2007 г. 09:43