|
|
View previous topic :: View next topic |
Author |
Message |
guhenn Guest
|
Please help with ADC calculations |
Posted: Tue Feb 12, 2008 7:11 am |
|
|
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
|
|
Posted: Tue Feb 12, 2008 9:39 am |
|
|
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
|
|
Posted: Wed Feb 13, 2008 2:55 pm |
|
|
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! |
|
|
|
|
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
|