Đệ tử 5 túi
Tham gia ngày: Sep 2007
Bài gửi: 94
:
|
Trích:
Nguyên văn bởi cuongthinh

Em đang làm mạch này mà lập trình mãi nó vẫn không chạy cho. Một tuần nữa em phải bảo vệ tốt nghiệp về cái này rồi mà kô tìm ra lỗi ở đâu! Mong các cao thủ giúp em với?
Chân PWM ra của em đã có xung ra nhưng kô đúng theo ý muốn em cũng kô hiểu tại sao nữa, hic
Chương trình của em đây:
Code:
#include <p30f4011.h>
#include <dsp.h>
#include <math.h>
_FOSC(CSW_FSCM_OFF & FRC_PLL16);
_FWDT(WDT_OFF);
_FBORPOR(PBOR_OFF & MCLR_EN);
_FGS(CODE_PROT_OFF);
//------------------------------------------------------------------------------
//Cac hang so cua chuong trinh (gia tri tuc thoi dung trong chuong trinh)
#define Fcy 32000000 //Tan so thuc thi lenh
#define Fpwm 40000 //Tan so PWM = 40 kHz
#define vOutmax Q15(0.9)
#define vOutmin Q15(0.1)
#define iOutmax Q15(0.9)
#define iOutmin Q15(0.1)
//Cac prototype cho cac chuong trinh con
void Init_PORTS(void);
void Init_MCPWM(void);
void Init_ADC10(void);
void CalciPI( fractional iInRef, fractional iInMeas);
void CalcvPI( fractional vInRef, fractional vInMeas);
void InitiPI(void);
void InitvPI(void);
//Cac bien toan cuc
fractional Vo,Vac,Iac,Vcom,vPI,Iref,Vavg;
fractional iSum, iExc, iErr;
fractional vSum, vExc, vErr;
fractional iU, iOut, vU, vOut;
int n,m,k;
unsigned int duty;
//------------------------------------------------------------------------------
//Chuong trinh chinh
int main(void) {
void InitvPI();
void InitvPI();
Init_PORTS(); //Khoi tao cac cong I/O
Init_MCPWM(); //Khoi tao module PWM
Init_ADC10();
while(1) Nop();
}
//Chuong trinh con khoi tao cac cong I/O, de xuat cac tin hieu PWM, va doc tin
//hieu dieu chinh cua bien tro tai AN0
void Init_PORTS(void) {
LATE = 0; //Xoa thanh ghi chot cac tin hieu PWM
TRISE = 0; //Tin hieu PWM nam tai RE0
TRISB = 0x0007; //RB0 den RB2 la ngo vao, cac chan RB khac la ngo ra
}
//Chuong trinh con khoi tao module chuyen doi A/D
// AN0 phan hoi Vac, AN1 phan hoi Iac, AN2 phan hoi Vo
void Init_ADC10(void) {
ADPCFG = 0b1111111111111000; // RB0,RB1,RB2 = analog input
ADCON1 = 0b0000001001101100; // SIMSAM bit = 1 implies ...
// simultaneous sampling
// ASAM = 1 for auto sample after convert
// SSRC = 011 for PWM trigger
// integer output
ADCSSL=0x0007; // Lan luot quét ANO, AN1, AN2 kéet qua lan luot luu vao ADCBUF0->2
ADCON3 = 0x0302; // Auto Sampling 3 Tad, Tad = internal 2 Tcy
ADCON2 = 0b0000010000001000; // CHPS= 00 Convert CHO
// SMPI = 0010 for interrupt after 3 converts
// CSCNA=1 scan input
ADCHS=0;
_ADIF = 0; //Xoa co ngat ADC
_ADIE = 1; //Cho phep ngat ADC
_ASAM = 1; //Khoi dong che do tu dong lay mau
ADCON1bits.ADON = 1; // turn ADC ON
}
//Chuong trinh con khoi tao module PWM
void Init_MCPWM(void) {
PTPER = Fcy/Fpwm-1; //Dat thanh ghi chu ky voi tan so PWM = 40 kHz
SEVTCMP = PTPER;
PWMCON1 = 0x070F; //Chi dung cac chan PxL, mot cach doc lap
OVDCON = 0xFF00; //Khong dung overdrive
PDC1 = 200; //Khoi tao PWM1, 2, va 3 la 25%
PWMCON2 = 0x0F00; //Postscale = 1:10
PTCON = 0x8000; //Kich hoat module PWM
}
void CalciPI( fractional iInRef, fractional iInMeas)
{ iErr = iInRef - iInMeas;
iU = iSum + Q15(8.174) * iErr; //kpz = 8.174 = 0.00025 fraction
if( iU > iOutmax ) iOut = iOutmax;
else {
if( iU < iOutmin ) iOut = iOutmin;
else iOut = iU ;
}
iSum = iSum + Q15(4.266)*iErr; //kiz = 4.266 = 0.00013 fraction
}
void CalcvPI( fractional vInRef, fractional vInMeas)
{ vErr = vInRef - vInMeas;
vU = vSum + Q15(49.36) * vErr; //kpz = 49.36 = 0.0015 fraction
if( vU > vOutmax ) vOut = vOutmax;
else {
if( vU < vOutmin ) vOut = vOutmin;
else vOut = vU ;
}
vSum = vSum + Q15(48.0)*vErr; //kiz = 48 = 0.001465 fraction
}
void InitvPI(void)
{
vSum = 0;
vOut = 0;
}
void InitiPI(void)
{
iSum = 0;
iOut = 0;
n = 0;
k = 0;
}
//Trinh phuc vu ngat cho ADC
void __attribute__((__interrupt__ , auto_psv)) _ADCInterrupt(void)
{
Vac = ADCBUF0; //4kHz
Vavg = Vavg + Vac;
if (k=40) { Vcom = Q15(1)/(Vavg*Vavg); k = 0; }
else (k++);
if (n=40) Vo = ADCBUF2; // tao bien dem de duoc Vac voi tan so 100Hz (ADC trich mau voi tan so 4kHz)
else (n++) ;
CalcvPI(Q15(1),Vo); // V_refer = 1V , Tinh toan khau PI ap
vPI = vOut; // Tin hieu ra khau PI ap
Iref = vPI*Vcom*Vac*Q15(2.4); //Voi km=2.4
Iac = ADCBUF1; // Iac voi tan so 4kHz (ADC trich mau voi tan so 4kHz)
CalciPI(Iref,Iac); // Tinh toan Pi dong
// dai luon tham chieu la Iref
// Tin hieu phan hoi la Iac
PDC1 = (unsigned int)((iOut*32768)*2*PTPER); ;// Update thanh ghi chu ki nhiem vu
_ADIF = 0;
}
|
Phần cứng của PFC cũng rất quan trọng, phần cúng phải đúng thì bạn mới nói tới chuyện phần mềm,bạn post mạch nên xem nào
Về phần code của bạn, bạn nên đọc lại phần ADC , bạn chọn AN0-AN2 như vậy là không đúng, để thực hiện việc quét kênh bạn phải chọn các kênh CH0,CH1,CH2,CH3, như vậy bạn đã chưa chọn các kênh cho tín hiệu, tôi khuyên bạn nên xem application note về PFC sau: http://www.microchip.com/stellent/id...pnote=en531747
Nó thực sự có ích với bạn đó, từ cách tính hàm PI, không phải ngẫu nhiên mà họ lại viết bằng ASM, họ viết như vậy để tiết kiệm thời gian tính toán lại , code ASM không có gì khó hiẻu cả,trong hàm PFC.s và hàm PI.s hầu như bạn không phải thay đổi gì cả, bạn nên đọc phần nhúng ASM va C như thế nào là được, cốt nhất là bạn phải hiểu bản chất của vấn đề. Tôi đã làm PFC này rồi và lấy nguyên 2 file PFC.s và PI.s và chỉnh sửa lại code một chút cho đúng phần cứng kết quả chạy khá ổn.
|