PIC Vietnam

PIC Vietnam (http://www.picvietnam.com/forum/index.php)
-   dsPIC - Bộ điều khiển tín hiệu số 16-bit (http://www.picvietnam.com/forum/forumdisplay.php?f=29)
-   -   Sửa lỗi (http://www.picvietnam.com/forum/showthread.php?t=2891)

namqn 19-10-2008 08:06 PM

Xác nhận với bạn rằng PICkit 2 v2.55 vẫn đưa ra cảnh báo trên ngay cả khi tất cả các field của tất cả các từ cấu hình đã được mô tả tường minh giá trị trong code.

Về code LCD của bạn, bạn để ý trong chương trình con khởi tạo LCD của tôi, sau mỗi bước đặt cấu hình tôi đều có delay 1 ms (sau khi xóa màn hình thì phải chờ khoảng 5 ms), code của bạn đang xuất ào ào các giá trị cấu hình ra LCD. Bạn thử chỉnh lại phần này xem, nếu vẫn không thành công, có lẽ bạn phải thực hiện quá trình khởi động mềm cho LCD, tham khảo quy trình ở post #269, link dưới đây:
http://www.picvietnam.com/forum/showthread.php?t=357

Xung Enable của bạn có thể không đủ rộng (vì bạn bật xong thì tắt nó ngay). Code ví dụ của tôi có 1 vòng for nhỏ dùng để tạo độ rộng tối thiểu 1 us cho xung Enable.

Thân,

tungnh 23-10-2008 12:32 AM

1 Attachment(s)
Cám ơn anh Nam nhé, em đã làm đúng như anh bảo nhưng LCD vẫn không chịu hiển thị, em kiểm tra phần cứng không có vấn đề gì, em thử test chương trình cũ của một anh ( tên là H ) ra đi không một lời chăn chối thì LCD vẫn chạy. Thôi em đành bỏ cái mạch đó đi làm lại mạch mới, nhưng em vẫn ấm ức lắm, rồi có ngày em sẽ tìm được nguyên nhân.
Thưa anh em nhận được nhiệm vụ mới đó là thực hiện điều khiển số PFC để ổn định áp ra......
Em đã viết code mong em xem giúp em :
Code:

////////////////////////// tham khao tutorial 06.01 cua anh  Nguyen Quang Nam  //////////////////
#include        <p30f4011.h>
#include        <dsp.h>
        _FOSC(CSW_FSCM_OFF & FRC_PLL4);
        _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        PWM_PORT        PORTE                //Cac tin hieu PWM nam o cong E
#define        PWM_TRIS        TRISE                //Thanh ghi 3 trang thai cho cac tin hieu PWM
#define        PWM_LAT                LATE                //Thanh ghi chot cac tin hieu PWM
#define        Fcy        8000000                                //Tan so thuc thi lenh
#define        Fpwm        40000                        //Tan so PWM = 40 kHz       

//Cac prototype cho cac chuong trinh con
void Init_PORTS(void);
void Init_MCPWM(void);
void Init_ADC10(void);
void PID_Cal(float kp,float ki,float kd,fractional refer,fractional measu);
fractional ADC_Vo,ADC_Vi,ADC_I,Vc,Vx;
tPID fooPID;
fractional abcCoefficient[3] __attribute__ ((section (".xbss, bss, xmemory")));
fractional controlHistory[3] __attribute__ ((section (".ybss, bss, ymemory")));
fractional kCoeffs[] = {0,0,0};
int main (void)
{
        Init_PORTS();                        //Khoi tao cac cong I/O
        Init_MCPWM();                        //Khoi tao module PWM
        Init_ADC10();                        //Khoi tao module ADC
        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) {
        PWM_LAT = 0;                        //Xoa thanh ghi chot cac tin hieu PWM
        PWM_TRIS = 0xFFC0;                //Cac tin hieu PWM nam tai RE0..RE5
        TRISB = 0x000B;                        //Chan RB0,1,3 la ngo vao , cac chan khac
                                                        //la ngo ra
}

//Chuong trinh con khoi tao module chuyen doi A/D, doc ngo vao AN0
void Init_ADC10(void) {
  // ADCON2bits.CHPS = 3;    // Convert CH0, CH1, CH2 and CH3
    ADCON1bits.FORM = 3;    //Dinh dang du lieu ra Q15
        ADPCFG = 0xFFF8;                //Cac chan khac la digital, chan RB0,1,2 la analog
        ADCON1 = 0x0060;                //Module PWM cham dut lay mau va kich hoat
                                                        //viec chuyen doi A/D
//        ADCON1 = 0x0040;                //Timer 3 cham dut lay mau va kich hoat
                                                        //viec chuyen doi A/D
        ADCON2 = 0;
        ADCHS = 0x0008;                        //Kenh 0 doc tin hieu giua AN0,AN1,AN2 va AVss
        ADCSSL = 0;                                //Khong quet cac ngo vao
        ADCON3 = 0x0103;                //Dung 1 TAD cho lay mau, dung clock he thong,
                                                        //TAD = 2xTcy = 250 ns
/*        TMR3 = 0;                                //Xoa thanh ghi dem cua Timer 3
        PR3 = 0x03E8;                        //Nguong delay cho TMR3 la khoang 1 ms
        T2CON = 0x8010;                        //Prescale = 1:8, bat cho TMR3 chay
*/
        _ADIF = 0;                                //Xoa co ngat ADC
        _ADIE = 1;                                //Cho phep ngat ADC
        _ADON = 1;                                //Bat module ADC
        _ASAM = 1;                                //Khoi dong che do tu dong lay mau
}

//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 = 0x0100;                       
        PWMCON2 = 0x0F00;                //Postscale = 1:16
        PTCON = 0x8000;                        //Kich hoat module PWM
}
void PID_Cal(float kp,float ki,float kd,fractional refer,fractional measu)
                        {
        fooPID.abcCoefficients = &abcCoefficient[0];    /*Set up pointer to derived coefficients */
        fooPID.controlHistory = &controlHistory[0];    /*Set up pointer to controller history samples */
        PIDInit(&fooPID);                              /*Clear the controler history and the controller output */
                kCoeffs[0] = Q15(kp);
                kCoeffs[1] = Q15(ki);
                kCoeffs[2] = Q15(kd);
        //        kCoeffs[0] = Q15(0.7);
        //        kCoeffs[1] = Q15(0.2);
        //        kCoeffs[2] = Q15(0.07);
        PIDCoeffCalc(&kCoeffs[0], &fooPID);            /*Derive the a,b, & c coefficients from the Kp, Ki & Kd */
        //fooPID.controlReference = Q15(0.74) ;
                fooPID.controlReference = refer;       
                  fooPID.measuredOutput = measu ;       
                PID(&fooPID);                                                 
                        }
//Trinh phuc vu ngat cho ADC
void _ISR _ADCInterrupt(void)
{
        ADC_Vo = ADCBUF0 >> 1 ;               
        PID_Cal(27,0.04211,0,0x1999,ADC_Vo); // V_refer = 1V
        Vc = fooPID.controlOutput;
        ADC_Vi = ADCBUF1 >> 1;
        Vx = Vc*ADC_Vi;                                        // tran !!!!!...........
        ADC_I = ADCBUF2 >> 1;
        PID_Cal(1.777,0.1479,0,Vx,ADC_I);
        PDC1 = fooPID.controlOutput;
        _ADIF = 0;
}

Nguyên lý như trong hình anh ạ. Và thuật toán của em như sau:
3 Biến đổi AD đưa vào 3 chân AN0,1,2. ( ở phần khai báo không biết có đúng không )
Phần tính toán PI của áp và dòng em thực hiện trong vong ngắt của ADC:
Bằng suy nghĩ của một nông dân, em cứ thực hiện từng bước tính toán như sơ đồ của nó.
Em đình dạng dữ liều ra kiểu fractional (Q15) cho ADC, thưa anh có phải khi biến đổi ADC ở 3 đầu vào thì kết quả của từng việc biến đổi sẽ lưu lần lượt ở ADCBUF0,1,2 không hả anh ?
và khi em thực hiện phép nhân Vx = Vc*ADC_Vi; liệu rằng nhân 2 số kiểu fractional nó có tràn không anh và cách xử lý ra sao ?
Liệu răng chương trình này có điều khiển được không anh nhỉ, Em tham khảo nhiều tài liệu , thấy họ viết code rất phức tạp, dùng ngắt timer, ngắt PWM, ADC, .....

namqn 23-10-2008 01:11 AM

Có lẽ bạn nên đọc thêm về module ADC của dsPIC. Khi đã hiểu rõ hơn cách hoạt động của module này, bạn có thể bắt đầu với code đơn giản để đọc 3 tín hiệu analog, rồi mới tiếp tục những công việc xử lý khác.

Nói chung, không nên thực hiện những tính toán phức tạp, hay gọi hàm tính toán phức tạp trong chương trình xử lý ngắt (với cách thiết lập trong ví dụ của tôi, bạn sẽ có khoảng 40000/16 = 2500 ngắt ADC mỗi giây).

Nhân hai số fractional trong dsPIC sẽ không tràn, điều này được đảm bảo.

Trong sơ đồ bạn đã post lên, không có phần D trong PID.

Như bạn đã viết, người ta dùng chương trình khá phức tạp để thực hiện bài toán mà bạn đang nghiên cứu. Do vậy, bạn cứ từ từ tìm hiểu, và tiến dần từ những chương trình rất đơn giản, và cơ bản.

Chúc bạn thành công.

Thân,


Múi giờ GMT. Hiện tại là 09:49 PM.

Tên diễn đàn: vBulletin Version 3.8.11
Được sáng lập bởi Đoàn Hiệp.
Copyright © PIC Vietnam