Lấy đặc tính h(t) của động cơ.
Chào các bạn. Tôi đã làm xong bài tập lớn môn lý thuyết điều khiển tự động là thiết kế bộ điều khiển PID trên nền PIC.Bây giờ tôi xin đưa các đoạn code của bài tập lớn của tôi.
Đầu tiên là công việc là lấy đặc tính đáp ứng h(t) của động cơ để từ đó tính toán các tham số Kp, Ki, Kd. Đây là bước tính toán thô các giá trị của bộ PID sau đó mình mới tinh chỉnh lại sau ở một chương trình khác.
Vi điều khiển ứng dụng: PIC6F877A
Ngôn ngữ lập trình: HTPIC
Trong bài này tôi mục đích làm như sau: khi ấn "P" trên giao diện trên PC hay nói cách khác truyền kí tự P xuống chip thì nó nhận lệnh và cho động cơ hoạt động. Tôi điều chế một xung 15KHZ, ở đây cho độ rộng 100% luôn. Và từ đó liên tục đọc 500 giá trị và truyền lên PC.
Thời gian trích mẫu của hệ thống là 10ms. Tôi truyền số xung đo được lên PC, từ số liệu này sẽ tính toán ra tốc độ thực và vẽ được hàm h(t) của đối tượng. Tôi dùng chương trình Terminal (do lười nên không viết chương trình trên PC riêng) và lấy dữ liệu và cho vào Matlab để nội suy ra hàm quá độ h(t) . Tôi định viết một chương trình bằng Matlab nhận giao tiếp RS232 tính toán và đưa ra đồ thị luôn. Nhưng phải chờ tí đã, dạo này ôn thi nên hơi lười làm.
Chương trình Terminal và giao tiếp RS232 các bạn có thể xem tại
http://www.picvietnam.com/forum/show...p?t=274&page=2
Code chương trình trên Matlab: dùng nội suy Cubic
Code cho PIC6F877A
Chương trình đã test và cho đặc tính h(t) thí dụ với động cơ 12V của tôi như sau:
Chúc các bạn thành công.
Chào các bạn. Tôi đã làm xong bài tập lớn môn lý thuyết điều khiển tự động là thiết kế bộ điều khiển PID trên nền PIC.Bây giờ tôi xin đưa các đoạn code của bài tập lớn của tôi.
Đầu tiên là công việc là lấy đặc tính đáp ứng h(t) của động cơ để từ đó tính toán các tham số Kp, Ki, Kd. Đây là bước tính toán thô các giá trị của bộ PID sau đó mình mới tinh chỉnh lại sau ở một chương trình khác.
Vi điều khiển ứng dụng: PIC6F877A
Ngôn ngữ lập trình: HTPIC
Trong bài này tôi mục đích làm như sau: khi ấn "P" trên giao diện trên PC hay nói cách khác truyền kí tự P xuống chip thì nó nhận lệnh và cho động cơ hoạt động. Tôi điều chế một xung 15KHZ, ở đây cho độ rộng 100% luôn. Và từ đó liên tục đọc 500 giá trị và truyền lên PC.
Thời gian trích mẫu của hệ thống là 10ms. Tôi truyền số xung đo được lên PC, từ số liệu này sẽ tính toán ra tốc độ thực và vẽ được hàm h(t) của đối tượng. Tôi dùng chương trình Terminal (do lười nên không viết chương trình trên PC riêng) và lấy dữ liệu và cho vào Matlab để nội suy ra hàm quá độ h(t) . Tôi định viết một chương trình bằng Matlab nhận giao tiếp RS232 tính toán và đưa ra đồ thị luôn. Nhưng phải chờ tí đã, dạo này ôn thi nên hơi lười làm.
Chương trình Terminal và giao tiếp RS232 các bạn có thể xem tại
http://www.picvietnam.com/forum/show...p?t=274&page=2
Code chương trình trên Matlab: dùng nội suy Cubic
Code:
hold off; x_rough= 0:0.01:5; %x_fine= 0:0.05:0.8 ;% chon buoc noi suy tu xmin:0.1:xmax( voi xmin la gia tri nho nhat cua x_rough, xmax tuong tu; x_fine = 0:0.001: 5; data = [ ]; // Các giá trị số xung đo được 500 giá trị data = data * 1000 /(10 * 100 *12); % tính toán ra tốc độ thực và chia cho 12V để suy ra đáp ứng khi U = 1V vì coi động cơ DC là tuyến tính % 100 là số lỗ /1 vòng của Encoder inter_cubic= interp1(x_rough,data,x_fine,'cubic'); % noi suy theo phuong phap cubic plot(x_fine,inter_cubic,'k','LineWidth',2); grid on;
Code:
#include<pic.h> # include "stdio.h" __CONFIG(HS & PWRTEN & BOREN & LVPDIS & WDTDIS ); const unsigned char Font[]={ 0b00000011, 0b10011111, 0b00100101, 0b00001101, 0b10011001,\ 0b01001001, 0b01000001, 0b00011111, 0b00000001, 0b00001001}; # define Ts 10 // Thoi gian trich mau Ts (ms) # define Encoder_resolution 100 // So lo cua Encoder/1 vong # define Total_Point 500 // So diem can trich mau // ham truyen du lieu void putch(unsigned char byte) { /* output one byte */ while(!TXIF); /* set when register is empty */ // continue; TXREG = byte; } //===== Ham khoi tao void interrupt MyInt(void){ static volatile unsigned int i, Pulse_Encoder; // i la so diem trich mau // Pulse_Encoder = so xung do duoc tu Encoder static volatile unsigned char allow,counter_Sampling; // allow la bien cho phep bat dau trich mau // counter_Sampling: bien dem de trich mau unsigned char RC_USART; // gia tri doc duoc tu thanh ghi nhan du lieu USART if(T0IF & T0IE){ TMR0 = 6; T0IF = 0 ;// xoa co ngat if((++counter_Sampling == Ts) && allow){ // Ts = 10 ms Pulse_Encoder = (TMR1H << 8) | TMR1L; // Toc do dong co = Pulse_Encoder * 1000 / (Encoder_resolution * Ts) (vong/s) printf("%6d",Pulse_Encoder); // Truyen gia tri xung do tren Ts counter_Sampling = 0; if (i++ == Total_Point){ i = 0; // Neu trich duoc 500 diem thi dung dong co lai CCPR1L = 0; allow = 0; }; }; }; if(RCIF){ // Neu co ngat nhan du lieu noi tiep RC_USART = RCREG; RCIF = 0; // Xoa co ngat RCIF switch(RC_USART){ case 'P': // === Bat dau cho dong co chay cho do rong xung = 100% TMR1ON = 0 ; // ngung Timer1 TMR1H = TMR1L = 0; TMR1ON = 1 ; // bat lai Timer1 CCPR1L = PR2 + 1; CCP1Y = CCP1X = 0; allow = 1; break; }; }; } //------------------------------------init void init(void){ // Khoi tao cho USART TRISC = TRISC | 0b11000000; // Bit 7,6 la RX va TX phai la Input SPEN = 1 ; // Enable Serial Port communication. SYNC = 0; // che do khong dong bo Asynchronous // cho che do truyen TXEN = 1; //enable truyen TX9 = 0 ; // chon che do 8 truyen bit du lieu BRGH = 1; // High - speed SPBRG = 129; //Baud = 9600; voi HS, Baud Rate = Fosc/(16(X+1)) TXIE = 0; // khong dung ngat Truyen // Che do nhan du lieu RCIE = 1; // dung ngat nhan PEIE = 1; // cho phep ngat ngoai vi GIE = 1; // cho phep ngat toan cuc RX9 = 0; // nhan 8 bit CREN = 1; // lien tuc nhan du lieu; = 0 k lien tuc nhan du lieu //===== init for PWM // PWM Period = [ PR2 +1 ] x 4 x Tosc x (TMR2 Prescaler Value) PR2 = 82; // Tan so = 15 KHz, TMR2 Prescaler Value = 4 // PWM Duty Cycle = [ CCPR1L : CCP1CON<5:4>) x Tosc x (TMR2 Prescaler Value) // => CCPR1L : CCP1CON<5:4> = k% x (TMR2 + 1 ) x 4; CCPR1L = 0; TRISC2 = 0; // RC2 la output RC2 = 1; T2CON = 0b00000101; // Timer2 on, TMR2 Prescaler Value = 4 CCP1CON = 0b00001100; // CCP1 hoat dong trong che do PWM //================= init for PORTs OPTION = 0b00000000; ADCON1 = 0b00000111; TRISA = 0b00000000; TRISD = 0b00000000; PORTD = 0xFF; //================ Khoi tao cho Timer0 GIE = 1; T0IE = 1; TMR0 = 6; // ========= Khoi tao cho dem Timer1 TMR1CS = 1; // Timer1 hoat dong o che do Counter Mode T1SYNC = 1; // TMR1 hoat dong o che do dem khong dong bo T1OSCEN = 1; // Dem xung tu chan RC1/T1OSI/CCP2 T1CKPS1 = T1CKPS0 = 0; // Chon Prescaler = 1:1 TMR1H = TMR1L = 0; TMR1IE = 0 ; // Khong dung ngat Timer1 TMR1ON = 1; // Bat Timer1 } //------------------------------------MAIN void main(){ init(); while(1); } // === Kết thúc
Chúc các bạn thành công.
Comment