CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

Stability issues with ADC?
Goto page Previous  1, 2
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Neutone



Joined: 08 Sep 2003
Posts: 839
Location: Houston

View user's profile Send private message

PostPosted: Thu Feb 22, 2007 12:11 pm     Reply with quote

sonicfire wrote:
Okay, here's a new problem. I've been informed that I need to output a 500KHz PWM signal, instead of a 20KHz signal. I manipulated the code a little bit and was able to get an output of 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:
#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_ccp1(CCP_PWM);   // Configure CCP1 as a PWM

  setup_timer_2(T2_DIV_BY_1, 4, 1);  //output at 500KHz

  setup_port_a(ALL_ANALOG);
  setup_adc(adc_clock_internal);
  set_adc_channel( 0 );

  while( TRUE ) {
    value=read_adc();

    set_pwm1_duty(value);          // This sets the time the pulse is
                                   // high each cycle.  We use the A/D
                                   // input to make a easy demo.
                                   // the high time will be:
                                   //  if value is LONG INT:
                                   //    value*(1/clock)*t2div
                                   //  if value is INT:
                                   //    value*4*(1/clock)*t2div
                                   // for example a value of 30 and t2div
                                   // of 1 the high time is 12us
                                   // WARNING:  A value too high or low will
                                   //           prevent the output from
                                   //           changing.
  }

}


This is a scaling issue. you need to scale the value you read from the ADC before you load it into the PWM. Your ADC is configured to return a value ranging from 0 to 1023 representing 0 to 100%. The PWM is configured to accept a value ranging from 0 to 19 representing 0 to 100%.

The scaling factor is 20/1024 or 0.01953125

To scale without using floating point math:
change
value=read_adc();
to
value=(read_adc()*20)/1024;
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu Feb 22, 2007 12:50 pm     Reply with quote

His A/D is not configured for 10-bit mode. The compiler defaults to
8-bit mode.

Here's the code from the .LST file for the posted program
The A/D is configured for left-justified output. Then, only
the MSB of the result is read, from the ADRESH register.
This discards the lower two bits. The posted program
puts this 8-bit result into the LSB of a 16-bit variable.
The code below clears the MSB of the variable.
Code:
......     value=read_adc(); 
002F:  BSF    ADCON0.2
0030:  BTFSC  ADCON0.2
0031:  GOTO   030
0032:  MOVF   ADRESH,W
0033:  CLRF   value+1
0034:  MOVWF  value
sonicfire



Joined: 11 Feb 2007
Posts: 19
Location: Cedar Rapids

View user's profile Send private message

PostPosted: Thu Feb 22, 2007 1:05 pm     Reply with quote

I now understand why the PWM only accepts values from 0 to 19, but I'm not sure why the A/D converter returns a number 0 to 1023. I tried implementing the change with no success. The scope output is unintelligible. I can manually set the A/D value from 0 to 20 and get satisfactory results, but I can't seem to read an input voltage (0 to 5V from a 5K pot) with the same success.

If my A/D converter is defaulting to 8bit read, how can I change it to read 10bits in my C code?
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu Feb 22, 2007 1:32 pm     Reply with quote

Quote:
how can I change it to read 10bits in my C code?


Code:

#include <16F877.H>
#device adc=10   // Add this line in this exact location.
sonicfire



Joined: 11 Feb 2007
Posts: 19
Location: Cedar Rapids

View user's profile Send private message

PostPosted: Thu Feb 22, 2007 1:33 pm     Reply with quote

thanks
sonicfire



Joined: 11 Feb 2007
Posts: 19
Location: Cedar Rapids

View user's profile Send private message

PostPosted: Thu Feb 22, 2007 1:40 pm     Reply with quote

You guys were both dead on! I now understand the scaling factor and that works quite well. The 10bit adc seems to have fixed a lot of problems as well. Thank you.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page Previous  1, 2
Page 2 of 2

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group