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

int32 comparison

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Guest








int32 comparison
PostPosted: Tue Mar 13, 2007 1:31 pm     Reply with quote

Quick question. I want to compare to int32's, but I have to scale one of the ADC readings a second time in order to compare apples and apples. How can I make it so the int32 current will end up as an int32 rather than a float or whatever it will be cast as in my line of code?

Code:
int32 compare_with_user(int32 duty_cycle)  {

   int16 current;
   int16 user;
   int32 scale = 100;
   int32 compare;

   current=(read_adc()*scale)/1024;     //note, adc_channel should already be set to 0 from check_current method!
   
   current = 3.125*(current - 50);  //this is the line I'm sure will bring me problems...

   set_adc_channel( 1 );         
   //delay_us( 10 );               //10uS delay is necessary for proper ADC reading.
   user=(read_adc()*scale)/1024;

   if (compare > 0) {
      if (duty_cycle < 100) {
         duty_cycle = duty_cycle + 1;
      }
   }
   if (compare < 0) {
      if (duty cycle > 0) {
         duty_cycle = duty_cycle - 1;
      }
   }   

   set_pwm1_duty(duty_cycle);
   /*   This sets the time the pulse is high each cycle.
      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 12uS
      A value too high or too low will prevent the output from changing.
   */
   
   return duty_cycle;

}
Ttelmah
Guest







PostPosted: Tue Mar 13, 2007 1:52 pm     Reply with quote

The line, won't cause a problem.
What will happen, is that 'current-50' will be evaluated using int16 maths, then this will be converted to a float, and multiplied by 3.125. The floating point result, will then be converted back to an int16, and stored in 'current'.

Best Wishes
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Tue Mar 13, 2007 1:53 pm     Reply with quote

Any time you have doubts about what the output will be, just make
a little test program. I do this all the time. In your case, you have
doubts about what number will be placed into 'current' when your
scaling equation is evaluated. Look at the following program.
It evaluates the equation and displays the results. If you use
MPLAB, as I do, then you can run it in the simulator and display
the output from printf() in the Output window. There's a feature
in the MPLAB simulator called "Uart1", which takes output sent the
hardware UART and displays it in the Output window. You don't
even have to touch hardware to test your program.
Code:

#include <16F877.H>
#fuses XT, NOWDT, BROWNOUT, PUT, NOLVP
#use delay(clock=4000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)

//=======================================
void main()
{
int16 current;

current = 150;

current = 3.125 * (current - 50); 

printf("current = %lu", current);

while(1);
}


You have a few other worrisome problems in your program.

1. You're using the 'compare' variable, but it's never initialized.

2. You have a comment in there that the A/D channel is set
in some other routine. This is very unsafe programming practice.
What if you cut out or modify that other routine at some future date ?
Then your A/D setup for this routine is trashed. You should put
the code to select the channel in that routine.

3. You have commented out the setup delay for the A/D (10 usec).
That delay is necessary. Also, look at the data sheet and verify
that the minimum delay is actually 10 us. The data sheet will have
a section where they crank through a series of calculations and come
up with a typical minimum delay. Look at that section.

4. As Ttelmah says, what if the A/D reads a value less than 50 ?
Guest








PostPosted: Tue Mar 13, 2007 2:25 pm     Reply with quote

I believe this clears up the problems

Code:
int16 compare_with_user(int16 duty_cycle)  {

   int16 current;
   int16 user;
   int32 scale = 100;

   set_adc_channel( 0 );
   delay_us( 10 );
   current=(read_adc()*scale)/1024;     
   
   if (current < 50) {
      current = 0;
   }
   else {
      current = 3.125*(current - 50);      //this should be cast as an int16 when all is said and done
   }

   set_adc_channel( 1 );         
   delay_us( 10 );
   user=(read_adc()*scale)/1024;

   if (user > current) {
      if (duty_cycle < 100) {
         duty_cycle = duty_cycle + 1;
      }
   }
   if (user < current) {
      if (duty_cycle > 0) {
         duty_cycle = duty_cycle - 1;
      }
   }   

   set_pwm1_duty(duty_cycle);
   /*   This sets the time the pulse is high each cycle.
      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 12uS
      A value too high or too low will prevent the output from changing.
   */
   
   return duty_cycle;

}
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
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