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 support@ccsinfo.com

Please help with ADC calculations

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







Please help with ADC calculations
PostPosted: Tue Feb 12, 2008 7:11 am     Reply with quote

Guys, i have problems with this C code:

#include "16f877A.h"
#device adc=10
#use delay (clock=20000000)
#fuses HS, NOWDT, PUT, NOLVP, NOBROWNOUT

void main()
{
// Definição das Variáveis:

signed long int Vout;
signed long int Vref = 700;
signed long int erro0 = 0;
signed long int erro1 = 0;
signed long int erro2 = 0;
signed long int U1 = 0;
signed long int U2 = 0;
signed long int D2 = 100;

setup_ADC_ports (RA0_ANALOG);
setup_adc (ADC_CLOCK_DIV_32);
set_adc_channel (0);

setup_timer_2 (T2_DIV_BY_4,124,1); //(1/4000000)*4*4*125 = 100 us.
setup_ccp1 (ccp_pwm);
set_pwm1_duty (0);
setup_ccp2 (ccp_pwm);
set_pwm2_duty (D2);

while (true)
{
Vout = read_adc();
erro0 = Vref - Vout;
D2 = (16*U1 - 6*U2)/10;
D2 = D2 + ((23*erro0 + 8*erro1 - 15*erro2)/1000);
if (D2 < 80) D2 = 80;
if (D2 > 350) D2 = 350;
set_pwm2_duty (D2);
erro2 = erro1;
erro1 = erro0;
U2 = U1;
U1 = D2;
}
}

Well, when I run this program in Proteus, for example, it works fine. Although, when I make it for real, it doesn't work properly.
The problem is that the D2 variable isn't being updated. The channel 2 PWM is fixed and do not make any changes.
I'm certain that the AD read is ok, cause i've already tested.
So, if you guys have some idea that could help me, i'd thank you so much.

Thanks in advance...
rnielsen



Joined: 23 Sep 2003
Posts: 852
Location: Utah

View user's profile Send private message

PostPosted: Tue Feb 12, 2008 9:39 am     Reply with quote

Your calculations might not be getting done in the proper sequence. Each operator has it's own precedence. You might need to add parenthasis around each section so the precedence is correct.

Quote:
D2 = (16*U1 - 6*U2)/10;
D2 = D2 + ((23*erro0 + 8*erro1 - 15*erro2)/1000);


This might need to be:

Code:
D2 = (((16 * U1) - (6 * U2))) / 10;
D2 = D2 + (((23 * erro0) + ((8 * erro1) - (15 * erro2))) / 1000);


I don't know if you need it that extensive but you can get the picture. This way you will get exactly what you want, not assuming anything for the compiler.

Ronald
kolio



Joined: 06 Feb 2008
Posts: 26

View user's profile Send private message

PostPosted: Wed Feb 13, 2008 2:55 pm     Reply with quote

1.Check for an overflow with * and /.
2.With long variables better use "long" constants, for example instead of 1000 or 15, use 1000L or 15L. Sometimes you'll be surprised what compilers would do with this.
3.Check again typecasting - signed to unsigned.
4.What will happen with PWM ratio if D2 is "subzero"?

Good luck!
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