PDA

View Full Version : PID Giao tiếp PIC 16F877A


nguyen_de89
09-05-2013, 09:50 AM
Mình đang viết về PID giao tiếp PIC 16F877A k biết chương trình thiếu sót chỗ nào mong mọi người cho ý kiến tham khảo
#include <16f877a.h>
#fuses hs,nolvp,nowdt,noprotect,put
#use delay(clock=12000000)
#include <string.h>
#use fast_io(c)
#use fast_io(d)
#use fast_io(e)

#byte portc=0x7
#byte portd=0x8
#byte porte=0x9

#byte timer0=0x1 // thanh ghi TIMER0
#byte option_reg=0x81 // thanh ghi Option_Reg
#byte PIR1=0x0c

#bit l10=porte.0
#bit l11=porte.1
#bit l12=porte.2

#bit TMR1IF=PIR1.0 // bit co bao tran TIMER1 :TMR1I
double T,Kp,Ki,Kd,ek,ek1,ek2,uk,uk1,a0,a1,a2;
int duty,tram,chuc,donvi,dem;

unsigned int16 speed,thuc;

#INT_TIMER0
void ngat_RTCC()
{
thuc=get_timer1();
dem++;
if(dem>=100)
{
speed=get_timer1();
dem=0;
set_timer1(0);
}
set_timer0(139);
}

/*void ngat_RTCC()
{
//thuc = timer0;
speed = timer0*10;
timer0=0;
set_timer1(15535);
TMR1IF =0;
}*/
void tinhtoan();
void hienthi();
void xuat_pwm();
void main()
{
unsigned int dat=50;
uk=0,uk1=0,ek=0,ek1=0,ek2=0,a0=0,a1=0,a2=0;
enable_interrupts(INT_TIMER0); //CHO PHEP NGAT TIMER0
enable_interrupts(GLOBAL); //CHO PHEP NGAT TOAN CUC-GLOBAL
//ext_int_edge(L_to_H); //CANH NGAT L_TO_H
set_tris_c(0b10000001);
set_tris_d(0b0);
set_tris_e(0);
portd=0;portc=0;porte=0;
tram=0;chuc=0;donvi=0;speed=0;
//CAU HINH CHO TIMER-1 VA TIMER-0,BAT DAU CHO TIMER HOAT DONG//
/*setup_timer_1(T1_INTERNAL|T1_DIV_BY_2); //Cai dat gia tri-cau hinh cho TIMER 1-chia tan 1:2,timer1=15535
set_timer1(15535); // ==> ngat sau 100mS.
timer0=0; // Cai dat gia tri-cau hinh cho TIMER 0
p0=0;p1=1;p2=0; // Gia tri chia tan ,mac dinh 1:1
p3=0; // Khong chia tan
p4=1; // Chon canh tac dong L_TO_H
p5=1;*/ // Cho TIMER0 bat dau hoat dong o che do Counter
setup_timer_0(RTCC_8_BIT|RTCC_INTERNAL|RTCC_DIV_25 6);
set_timer0(139);
// (256-138)*256*(4/12)=10069us = 10.069ms ~10ms //
setup_timer_1(T1_EXTERNAL);//TIMER1 O CHE DO COUNTER
set_timer1(0);
ek=dat-thuc;
while(1)
{
tinhtoan();
hienthi();
Kp=0.058;//Chi su dung khau Kp=0.05,khong dung Ki va Kd.
Ki=0.00004;
Kd=0.1;
T=0.1;

a0=Kp+(Ki*T)/2+Kd/T;
a1=-Kp+(Ki*T)/2-(2*Kd)/T;
a2=Kd/T;
uk=uk1+a0*ek+a1*ek1+a2*ek2;
//uk=uk1+(Kp+Ki*T/2+Kd/T)*ek;
//uk=uk-(Kp-Ki*T/2+2*Kd/T)*ek1;
//uk=uk+(Kd/T)*ek2;
//uk= dat + ek + 25;
if (uk>255)
{
uk=255;
}
else if (uk<0)
{
uk=0;
}
uk1=uk;
ek2=ek1;
ek1=ek;
duty=uk;
xuat_pwm();
//uk=0;
}
}
void tinhtoan()
{
tram=speed/100;
chuc=(speed%100)/10;
donvi=speed%10;
}
void hienthi()
{
int ht[10]={192,249,164,176,153,146,130,248,128,144};
l10=1;l11=0;l12=0;
portd=ht[tram];
l10=0;l11=0;l12=0;
delay_ms(15);
l10=0;l11=1;l12=0;
portd=ht[chuc];
l10=0;l11=0;l12=0;
delay_ms(15);
l10=0;l11=0;l12=1;
portd=ht[donvi];
l10=0;l11=0;l12=0;
delay_ms(15);
}
void xuat_pwm()
{
setup_ccp2(ccp_pwm);
set_pwm2_duty(duty);
setup_timer_2(t2_div_by_16,255,1);
}