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:
#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;
}
#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;
}