PIC Vietnam

Go Back   PIC Vietnam > Microchip PIC > dsPIC - Bộ điều khiển tín hiệu số 16-bit

Tài trợ cho PIC Vietnam
Trang chủ Đăng Kí Hỏi/Ðáp Thành Viên Lịch Bài Trong Ngày Vi điều khiển

dsPIC - Bộ điều khiển tín hiệu số 16-bit Theo dự kiến của Microchip, vào khoảng năm 2011 dsPIC sẽ có doanh số lớn hơn PIC

 
 
Ðiều Chỉnh Xếp Bài
Prev Previous Post   Next Post Next
Old 24-12-2008, 06:04 PM   #1
ham_hoc_hoi
Đệ tử 1 túi
 
Tham gia ngày: Dec 2008
Bài gửi: 25
:
Giúp em chtr liên quan đến số fractional Q15 này với

em dựa vào 1 ví dụ của C30 về PID như này
Code:
#include <dsp.h>

/*
Variable Declaration required for each PID controller in your application
*/
/* Declare a PID Data Structure named, fooPID */
tPID fooPID;
/* The fooPID data structure contains a pointer to derived coefficients in X-space and */
/* pointer to controler state (history) samples in Y-space. So declare variables for the */
/* derived coefficients and the controller history samples */
fractional abcCoefficient[3] __attribute__ ((section (".xbss, bss, xmemory")));
fractional controlHistory[3] __attribute__ ((section (".ybss, bss, ymemory")));
/* The abcCoefficients referenced by the fooPID data structure */
/* are derived from the gain coefficients, Kp, Ki and Kd */
/* So, declare Kp, Ki and Kd in an array */
fractional kCoeffs[] = {0,0,0};

/*
Main function demonstrating the use of PID(), PIDInit() and PIDCoeffCalc()
functions from DSP library in MPLAB C30 v2.0 and higher
*/
int main (void)
{
/*
Step 1: Initialize the PID data structure, fooPID
*/
        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(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 */

/*
Step 2: Use the PID Controller
*/
        fooPID.controlReference = Q15(0.74) ;           /*Set the Reference Input for your controller */
        fooPID.measuredOutput = Q15(0.453) ;            /*Typically the measuredOutput variable is a plant response*/
                                                        /*measured from an A/D input or a sensor. */
                                                        /*In this example we manually set it to some value for */
                                                        /*demonstration but the user should note that this value will */
                                                        /*keep changing in a real application*/
        while (1)                                       /*We use a while(1) loop here for demonstration purposes.*/
        {                                               /*Typically, the PID calculation may be triggered off a timer*/
                                                        /*or A/D interrupt */

                PID(&fooPID);                           /*Call the PID controller using the new measured input */
                                                        /*The user may place a breakpoint on "PID(&fooPID)", halt the debugger,*/
                                                        /*tweak the measuredOutput variable within the watch window */
                                                        /*and then run the debugger again */
        }

}
em đã viết lại chuong trình như sau, em chỉ đưa phần liên quan đến PID
Code:
	/* Dat  PID Data Structure voi ten fooPID */
		
	tPID fooPID;
	
	/* The fooPID data structure contains a pointer to derived coefficients in X-space and */
	/* pointer to controler state (history) samples in Y-space. So declare variables for the */
	/* derived coefficients and the controller history samples */
	/* Voi iPID duoc khai bao nhu sau
	typedef struct 
		{
			fractional* abcCoefficients;  		// coeffs derived from Kp, Ki & Kd 
			fractional* controlHistory;   		// state variables (delay line)in Y-data
			fractional controlOutput;     		// PID Controller Output  
			fractional measuredOutput;    	// Measured Output sample 
			fractional controlReference;  	// Reference Input sample 
		} tPID;
	*/
	fractional abcCoefficient[3] __attribute__ ((section (".xbss, bss, xmemory")));
	fractional controlHistory[3] __attribute__ ((section (".ybss, bss, ymemory")));
int PWM_duty;
//Chuong trinh khoi tao thong so PID
//------------------------------------------------------------------------------
void PID_init(void)
{ 
    	
	/* The abcCoefficients referenced by the fooPID data structure */
	/* are derived from the gain coefficients, Kp, Ki and Kd */
	/* Dat cac he so Kp, Ki and Kd trong mang sau*/
	
	fractional kCoeffs[] = {0,0,0};
	
	//Step 1: Khoi tao  PID data structure, fooPID
	
    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(0.9);							// Kp = 1
	kCoeffs[1] = Q15(0);							// Ki = 0
	kCoeffs[2] = Q15(0);							// Kd = 0
    PIDCoeffCalc(&kCoeffs[0], &fooPID);             // Tinh cac he so a,b, & c tu Kp, Ki & Kd */
													// a = abcCoefficients[0] = Kp + Ki + Kd
													// b = abcCoefficients[1] = -(Kp + 2*Kd)
													// c = abcCoefficients[2] = Kd
}

//Chuong trinh xu ly ngat Timer 2 sau 10ms
//------------------------------------------------------------------------------
void  __attribute__((__interrupt__)) _T2Interrupt(void) 
{
	_T2IF = 0;			//Xoa co ngat
	
	
        fooPID.controlReference = Q15(ADCBUF0 >> 1) ;           // controlReference la dai luong dat
																// O day la toc do dc dat tu bien tro dieu chinh toc do thong qua bo ADC
        fooPID.measuredOutput = Q15(POSCNT * 0x0003) ;          // measuredOutput dai luong do ve
																// La toc do do encoder dua ve
		/*	Chinh xac gia tri dat la ADC, bo ADC 10bit
			gia tri 	0 - 504,
			tuong ung	0 - 17.5 vong/s  (20v/s la gia tri toc do dat giói han tren)
			tuong ung 	0 - 168 xung/10ms ( 1 vong quay thi có 960 xung)
			Gia tri toc do doc ve là so xung/10ms (POSCNT/10ms)			
		*/
		
        PID(&fooPID);                           	
		
		/*		
		controlOutput[n] = 	controlOutput[n-1] + controlHistory[n] * abcCoefficient[0] 
						+ controlHistory[n-1] * abcCoefficient[1] + controlHistory[n-2] * abcCoefficient[2]
		Trong do
		abcCoefficient[0] = Kp + Ki + Kd
		abcCoefficient[1] = -(Kp + 2*Kd)
		abcCoefficient[2] = Kd
		ControlHistory[n] = MeasuredOutput[n] - ReferenceInput[n] 
		*/
		PWM_duty = fooPID.controlOutput;
		if (PWM_duty > 504 ) 		//Chan gia tri tren
		{	PWM_duty = 504;}
		
		if (PWM_duty < 0 ) 			//Chan gia tri duoi
		{	PWM_duty = 0;}
                                              
		PDC1 = PWM_duty ;
		POSCNT = 0;
}
em dùng 1 biến trở để đặt giá trị tốc độ động cơ với ADC chế độ tự động chuyển đổi,
em lấy 9 bit trong ADCBUF0, giá trị từ 0 đến 504 thì tương đuơng dutt cycle từ 0 đến 100%, ứng với tốc độ từ 0 đến 20v/s,
giá trị đặt của em là giá trị ở ADCBUF0>>1 từ 0 đến 504
giá trị phẩn hồi e quy đổi về là sô xung/ 10ms, và cũng tính toán theo 1 tỉ lệ để dc từ 0 đến 504,
sau khi nạp vào chip thì động cơ ko điều khiển dc, chạy lờ đờ và rất giật.
Theo em nghĩ là với thời gian trích mẫu 10ms thì và với bộ dsp thì vdk thừa sức tính toán các hàm trong chtr ngắt, nên em loại bỏ nguyên nhân vdk ko đủ thời gian tính toán PID
Em đọc tài liều thì thấy định dang fractional Q15 thì có giá trị từ -1.0 đến (1.0 – 2^-15)
thì ở đoặn này fooPID.controlReference = Q15(ADCBUF0 >> 1) ; fooPID.measuredOutput = Q15(POSCNT * 0x0003) ; // so xung nhân với 3
thì giá tri (ADCBUF0 >> 1) và (POSCNT * 0x0003) lúc này trở thành số fractional Q15 đúng ko ah, như vậy giá trị đặt và phản hổi về nằm trong [-1;1), do đó sau 1 tính toan trong hàm PID(&fooPID) thì cho ta kết quả fooPID.controlOutput là số fractional, em nghĩ là giá trị nạp vào PDC1 là số nguyên từ 0 đên 504, nen em khai báo 1 biến int PWM_duty và cho PWM_duty=fooPID.controlOutput, để chuyển số fractional thành số int tương ứng
em ví du số fractional fooPID.controlOutput= 0x4001 = 2-1 + 2-15 = 0.5 + .000030518 = 0.500030518
thì PWM_duty = 0x4001 = 214 + 20 = 16384 + 1 = 16385
em nghĩ như thế có đúng ko, nếu đúng thì chtr của em phải chạy đúng chứ đằng này động cơ lại chạy giật,
Bác nào xem hộ em sai chỗ nào vơi
ham_hoc_hoi vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
 


Quyền Sử Dụng Ở Diễn Ðàn
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is Mở
Smilies đang Mở
[IMG] đang Mở
HTML đang Tắt

Chuyển đến


Múi giờ GMT. Hiện tại là 07:59 AM.


Được sáng lập bởi Đoàn Hiệp
Powered by vBulletin®
Page copy protected against web site content infringement by Copyscape
Copyright © PIC Vietnam