following is my code for lookup table for PID for DC/DC converter.
I used debugger to check each step for I couldn't get the good result. I found even I set Vout=0XFF, Vref=0XCC, error=vref-vout,
when the code run to
if (error>11){error=11;} , sometime error=11, sometime error is negative. why did this happen? how to solve it? thanks a lot
#include <18F458.h>
#device ADC=8
#use delay(clock=40000000)
#fuses HS,NOWDT,NOLVP
#use fixed_io(c_outputs=PIN_C2)
#BYTE ADCON0=0XFC2
///digital PID table a=kp*error,b=kb*error,c=kc*error
signed int16 a[22]={-130,-117,-104,-91,-78,-65,-52,-39,-26,-13,0,13,26,39,52,65,78,91,104,117,130,160};
signed int16 b[22]={-234,-211,-187,-164,-140,-117,-94,-70,-47,-23,0,23,47,70,94,117,140,164,187,211,234,250};
signed int16 c[22]={-108,-97,-86,-76,-65,-54,-43,-32,-22,-11,0,11,22,32,43,54,65,76,86,97,108,120};
signed int16 PWM_MAX=600;
signed int16 PWM_MIN=200;
signed int16 error=0; // real error read from ADC
signed int16 ei=0;// index for error[k] the table -10->0 2->12
signed int16 ei_1=10; // index for error[k-1],initial value error[k-1]=0, index is 10
signed int16 ei_2=10; // index for error[k-2],initial value error[k-2]=0, index is 10
signed int16 aa; //aa=a[index]
signed int16 bb;
signed int16 cc;
// signed int16 delta_u=0;
signed int16 tt=0;
signed int16 u=10;
signed int16 u_1=0;
signed int16 vout=0;
signed int16 vref=204; //204 in 8 bits for 4V, output at 12V
//interupt, once newduty start, start to read output voltage and calculate next duty
#int_TIMER2 fast
void TIMER2_irs(void)
{
vout=0;
read_adc(adc_start_only);
bb=b[ei_1];
cc=c[ei_2];
u_1=u;
vout=read_adc(adc_read_only);
error=vref-vout;//difference between ref and output
if (error>11){error=11;}
if (error<-10){error=-10;}
// tt=error+10;
ei=error+10;// get the index
// implement digital pid by reading table.
//delta_u=a[ei]-bb+cc;
aa=a[ei];
u=u_1+aa-bb+cc;
if( u>PWM_MAX)
{u=PWM_MAX;}
// if (u
set_pwm1_duty(u);
u_1=u;
ei_2=ei_1;
ei_1=ei;
}
void main()
{
setup_adc_ports(all_analog);
setup_adc(adc_clock_div_64);
setup_timer_2(T2_DIV_by_1,249,1);
setup_timer_3(T3_INTERNAL|T3_DIV_by_1);
setup_ccp1(CCP_PWM);
set_adc_channel(0);
ADCON0|=0X4;
enable_interrupts(INT_TIMER2);
enable_interrupts(global);
set_pwm1_duty(u);
while(1);
//{read_adc(adc_start_only);}
}
另外,我这里有好多篇关于数字控制电源的论文,大家有兴趣的话我可以贴上来,都是我这几个月收集的.