Thiết kế thuật toán và cấu hình dự án

Một phần của tài liệu XÂY DỰNG FRAMEWORK GIÚP SỬ DỤNG CÁC THUẬT TOÁN ĐIỀU KHIỂN TỰ ĐỘNG THIẾT KẾ TRÊN MATLAB SIMULINK VÀO HỆ THỐNG NHÚNG SỬ DỤNG VI ĐIỀU KHIỂN ARM (Trang 53 - 58)

CHƯƠNG 2: NỘI DUNG NGHIÊN CỨU

2. Giải pháp thực hiện bộ điều khiển nhúng

2.3 Thực hiện thiết kế tự động

2.3.3 Thiết kế thuật toán và cấu hình dự án

Với giải pháp này người sử dụng có thể kéo thả trực tiếp các khối ngoại vi để thiết kế một hệ thống hoàn chỉnh trên Simulink. Tuy nhiên, chương trình Simulink này không thể mô phỏng trực tiếp được, nó chỉ thiết kế để sinh mã C. Nếu người sử dụng muốn mô phỏng thuật toán thì phải thiết kế ở một tập tin khác. Hình 2.19 là chương trình Simulink điều khiển vị trí động cơ sử dụng các khối thư vị trong phương pháp này.

Hình 2.19 Điều khiển vị trí động cơ dùng bộ điều khiển PID số.

40

Sau khi biên dịch thành công, các tập tin sinh mã cần đƣợc thêm vào án một cách thủ công và khai báo đường dẫn thư viện đến thư mục chứa mã biên dịch. Tuy nhiên, việc này chỉ cần thực hiện một lần duy nhất nếu không có sự thay đổi tên hay số lượng các tập tin sinh ra. Mã lệnh sinh mã tự động cho chương trình Simulink Hình 2.19 nhƣ sau:

#include "testPID.h"

#include "stm32f4xx.h"

/*declare global vars*/

uint8_t sample_flag= 0;

void rt_OneStep() {

testPID_step();

/* Get model outputs here */

}

static void SampleTime_Config(void);

int main(void) {

/*local variable*/

/* Initialize model */

testPID_initialize();

SampleTime_Config();

while (1) {

/*Others user task here*/

}

return 0;

}

//sample time configure

static void SampleTime_Config(void) {

if (SysTick_Config(SystemCoreClock * 0.01)) { /*handles wrong parameter*/

while (1) ; }

}

//System tick handler

41

void SysTick_Handler(void) {

rt_OneStep();

sample_flag = 1; //synchronize with main }

Mã l nh củ hàm rt_OneStep():

#include "testPID.h"

#include "testPID_private.h"

/* #include "mytables.h" */

#include <CTUProj_Driver.h> //nạp thư viện ngoại vi /* Block signals (auto storage) */

BlockIO_testPID testPID_B;

/* Block states (auto storage) */

D_Work_testPID testPID_DWork;

/* Real-time model */

RT_MODEL_testPID testPID_M_;

RT_MODEL_testPID *testPID_M = &testPID_M_;

/* Model step function */

void testPID_step(void) {

real_T rtb_Sum;

real_T rtb_Saturation;

real_T rtb_FilterCoefficient;

/* S-Function (Read_QEI): '<Root>/feedback' */

testPID_B.feedback_o1= Read_QEI(TIM1);

if (TIM1->CR1 & 0x0010) testPID_B.feedback_o2 = 1;

else

testPID_B.feedback_o2 = 0;

/* Switch: '<S2>/Switch' incorporates:

* Constant: '<S2>/Constant1' * Constant: '<S3>/Constant'

* RelationalOperator: '<S3>/Compare' * Sum: '<S2>/Add'

42

*/

if (testPID_B.feedback_o1 >= testPID_P.Constant_Value) {

rtb_Sum = testPID_B.feedback_o1 - testPID_P.Constant1_Value_f;

} else {

rtb_Sum = testPID_B.feedback_o1;

}

/* Sum: '<Root>/Sum' incorporates:

* Constant: '<Root>/Reference' */

rtb_Sum = testPID_P.Reference_Value - rtb_Sum;

/* Gain: '<S1>/Filter Coefficient' incorporates:

* DiscreteIntegrator: '<S1>/Filter' * Gain: '<S1>/Derivative Gain' * Sum: '<S1>/SumD'

*/

rtb_FilterCoefficient = (testPID_P.DerivativeGain_Gain * rtb_Sum - testPID_DWork.Filter_DSTATE) * testPID_P.FilterCoefficient_Gain;

/* Sum: '<S1>/Sum' incorporates:

* DiscreteIntegrator: '<S1>/Integrator' * Gain: '<S1>/Proportional Gain'

*/

rtb_Saturation = (testPID_P.ProportionalGain_Gain * rtb_Sum +

testPID_DWork.Integrator_DSTATE) + rtb_FilterCoefficient;

/* Saturate: '<Root>/Saturation' */

rtb_Saturation = rt_SATURATE(rtb_Saturation,

testPID_P.Saturation_LowerSat, testPID_P.Saturation_UpperSat);

/* Switch: '<Root>/Switch1' incorporates:

* Constant: '<Root>/Constant1' * Constant: '<Root>/Constant2' */

if (rtb_Saturation > testPID_P.Switch1_Threshold) { testPID_B.Switch1 = testPID_P.Constant2_Value;

} else {

43

testPID_B.Switch1 = testPID_P.Constant1_Value;

}

/* S-Function (Write_GPIO): '<Root>/Direction' */

Write_GPIO(GPIOC,GPIO_Pin_0,testPID_B.Switch1);

/* Abs: '<Root>/Abs1' */

testPID_B.Abs1 = fabs(rtb_Saturation);

/* S-Function (Write_PWM): '<Root>/Speed' */

Write_PWM(TIM3,1,testPID_B.Abs1);

/* Update for DiscreteIntegrator: '<S1>/Integrator' incorporates:

* Gain: '<S1>/Integral Gain' */

testPID_DWork.Integrator_DSTATE = testPID_P.IntegralGain_Gain * rtb_Sum * testPID_P.Integrator_gainval + testPID_DWork.Integrator_DSTATE;

/* Update for DiscreteIntegrator: '<S1>/Filter' */

testPID_DWork.Filter_DSTATE = testPID_P.Filter_gainval * rtb_FilterCoefficient

+ testPID_DWork.Filter_DSTATE;

}

Tóm lại, một framework đã đƣợc đề nghị giúp có thể sử dụng các thuật toán điều khiển tự động thiết kế trên Matlab simulink vào hệ thống nhúng sử dụng vi điều khiển ARM. Có hai giải pháp thiết kế và sinh mã bộ điều khiển cũng đã đƣợc đề nghị.

Thứ nhất là giải pháp thủ công, với giải pháp này người dùng phải thực hiện thủ công từ khâu thiết kế Simulink đến việc lập trình thêm mã lệnh kết nối thuật toán với thƣ viện ngoại vi. Mặc dù giải pháp này phức tạp, tốn nhiều thời gian và đòi hỏi người sử dụng phải am hiểu lập trình cho nền tảng đang sử dụng nhƣng nó có một ƣu điểm lớn đó là người dùng hoàn toàn làm chủ hệ thống, có thể tùy biến để chạy trên bất kỳ nền tảng nào. Thứ hai là giải pháp tự động, với giải pháp này người dùng sử dụng các khối Simulink đƣợc thiết sẵn để liên kết giữa thƣ viện ngoại vi và Simulink. Do đó, việc sinh mã gần như tự động mà không đòi hỏi người sử dụng viết thêm mã lệnh. Bên cạnh mã lệnh ngôn ngữ C truyền thống, tác giả cũng đã đề nghị sử dụng hệ điều hành thời gian thực RTOS vào framework đề nghị.

44

Một phần của tài liệu XÂY DỰNG FRAMEWORK GIÚP SỬ DỤNG CÁC THUẬT TOÁN ĐIỀU KHIỂN TỰ ĐỘNG THIẾT KẾ TRÊN MATLAB SIMULINK VÀO HỆ THỐNG NHÚNG SỬ DỤNG VI ĐIỀU KHIỂN ARM (Trang 53 - 58)

Tải bản đầy đủ (PDF)

(70 trang)